@instructure/canvas-rce 5.14.0 → 5.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/DEVELOPMENT.md +1 -1
- 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/__tests__/sidebar/reducers/all_files.test.js +28 -0
- package/babel.config.js +3 -1
- package/build.sh +7 -7
- package/es/bridge/Bridge.js +8 -56
- package/es/bridge/index.js +1 -0
- package/es/canvasFileBrowser/FileBrowser.js +12 -59
- package/es/canvasFileBrowser/en-US.js +3 -6
- package/es/common/FlashAlert.js +7 -28
- package/es/common/browser.js +4 -2
- package/es/common/fileUrl.js +104 -59
- package/es/common/incremental-loading/LoadMoreButton.js +1 -0
- package/es/common/incremental-loading/LoadingIndicator.js +1 -2
- package/es/common/incremental-loading/LoadingStatus.js +1 -2
- package/es/common/incremental-loading/index.js +1 -0
- package/es/common/incremental-loading/useIncrementalLoading.js +1 -3
- package/es/common/indicate.js +15 -8
- 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 +17 -28
- package/es/enhance-user-content/enhance_user_content.js +28 -60
- package/es/enhance-user-content/external_links.js +5 -8
- package/es/enhance-user-content/index.js +1 -0
- package/es/enhance-user-content/instructure_helper.js +25 -38
- package/es/enhance-user-content/jqueryish_funcs.js +8 -11
- package/es/enhance-user-content/mathml.js +35 -82
- package/es/enhance-user-content/media_comment_thumbnail.js +5 -17
- package/es/format-message.js +3 -4
- package/es/getThemeVars.js +8 -6
- package/es/getTranslations.js +1 -78
- package/es/index.js +3 -1
- package/es/rce/AlertMessageArea.js +1 -1
- package/es/rce/DraggingBlocker.js +4 -2
- package/es/rce/KeyboardShortcutModal.js +1 -0
- package/es/rce/RCE.js +12 -11
- package/es/rce/RCEGlobals.js +12 -10
- package/es/rce/RCEVariants.js +27 -10
- package/es/rce/RCEWrapper.js +167 -386
- package/es/rce/RCEWrapperProps.js +8 -3
- package/es/rce/RceHtmlEditor.js +5 -8
- package/es/rce/ResizeHandle.js +3 -8
- package/es/rce/RestoreAutoSaveModal.js +1 -2
- package/es/rce/ShowOnFocusButton/index.js +0 -6
- package/es/rce/StatusBar.js +8 -37
- package/es/rce/alertHandler.js +1 -4
- package/es/rce/contentInsertion.js +35 -57
- package/es/rce/contentInsertionUtils.js +6 -8
- package/es/rce/contentRendering.js +7 -12
- package/es/rce/customEvents.js +1 -0
- package/es/rce/editorLanguage.js +22 -10
- package/es/rce/indicatorRegion.js +6 -5
- package/es/rce/normalizeLocale.js +5 -3
- package/es/rce/normalizeProps.js +3 -1
- package/es/rce/plugins/instructure-ui-icons/plugin.js +21 -3
- package/es/rce/plugins/instructure_color/clickCallback.js +84 -0
- package/es/rce/plugins/instructure_color/components/ColorPicker.js +299 -0
- package/es/rce/plugins/instructure_color/components/ColorPopup.js +68 -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 +22 -15
- package/es/rce/plugins/instructure_condensed_buttons/ui/subscript-superscript-button.js +1 -2
- 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 +3 -18
- 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 +12 -29
- package/es/rce/plugins/instructure_equation/EquationEditorModal/latexTextareaUtil.js +11 -12
- package/es/rce/plugins/instructure_equation/EquationEditorModal/parseLatex.js +4 -3
- package/es/rce/plugins/instructure_equation/EquationEditorModal/styles.js +4 -2
- package/es/rce/plugins/instructure_equation/EquationEditorToolbar/buttons.js +13 -7
- package/es/rce/plugins/instructure_equation/EquationEditorToolbar/index.js +4 -7
- package/es/rce/plugins/instructure_equation/MathIcon/index.js +1 -1
- 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 +1 -1
- package/es/rce/plugins/instructure_equation/plugin.js +7 -10
- package/es/rce/plugins/instructure_fullscreen/plugin.js +3 -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 +2 -4
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ColorSection.js +1 -2
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/CreateIconMakerForm.js +1 -0
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Footer.js +1 -0
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Group.js +1 -0
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Header.js +1 -2
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Course.js +25 -22
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageOptions.js +7 -11
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageSection.js +27 -23
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ModeSelect.js +5 -4
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/index.js +11 -9
- 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 +5 -4
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGThumbnail.js +1 -3
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/index.js +7 -7
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/svg.js +1 -0
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Upload.js +27 -20
- 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 +1 -0
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Preview.js +4 -4
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ShapeSection.js +1 -2
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/TextSection.js +1 -5
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/index.js +1 -0
- package/es/rce/plugins/instructure_icon_maker/components/IconMakerTray.js +18 -33
- 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 +1 -3
- 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 +69 -83
- package/es/rce/plugins/instructure_icon_maker/svg/index.js +11 -15
- package/es/rce/plugins/instructure_icon_maker/svg/metadata.js +1 -0
- package/es/rce/plugins/instructure_icon_maker/svg/settings.js +32 -39
- package/es/rce/plugins/instructure_icon_maker/svg/shape.js +1 -49
- package/es/rce/plugins/instructure_icon_maker/svg/text.js +7 -92
- package/es/rce/plugins/instructure_icon_maker/svg/utils.js +1 -7
- package/es/rce/plugins/instructure_icon_maker/utils/IconMakerClose.js +2 -6
- 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 +1 -1
- 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 +6 -24
- package/es/rce/plugins/instructure_image/ImageList/Image.js +1 -6
- package/es/rce/plugins/instructure_image/ImageList/index.js +1 -2
- package/es/rce/plugins/instructure_image/ImageOptionsTray/TrayController.js +7 -27
- package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +3 -16
- 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 +13 -18
- package/es/rce/plugins/instructure_links/clickCallback.js +1 -0
- package/es/rce/plugins/instructure_links/components/AccordionSection.js +1 -0
- package/es/rce/plugins/instructure_links/components/CollectionPanel.js +1 -3
- package/es/rce/plugins/instructure_links/components/Link.js +7 -19
- package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/LinkOptionsDialogController.js +1 -21
- package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/index.js +1 -4
- package/es/rce/plugins/instructure_links/components/LinkOptionsTray/LinkOptionsTrayController.js +3 -20
- package/es/rce/plugins/instructure_links/components/LinkOptionsTray/index.js +1 -12
- package/es/rce/plugins/instructure_links/components/LinkSet.js +4 -20
- package/es/rce/plugins/instructure_links/components/LinksPanel.js +1 -2
- package/es/rce/plugins/instructure_links/components/NavigationPanel.js +7 -9
- package/es/rce/plugins/instructure_links/components/NoResults.js +1 -7
- package/es/rce/plugins/instructure_links/plugin.js +17 -40
- package/es/rce/plugins/instructure_links/validateURL.js +81 -36
- package/es/rce/plugins/instructure_media_embed/clickCallback.js +2 -5
- package/es/rce/plugins/instructure_media_embed/components/Embed.js +1 -0
- 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 +27 -29
- package/es/rce/plugins/instructure_rce_external_tools/ExternalToolsEnv.js +14 -53
- package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.js +21 -49
- package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialog.js +11 -42
- 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 +2 -10
- 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 +19 -4
- 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 +130 -136
- package/es/rce/plugins/instructure_rce_external_tools/lti11-content-items/RceLti11ContentItem.js +100 -95
- 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 +2 -19
- package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/BaseLinkContentItem.js +1 -14
- 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 +18 -10
- package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/rceLti13ContentItemFromJson.js +4 -4
- package/es/rce/plugins/instructure_rce_external_tools/plugin.js +7 -16
- package/es/rce/plugins/instructure_rce_external_tools/util/addParentFrameContextToUrl.js +1 -1
- package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +1 -25
- package/es/rce/plugins/instructure_record/AudioOptionsTray/index.js +1 -4
- package/es/rce/plugins/instructure_record/MediaPanel/index.js +1 -9
- package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +8 -51
- package/es/rce/plugins/instructure_record/VideoOptionsTray/index.js +4 -17
- package/es/rce/plugins/instructure_record/clickCallback.js +7 -15
- 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 +2 -5
- package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTray.js +20 -35
- package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTrayController.js +3 -18
- package/es/rce/plugins/instructure_search_and_replace/getSelectionContext.js +2 -9
- package/es/rce/plugins/instructure_search_and_replace/plugin.js +1 -3
- package/es/rce/plugins/instructure_studio_media_options/plugin.js +1 -1
- package/es/rce/plugins/instructure_wordcount/clickCallback.js +2 -5
- package/es/rce/plugins/instructure_wordcount/components/WordCountModal.js +1 -4
- package/es/rce/plugins/instructure_wordcount/plugin.js +1 -0
- package/es/rce/plugins/instructure_wordcount/utils/countContent.js +1 -8
- package/es/rce/plugins/instructure_wordcount/utils/tableContent.js +1 -0
- package/es/rce/plugins/shared/CanvasContentTray.js +43 -63
- package/es/rce/plugins/shared/CheckerboardStyling.js +1 -1
- package/es/rce/plugins/shared/ColorInput.js +5 -14
- package/es/rce/plugins/shared/ConditionalTooltip.js +1 -0
- package/es/rce/plugins/shared/ContentSelection.js +17 -58
- package/es/rce/plugins/shared/DimensionUtils.js +1 -8
- 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 +1 -3
- package/es/rce/plugins/shared/Filter.js +8 -38
- package/es/rce/plugins/shared/FixedContentTray.js +3 -3
- package/es/rce/plugins/shared/ImageCropper/DirectionRegion.js +1 -8
- package/es/rce/plugins/shared/ImageCropper/Modal.js +4 -7
- package/es/rce/plugins/shared/ImageCropper/Preview.js +7 -11
- package/es/rce/plugins/shared/ImageCropper/constants.js +1 -0
- package/es/rce/plugins/shared/ImageCropper/controls/CustomNumberInput.js +2 -5
- package/es/rce/plugins/shared/ImageCropper/controls/ResetControls.js +1 -0
- package/es/rce/plugins/shared/ImageCropper/controls/RotationControls.js +1 -10
- package/es/rce/plugins/shared/ImageCropper/controls/ShapeControls.js +1 -0
- package/es/rce/plugins/shared/ImageCropper/controls/ZoomControls.js +1 -11
- package/es/rce/plugins/shared/ImageCropper/controls/index.js +1 -0
- package/es/rce/plugins/shared/ImageCropper/controls/useDebouncedNumericValue.js +3 -16
- package/es/rce/plugins/shared/ImageCropper/controls/utils.js +1 -2
- package/es/rce/plugins/shared/ImageCropper/imageCropUtils.js +1 -10
- 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 +1 -17
- package/es/rce/plugins/shared/ImageCropper/svg/utils.js +1 -0
- package/es/rce/plugins/shared/ImageCropper/useKeyMouseEvents.js +19 -46
- package/es/rce/plugins/shared/ImageCropper/useMouseWheel.js +8 -10
- package/es/rce/plugins/shared/ImageOptionsForm.js +1 -2
- package/es/rce/plugins/shared/LinkDisplay.js +1 -2
- package/es/rce/plugins/shared/PreviewIcon.js +1 -6
- package/es/rce/plugins/shared/Previewable.js +1 -0
- package/es/rce/plugins/shared/RceFileBrowser.js +5 -7
- package/es/rce/plugins/shared/StoreContext.js +1 -2
- package/es/rce/plugins/shared/StudioLtiSupportUtils.js +10 -6
- package/es/rce/plugins/shared/UnknownFileTypePanel.js +1 -0
- package/es/rce/plugins/shared/Upload/CanvasContentPanel.js +13 -18
- package/es/rce/plugins/shared/Upload/CategoryProcessor.js +1 -1
- package/es/rce/plugins/shared/Upload/ComputerPanel.js +8 -26
- package/es/rce/plugins/shared/Upload/PanelFilter.js +3 -12
- package/es/rce/plugins/shared/Upload/SvgCategoryProcessor.js +4 -3
- package/es/rce/plugins/shared/Upload/UploadFile.js +15 -18
- package/es/rce/plugins/shared/Upload/UploadFileModal.js +9 -25
- package/es/rce/plugins/shared/Upload/UrlPanel.js +1 -0
- package/es/rce/plugins/shared/Upload/UsageRightsSelectBox.js +7 -12
- package/es/rce/plugins/shared/Upload/doFileUpload.js +4 -6
- package/es/rce/plugins/shared/Upload/index.js +1 -0
- package/es/rce/plugins/shared/ai_tools/AIResponseModal.js +1 -3
- package/es/rce/plugins/shared/ai_tools/AIToolsTray.js +6 -24
- package/es/rce/plugins/shared/ai_tools/aiicons.js +1 -0
- 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 +6 -9
- package/es/rce/plugins/shared/compressionUtils.js +1 -8
- 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 +7 -10
- 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 +32 -42
- 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 +1 -0
- package/es/rce/plugins/shared/trayUtils.js +4 -3
- package/es/rce/plugins/shared/useDataUrl.js +9 -9
- package/es/rce/plugins/shared/useFilterSettings.js +3 -3
- package/es/rce/plugins/tinymce-a11y-checker/components/ColorField.js +2 -6
- package/es/rce/plugins/tinymce-a11y-checker/components/checker.js +5 -63
- 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 +1 -6
- package/es/rce/plugins/tinymce-a11y-checker/plugin.js +4 -7
- 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 +1 -5
- 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 +1 -4
- 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 +1 -6
- 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 +1 -26
- package/es/rce/plugins/tinymce-a11y-checker/utils/indicate.js +16 -15
- package/es/rce/plugins/tinymce-a11y-checker/utils/rgb-hex.js +7 -10
- package/es/rce/plugins/tinymce-a11y-checker/utils/strings.js +1 -4
- package/es/rce/root.js +9 -8
- package/es/rce/sanitizePlugins.js +1 -3
- package/es/rce/style.js +1 -4
- package/es/rce/tinyRCE.js +13 -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 +8 -10
- 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 +61 -116
- package/es/rcs/buildError.js +5 -17
- package/es/rcs/fake.js +4 -13
- package/es/sidebar/actions/all_files.js +2 -0
- package/es/sidebar/actions/data.js +4 -7
- package/es/sidebar/actions/documents.js +9 -6
- package/es/sidebar/actions/files.js +3 -6
- package/es/sidebar/actions/filter.js +1 -0
- package/es/sidebar/actions/flickr.js +1 -1
- package/es/sidebar/actions/images.js +12 -11
- package/es/sidebar/actions/links.js +1 -0
- package/es/sidebar/actions/media.js +12 -10
- package/es/sidebar/actions/session.js +1 -3
- package/es/sidebar/actions/ui.js +1 -0
- package/es/sidebar/actions/upload.js +14 -39
- package/es/sidebar/containers/Sidebar.js +1 -2
- package/es/sidebar/containers/sidebarHandlers.js +3 -1
- package/es/sidebar/dragHtml.js +5 -3
- package/es/sidebar/reducers/all_files.js +4 -3
- package/es/sidebar/reducers/collection.js +12 -13
- package/es/sidebar/reducers/collections.js +5 -5
- package/es/sidebar/reducers/documents.js +6 -13
- package/es/sidebar/reducers/files.js +3 -3
- package/es/sidebar/reducers/filter.js +1 -8
- package/es/sidebar/reducers/flickr.js +9 -9
- package/es/sidebar/reducers/folder.js +15 -15
- package/es/sidebar/reducers/folders.js +3 -3
- package/es/sidebar/reducers/images.js +3 -13
- package/es/sidebar/reducers/index.js +3 -1
- package/es/sidebar/reducers/media.js +6 -13
- package/es/sidebar/reducers/newPageLinkExpanded.js +1 -2
- package/es/sidebar/reducers/noop.js +1 -0
- package/es/sidebar/reducers/rootFolderId.js +1 -2
- package/es/sidebar/reducers/session.js +3 -3
- package/es/sidebar/reducers/ui.js +3 -16
- package/es/sidebar/reducers/upload.js +8 -40
- package/es/sidebar/store/configureStore.js +1 -0
- package/es/sidebar/store/initialState.js +13 -24
- package/es/translations/locales/ab.js +1 -0
- package/es/translations/locales/ar.js +67 -9
- package/es/translations/locales/ca.js +67 -9
- package/es/translations/locales/cs.js +1 -0
- package/es/translations/locales/cs_CZ.js +1 -0
- package/es/translations/locales/cy.js +67 -9
- package/es/translations/locales/da-x-k12.js +67 -9
- package/es/translations/locales/da.js +67 -9
- package/es/translations/locales/da_DK.js +1 -0
- package/es/translations/locales/de.js +67 -9
- package/es/translations/locales/el.js +4 -0
- package/es/translations/locales/en-AU-x-unimelb.js +67 -9
- package/es/translations/locales/en-GB-x-ukhe.js +67 -9
- package/es/translations/locales/en.js +72 -8
- package/es/translations/locales/en_AU.js +67 -9
- package/es/translations/locales/en_CA.js +67 -9
- package/es/translations/locales/en_CY.js +67 -9
- package/es/translations/locales/en_GB.js +67 -9
- 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 +67 -9
- package/es/translations/locales/es_ES.js +67 -9
- package/es/translations/locales/es_GT.js +1 -0
- package/es/translations/locales/fa_IR.js +7 -0
- package/es/translations/locales/fi.js +67 -9
- package/es/translations/locales/fr.js +67 -9
- package/es/translations/locales/fr_CA.js +68 -10
- package/es/translations/locales/ga.js +5 -13
- package/es/translations/locales/he.js +7 -0
- package/es/translations/locales/hi.js +67 -9
- package/es/translations/locales/ht.js +67 -9
- 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 +67 -9
- package/es/translations/locales/id_ID.js +1 -0
- package/es/translations/locales/is.js +67 -9
- package/es/translations/locales/it.js +67 -9
- package/es/translations/locales/ja.js +67 -9
- 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 +67 -9
- package/es/translations/locales/mn_MN.js +1 -0
- package/es/translations/locales/ms.js +67 -9
- package/es/translations/locales/nb-x-k12.js +67 -9
- package/es/translations/locales/nb.js +67 -9
- package/es/translations/locales/nl.js +67 -9
- package/es/translations/locales/nl_NL.js +1 -0
- package/es/translations/locales/nn.js +7 -6
- package/es/translations/locales/pl.js +67 -9
- package/es/translations/locales/pt.js +67 -9
- package/es/translations/locales/pt_BR.js +67 -9
- package/es/translations/locales/ro.js +1 -0
- package/es/translations/locales/ru.js +67 -9
- package/es/translations/locales/se.js +1 -0
- package/es/translations/locales/sl.js +67 -9
- package/es/translations/locales/sv-x-k12.js +67 -9
- package/es/translations/locales/sv.js +67 -9
- package/es/translations/locales/sv_SE.js +1 -0
- package/es/translations/locales/tg.js +1 -0
- package/es/translations/locales/th.js +67 -9
- 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 +67 -9
- package/es/translations/locales/vi_VN.js +1 -0
- package/es/translations/locales/zh-Hans.js +67 -9
- package/es/translations/locales/zh-Hant.js +67 -9
- package/es/translations/locales/zh.js +67 -9
- package/es/translations/locales/zh_HK.js +67 -9
- 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/encrypted-storage.js +3 -13
- package/es/util/file-url-util.js +1 -6
- package/es/util/fullscreenHelpers.js +4 -1
- package/es/util/instui-icon-helper.js +4 -3
- package/es/util/loadingPlaceholder.js +38 -39
- package/es/util/simpleCache.js +0 -3
- 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 +16 -25
- package/eslint.config.js +239 -0
- package/jest.config.js +1 -1
- package/package.json +77 -82
- package/scripts/build-canvas +2 -1
- package/scripts/build.js +4 -4
- package/scripts/publish_to_npm.sh +1 -1
- 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 +20 -15
- package/.eslintrc +0 -45
- package/.prettierignore +0 -6
- package/es/common/components/FileTree/File.js +0 -64
- package/es/common/components/FileTree/Folder.js +0 -110
- package/es/common/components/FileTree/index.js +0 -84
- package/es/common/components/FileTree/styles.js +0 -72
- package/es/common/components/Loading.js +0 -83
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* because figuring this stuff out wasn't trivial and
|
|
24
24
|
* I didn't want to lose it.
|
|
25
25
|
********************************************************* */
|
|
26
|
+
|
|
26
27
|
import formatMessage from '../../../format-message';
|
|
27
28
|
import { showFlashAlert } from '../../../common/FlashAlert';
|
|
28
29
|
export function initPasteMenuCommand(ed, handlePasteOrDrop) {
|
|
@@ -39,7 +40,6 @@ export function initPasteMenuCommand(ed, handlePasteOrDrop) {
|
|
|
39
40
|
text: formatMessage('Paste'),
|
|
40
41
|
icon: 'paste',
|
|
41
42
|
onAction: () => ed.execCommand('instructurePaste'),
|
|
42
|
-
|
|
43
43
|
onSetup(_api) {
|
|
44
44
|
// If I add the shortcut, then it overwrites the browsers
|
|
45
45
|
// built-in keyboard shortcut for paste. we don't want that
|
|
@@ -47,15 +47,12 @@ export function initPasteMenuCommand(ed, handlePasteOrDrop) {
|
|
|
47
47
|
ed.execCommand('instructurePaste');
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
|
|
51
50
|
});
|
|
52
|
-
|
|
53
51
|
async function handlePasteMenuCommand() {
|
|
54
52
|
try {
|
|
55
53
|
const cbitems = await window.navigator.clipboard.read();
|
|
56
54
|
const cbitem = cbitems[0];
|
|
57
55
|
const imageType = cbitem.types.find(t => /^image\//.test(t));
|
|
58
|
-
|
|
59
56
|
if (imageType) {
|
|
60
57
|
const blob = await cbitem.getType(imageType);
|
|
61
58
|
const file = new File([blob], imageType.replace('/', '.'), {
|
|
@@ -92,7 +89,6 @@ export function initPasteMenuCommand(ed, handlePasteOrDrop) {
|
|
|
92
89
|
});
|
|
93
90
|
} else {
|
|
94
91
|
const textType = cbitem.types.find(t => /^text\//.test(t));
|
|
95
|
-
|
|
96
92
|
if (textType) {
|
|
97
93
|
const blob = await cbitem.getType(textType);
|
|
98
94
|
const text = await blob.text();
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
/*
|
|
4
2
|
* Copyright (C) 2022 - present Instructure, Inc.
|
|
5
3
|
*
|
|
@@ -17,6 +15,7 @@
|
|
|
17
15
|
* You should have received a copy of the GNU Affero General Public License along
|
|
18
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
17
|
*/
|
|
18
|
+
|
|
20
19
|
import tinymce from 'tinymce';
|
|
21
20
|
import bridge from '../../../bridge';
|
|
22
21
|
import configureStore from '../../../sidebar/store/configureStore';
|
|
@@ -34,7 +33,9 @@ const config = {
|
|
|
34
33
|
session: null,
|
|
35
34
|
// null: we haven't gotten it yet, false: we don't need it
|
|
36
35
|
sessionPromise: null
|
|
37
|
-
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// when UploadFile renders
|
|
38
39
|
// <StoreProvider {...trayProps}>
|
|
39
40
|
// {contentProps => {
|
|
40
41
|
// return (
|
|
@@ -43,17 +44,18 @@ const config = {
|
|
|
43
44
|
// (We don't seem to have a way to grab an existing store)
|
|
44
45
|
// So the configureStore and getSession logic gets repeated here for the
|
|
45
46
|
// automatic file upload when pasting or dropping a file on the RCE
|
|
46
|
-
|
|
47
|
+
// @ts-expect-error
|
|
47
48
|
function initStore(initProps) {
|
|
48
49
|
if (config.store === null) {
|
|
49
50
|
config.store = configureStore(initProps);
|
|
50
51
|
}
|
|
51
|
-
|
|
52
52
|
if (config.session === null) {
|
|
53
53
|
if (initProps.host && initProps.jwt) {
|
|
54
54
|
config.sessionPromise = getSession(config.store.dispatch, config.store.getState).then(() => {
|
|
55
55
|
config.session = config.store.getState().session;
|
|
56
|
-
})
|
|
56
|
+
})
|
|
57
|
+
// @ts-expect-error
|
|
58
|
+
.catch(_err => {
|
|
57
59
|
// eslint-disable-next-line no-console
|
|
58
60
|
console.error('The Paste plugin failed to get canvas session data.');
|
|
59
61
|
});
|
|
@@ -63,12 +65,11 @@ function initStore(initProps) {
|
|
|
63
65
|
config.sessionPromise = Promise.resolve();
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
|
-
|
|
67
68
|
return config.store;
|
|
68
69
|
}
|
|
69
|
-
|
|
70
70
|
tinymce.PluginManager.add('instructure_paste', function (editor) {
|
|
71
71
|
const store = initStore(bridge.trayProps.get(editor));
|
|
72
|
+
|
|
72
73
|
/**
|
|
73
74
|
* Starts the file upload (and insertion) process for the given file.
|
|
74
75
|
*
|
|
@@ -76,13 +77,11 @@ tinymce.PluginManager.add('instructure_paste', function (editor) {
|
|
|
76
77
|
*
|
|
77
78
|
* @returns a promise that resolves when the user has made their choice about uploading the file
|
|
78
79
|
*/
|
|
79
|
-
|
|
80
80
|
async function requestFileInsertion(file) {
|
|
81
81
|
// it's very doubtful that we won't have retrieved the session data yet,
|
|
82
82
|
// since it takes a while for the RCE to initialize, but if we haven't
|
|
83
83
|
// wait until we do to carry on and finish pasting.
|
|
84
84
|
await config.sessionPromise;
|
|
85
|
-
|
|
86
85
|
if (config.session === null) {
|
|
87
86
|
// we failed to get the session and don't know if usage rights are required in this course|group
|
|
88
87
|
// In all probability, the file upload will fail too, but I feel like we have to do something here.
|
|
@@ -90,12 +89,11 @@ tinymce.PluginManager.add('instructure_paste', function (editor) {
|
|
|
90
89
|
message: formatMessage('If Usage Rights are required, the file will not publish until enabled in the Files page.'),
|
|
91
90
|
type: 'info'
|
|
92
91
|
});
|
|
93
|
-
}
|
|
94
|
-
// on the user to store it. Only Group and Course.
|
|
95
|
-
|
|
92
|
+
}
|
|
96
93
|
|
|
94
|
+
// even though usage rights might be required by the course, canvas has no place
|
|
95
|
+
// on the user to store it. Only Group and Course.
|
|
97
96
|
const requiresUsageRights = config.session.usageRightsRequired && /course|group/.test(bridge.trayProps.get(editor).contextType);
|
|
98
|
-
|
|
99
97
|
if (requiresUsageRights) {
|
|
100
98
|
return doFileUpload(editor, document, {
|
|
101
99
|
accept: file.type,
|
|
@@ -114,61 +112,61 @@ tinymce.PluginManager.add('instructure_paste', function (editor) {
|
|
|
114
112
|
domObject: file
|
|
115
113
|
};
|
|
116
114
|
let tabContext = 'documents';
|
|
117
|
-
|
|
118
115
|
if (isImage(file.type)) {
|
|
119
116
|
tabContext = 'images';
|
|
120
117
|
} else if (isAudioOrVideo(file.type)) {
|
|
121
118
|
tabContext = 'media';
|
|
122
119
|
}
|
|
123
|
-
|
|
124
120
|
store.dispatch(uploadToMediaFolder(tabContext, fileMetaProps));
|
|
125
121
|
return 'submitted';
|
|
126
122
|
}
|
|
127
123
|
}
|
|
128
|
-
|
|
129
124
|
async function handlePasteOrDrop(event) {
|
|
130
125
|
var _bridge$activeEditor, _bridge$activeEditor$, _editor$rceWrapper;
|
|
131
|
-
|
|
132
126
|
const isPaste = event.type === 'paste';
|
|
133
127
|
const dataTransfer = isPaste ? event.clipboardData : event.dataTransfer;
|
|
134
128
|
const files = Array.from((dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.files) || []);
|
|
135
129
|
const types = (dataTransfer === null || dataTransfer === void 0 ? void 0 : dataTransfer.types) || [];
|
|
136
|
-
const isAudioVideoDisabled = (_bridge$activeEditor = bridge.activeEditor()) === null || _bridge$activeEditor === void 0 ? void 0 : (_bridge$activeEditor$ = _bridge$activeEditor.props) === null || _bridge$activeEditor$ === void 0 ? void 0 : _bridge$activeEditor$.instRecordDisabled;
|
|
130
|
+
const isAudioVideoDisabled = (_bridge$activeEditor = bridge.activeEditor()) === null || _bridge$activeEditor === void 0 ? void 0 : (_bridge$activeEditor$ = _bridge$activeEditor.props) === null || _bridge$activeEditor$ === void 0 ? void 0 : _bridge$activeEditor$.instRecordDisabled;
|
|
131
|
+
|
|
132
|
+
// delegate to tiny if there aren't any files to handle
|
|
133
|
+
if (!types.includes('Files')) return;
|
|
137
134
|
|
|
138
|
-
|
|
135
|
+
// delegate to tiny if there is Microsoft Word content, because it may contain an image
|
|
139
136
|
// rendering of the content and we don't want to incorrectly paste the image
|
|
140
137
|
// instead of the actual rich content, which TinyMCE has special handing for
|
|
138
|
+
if (isMicrosoftWordContentInEvent(event)) return;
|
|
141
139
|
|
|
142
|
-
|
|
140
|
+
// we're pasting file(s), prevent the default tinymce pasting behavior
|
|
141
|
+
event.preventDefault();
|
|
143
142
|
|
|
144
|
-
|
|
143
|
+
// Ensure the editor has focus, because downstream code requires that it does, and drag-n-drop
|
|
145
144
|
// events can be started when the editor doesn't have focus.
|
|
145
|
+
if (!editor.hasFocus()) (_editor$rceWrapper = editor.rceWrapper) === null || _editor$rceWrapper === void 0 ? void 0 : _editor$rceWrapper.focus();
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
// Checking if we've encountered an issue with file processing for paste events in the browser
|
|
148
148
|
// Specifically implementing due to this bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1699743
|
|
149
149
|
// However, there could be other issues that cause this condition so it's a nice safety net regardless
|
|
150
|
-
|
|
151
150
|
if (isPaste && files.some(file => file.size === 0)) {
|
|
151
|
+
// @ts-expect-error
|
|
152
152
|
showFlashAlert({
|
|
153
153
|
message: formatMessage('One or more files failed to paste. Please try uploading or dragging and dropping files.'),
|
|
154
154
|
type: 'error'
|
|
155
155
|
});
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
158
|
-
|
|
159
158
|
for (const file of files) {
|
|
160
159
|
if (isAudioVideoDisabled && isAudioOrVideo(file.type)) {
|
|
161
160
|
// Skip audio and video files when disabled
|
|
162
161
|
continue;
|
|
163
|
-
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// This will finish once the dialog is closed, if one was created, putting this in a loop allows us
|
|
164
165
|
// to show a dialog for each file without them conflicting.
|
|
165
166
|
// eslint-disable-next-line no-await-in-loop
|
|
166
|
-
|
|
167
|
-
|
|
168
167
|
await requestFileInsertion(file);
|
|
169
168
|
}
|
|
170
169
|
}
|
|
171
|
-
|
|
172
170
|
editor.on('paste', handlePasteOrDrop);
|
|
173
171
|
editor.on('drop', handlePasteOrDrop);
|
|
174
172
|
});
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
/*
|
|
4
2
|
* Copyright (C) 2023 - present Instructure, Inc.
|
|
5
3
|
*
|
|
@@ -17,65 +15,55 @@
|
|
|
17
15
|
* You should have received a copy of the GNU Affero General Public License along
|
|
18
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19
17
|
*/
|
|
18
|
+
|
|
20
19
|
import RCEWrapper from '../../RCEWrapper';
|
|
20
|
+
import { fallbackIframeAllowances } from './constants';
|
|
21
21
|
|
|
22
|
-
/**
|
|
23
|
-
* Fallback iframe allowances used when they aren't provided to the editor.
|
|
24
|
-
*/
|
|
25
|
-
export const fallbackIframeAllowances = ['geolocation *', 'microphone *', 'camera *', 'midi *', 'encrypted-media *', 'autoplay *', 'clipboard-write *', 'display-capture *'];
|
|
26
22
|
/**
|
|
27
23
|
* Type of the "editor buttons" that come from Canvas.
|
|
28
24
|
*
|
|
29
25
|
* They're actually the available LTI Tool configurations, so we give them a more reasonable name here.
|
|
30
26
|
*/
|
|
31
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Subset of TinyMCE used by the ExternalTools dialog. Used to document the subset of the API that we use so
|
|
30
|
+
* it's easier to test.
|
|
31
|
+
*/
|
|
32
|
+
|
|
32
33
|
/**
|
|
33
34
|
* Gets the environment information for the external tools dialog for a given tinyMCE editor.
|
|
34
35
|
*/
|
|
35
36
|
export function externalToolsEnvFor(editor) {
|
|
36
37
|
const props = () => {
|
|
37
38
|
var _ref, _RCEWrapper$getByEdit;
|
|
38
|
-
|
|
39
39
|
return (_ref = (_RCEWrapper$getByEdit = RCEWrapper.getByEditor(editor)) === null || _RCEWrapper$getByEdit === void 0 ? void 0 : _RCEWrapper$getByEdit.props) !== null && _ref !== void 0 ? _ref : undefined;
|
|
40
40
|
};
|
|
41
|
-
|
|
42
41
|
let cachedCanvasToolId;
|
|
43
|
-
|
|
44
42
|
function nonNullishArray(arr) {
|
|
45
43
|
return arr === null || arr === void 0 ? void 0 : arr.filter(it => it != null);
|
|
46
44
|
}
|
|
47
|
-
|
|
48
45
|
return {
|
|
49
46
|
editor: editor !== null && editor !== void 0 ? editor : null,
|
|
50
|
-
|
|
51
47
|
get rceWrapper() {
|
|
52
48
|
var _RCEWrapper$getByEdit2;
|
|
53
|
-
|
|
54
49
|
return (_RCEWrapper$getByEdit2 = RCEWrapper.getByEditor(editor)) !== null && _RCEWrapper$getByEdit2 !== void 0 ? _RCEWrapper$getByEdit2 : null;
|
|
55
50
|
},
|
|
56
|
-
|
|
57
51
|
get availableRceLtiTools() {
|
|
58
52
|
var _nonNullishArray, _props;
|
|
59
|
-
|
|
60
53
|
return (_nonNullishArray = nonNullishArray((_props = props()) === null || _props === void 0 ? void 0 : _props.ltiTools)) !== null && _nonNullishArray !== void 0 ? _nonNullishArray : [];
|
|
61
54
|
},
|
|
62
|
-
|
|
63
55
|
/**
|
|
64
56
|
* Gets information about the context in which the editor is launched.
|
|
65
57
|
*/
|
|
66
58
|
get contextAssetInfo() {
|
|
67
59
|
var _props2;
|
|
68
|
-
|
|
69
60
|
const trayProps = (_props2 = props()) === null || _props2 === void 0 ? void 0 : _props2.trayProps;
|
|
70
|
-
|
|
71
61
|
if (trayProps != null) {
|
|
72
62
|
var _trayProps$containing;
|
|
73
|
-
|
|
74
63
|
const {
|
|
75
64
|
contextId,
|
|
76
65
|
contextType
|
|
77
66
|
} = (_trayProps$containing = trayProps.containingContext) !== null && _trayProps$containing !== void 0 ? _trayProps$containing : trayProps;
|
|
78
|
-
|
|
79
67
|
if (contextId != null && contextId.length > 0 && contextType != null && contextType.length > 0) {
|
|
80
68
|
return {
|
|
81
69
|
contextType,
|
|
@@ -83,93 +71,66 @@ export function externalToolsEnvFor(editor) {
|
|
|
83
71
|
};
|
|
84
72
|
}
|
|
85
73
|
}
|
|
86
|
-
|
|
87
74
|
return null;
|
|
88
75
|
},
|
|
89
|
-
|
|
90
76
|
get resourceSelectionUrlOverride() {
|
|
91
77
|
var _props$externalToolsC, _props3, _props3$externalTools;
|
|
92
|
-
|
|
93
78
|
return (_props$externalToolsC = (_props3 = props()) === null || _props3 === void 0 ? void 0 : (_props3$externalTools = _props3.externalToolsConfig) === null || _props3$externalTools === void 0 ? void 0 : _props3$externalTools.resourceSelectionUrlOverride) !== null && _props$externalToolsC !== void 0 ? _props$externalToolsC : null;
|
|
94
79
|
},
|
|
95
|
-
|
|
96
80
|
get ltiIframeAllowPolicy() {
|
|
97
81
|
var _nonNullishArray2, _props4, _props4$externalTools;
|
|
98
|
-
|
|
99
82
|
return ((_nonNullishArray2 = nonNullishArray((_props4 = props()) === null || _props4 === void 0 ? void 0 : (_props4$externalTools = _props4.externalToolsConfig) === null || _props4$externalTools === void 0 ? void 0 : _props4$externalTools.ltiIframeAllowances)) !== null && _nonNullishArray2 !== void 0 ? _nonNullishArray2 : fallbackIframeAllowances).join('; ');
|
|
100
83
|
},
|
|
101
|
-
|
|
102
84
|
get isA2StudentView() {
|
|
103
85
|
var _props$externalToolsC2, _props5, _props5$externalTools;
|
|
104
|
-
|
|
105
86
|
return (_props$externalToolsC2 = (_props5 = props()) === null || _props5 === void 0 ? void 0 : (_props5$externalTools = _props5.externalToolsConfig) === null || _props5$externalTools === void 0 ? void 0 : _props5$externalTools.isA2StudentView) !== null && _props$externalToolsC2 !== void 0 ? _props$externalToolsC2 : false;
|
|
106
87
|
},
|
|
107
|
-
|
|
108
88
|
get maxMruTools() {
|
|
109
89
|
var _props$externalToolsC3, _props6, _props6$externalTools;
|
|
110
|
-
|
|
111
90
|
return (_props$externalToolsC3 = (_props6 = props()) === null || _props6 === void 0 ? void 0 : (_props6$externalTools = _props6.externalToolsConfig) === null || _props6$externalTools === void 0 ? void 0 : _props6$externalTools.maxMruTools) !== null && _props$externalToolsC3 !== void 0 ? _props$externalToolsC3 : 5;
|
|
112
91
|
},
|
|
113
|
-
|
|
114
92
|
get canvasOrigin() {
|
|
115
93
|
var _props$canvasOrigin, _props7;
|
|
116
|
-
|
|
117
94
|
return (_props$canvasOrigin = (_props7 = props()) === null || _props7 === void 0 ? void 0 : _props7.canvasOrigin) !== null && _props$canvasOrigin !== void 0 ? _props$canvasOrigin : window.location.origin;
|
|
118
95
|
},
|
|
119
|
-
|
|
120
96
|
/**
|
|
121
97
|
* Gets the context id that should be used when launching LTI iframes.
|
|
122
98
|
*/
|
|
123
99
|
get containingCanvasLtiToolId() {
|
|
124
100
|
var _props8, _props8$externalTools;
|
|
125
|
-
|
|
126
101
|
const propsToolId = (_props8 = props()) === null || _props8 === void 0 ? void 0 : (_props8$externalTools = _props8.externalToolsConfig) === null || _props8$externalTools === void 0 ? void 0 : _props8$externalTools.containingCanvasLtiToolId;
|
|
127
|
-
|
|
128
102
|
if (typeof propsToolId === 'string') {
|
|
129
103
|
return propsToolId;
|
|
130
104
|
}
|
|
131
|
-
|
|
132
105
|
try {
|
|
133
106
|
if (cachedCanvasToolId === undefined) {
|
|
134
107
|
// Fall back on localStorage until NQ implements
|
|
135
108
|
cachedCanvasToolId = window.localStorage.getItem('canvas_tool_id');
|
|
136
109
|
}
|
|
137
|
-
|
|
138
110
|
return cachedCanvasToolId;
|
|
139
111
|
} catch {
|
|
140
112
|
return null;
|
|
141
113
|
}
|
|
142
114
|
},
|
|
143
|
-
|
|
144
115
|
get editorSelection() {
|
|
145
116
|
var _editor$selection$get, _editor$selection;
|
|
146
|
-
|
|
147
117
|
return (_editor$selection$get = editor === null || editor === void 0 ? void 0 : (_editor$selection = editor.selection) === null || _editor$selection === void 0 ? void 0 : _editor$selection.getContent()) !== null && _editor$selection$get !== void 0 ? _editor$selection$get : null;
|
|
148
118
|
},
|
|
149
|
-
|
|
150
119
|
get editorContent() {
|
|
151
120
|
var _editor$getContent;
|
|
152
|
-
|
|
153
121
|
return (_editor$getContent = editor === null || editor === void 0 ? void 0 : editor.getContent()) !== null && _editor$getContent !== void 0 ? _editor$getContent : null;
|
|
154
122
|
},
|
|
155
|
-
|
|
156
123
|
insertCode(code) {
|
|
157
124
|
var _this$rceWrapper;
|
|
158
|
-
|
|
159
|
-
|
|
125
|
+
if ((_this$rceWrapper = this.rceWrapper) !== null && _this$rceWrapper !== void 0 && _this$rceWrapper.insertCode) {
|
|
126
|
+
this.rceWrapper.insertCode(code);
|
|
127
|
+
}
|
|
160
128
|
},
|
|
161
|
-
|
|
162
129
|
replaceCode(code) {
|
|
163
130
|
var _this$rceWrapper2;
|
|
164
|
-
|
|
165
|
-
|
|
131
|
+
if ((_this$rceWrapper2 = this.rceWrapper) !== null && _this$rceWrapper2 !== void 0 && _this$rceWrapper2.replaceCode) {
|
|
132
|
+
this.rceWrapper.replaceCode(code);
|
|
133
|
+
}
|
|
166
134
|
}
|
|
167
|
-
|
|
168
135
|
};
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Name of the parameter used to indicate to Canvas that it is being loaded in an iframe inside of an
|
|
172
|
-
* LTI tool. It should be set to the global id of the containing tool.
|
|
173
|
-
*/
|
|
174
|
-
|
|
175
|
-
export const PARENT_FRAME_CONTEXT_PARAM = 'parent_frame_context';
|
|
136
|
+
}
|
|
@@ -15,22 +15,24 @@
|
|
|
15
15
|
* You should have received a copy of the GNU Affero General Public License along
|
|
16
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
+
|
|
18
19
|
import { openToolDialogFor } from './dialog-helper';
|
|
19
20
|
import { simpleCache } from '../../../util/simpleCache';
|
|
20
|
-
import { instUiIconsArray } from '../../../util/instui-icon-helper';
|
|
21
|
+
import { instUiIconsArray } from '../../../util/instui-icon-helper';
|
|
21
22
|
|
|
23
|
+
// @ts-ignore
|
|
22
24
|
import { IconLtiSolid } from '@instructure/ui-icons/es/svg';
|
|
23
25
|
export function externalToolsForToolbar(tools) {
|
|
24
26
|
// Limit of not on_by_default but favorited tools is 2
|
|
25
27
|
const favorited = tools.filter(it => it.favorite && !it.on_by_default).slice(0, 2) || [];
|
|
26
28
|
const onByDefault = tools.filter(it => it.on_by_default && it.favorite) || [];
|
|
27
|
-
const set = new Map();
|
|
28
|
-
// we'd have duplicate buttons in the toolbar.
|
|
29
|
+
const set = new Map();
|
|
29
30
|
|
|
31
|
+
// Remove possible overlaps between favorited and onByDefault, otherwise
|
|
32
|
+
// we'd have duplicate buttons in the toolbar.
|
|
30
33
|
for (const toolInfo of favorited.concat(onByDefault)) {
|
|
31
34
|
set.set(toolInfo.id, toolInfo);
|
|
32
35
|
}
|
|
33
|
-
|
|
34
36
|
return Array.from(set.values()).sort((a, b) => {
|
|
35
37
|
if (a.on_by_default && !b.on_by_default) {
|
|
36
38
|
return -1;
|
|
@@ -45,75 +47,59 @@ export function externalToolsForToolbar(tools) {
|
|
|
45
47
|
}
|
|
46
48
|
});
|
|
47
49
|
}
|
|
50
|
+
|
|
48
51
|
/**
|
|
49
52
|
* Helper class for the connection between an external tool registration and a particular TinyMCE instance.
|
|
50
53
|
*/
|
|
51
|
-
|
|
52
54
|
export class RceToolWrapper {
|
|
53
55
|
static forEditorEnv(env) {
|
|
54
56
|
let toolConfigs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : env.availableRceLtiTools;
|
|
55
57
|
let mruIds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : loadMruToolIds();
|
|
56
58
|
return toolConfigs.map(it => new RceToolWrapper(env, it, mruIds));
|
|
57
59
|
}
|
|
58
|
-
|
|
59
60
|
get editor() {
|
|
60
61
|
return this.env.editor;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
63
|
constructor(env, toolInfo, mruToolIds) {
|
|
64
|
-
this.env = env;
|
|
65
|
-
this.toolInfo = toolInfo;
|
|
66
64
|
this.iconId = void 0;
|
|
67
65
|
this.isMruTool = void 0;
|
|
66
|
+
this.env = env;
|
|
67
|
+
this.toolInfo = toolInfo;
|
|
68
68
|
this.iconId = registerToolIcon(env, toolInfo);
|
|
69
69
|
this.isMruTool = mruToolIds.includes(String(toolInfo.id));
|
|
70
70
|
}
|
|
71
|
-
|
|
72
71
|
get id() {
|
|
73
72
|
return String(this.toolInfo.id);
|
|
74
73
|
}
|
|
75
|
-
|
|
76
74
|
get title() {
|
|
77
75
|
var _this$toolInfo$name;
|
|
78
|
-
|
|
79
76
|
return (_this$toolInfo$name = this.toolInfo.name) !== null && _this$toolInfo$name !== void 0 ? _this$toolInfo$name : `Unknown tool (${String(this.toolInfo.id)})`;
|
|
80
77
|
}
|
|
81
|
-
|
|
82
78
|
get description() {
|
|
83
79
|
return this.toolInfo.description;
|
|
84
80
|
}
|
|
85
|
-
|
|
86
81
|
get favorite() {
|
|
87
82
|
var _this$toolInfo$favori;
|
|
88
|
-
|
|
89
83
|
return (_this$toolInfo$favori = this.toolInfo.favorite) !== null && _this$toolInfo$favori !== void 0 ? _this$toolInfo$favori : false;
|
|
90
84
|
}
|
|
91
|
-
|
|
92
85
|
get image() {
|
|
93
86
|
var _parseIconValueFor;
|
|
94
|
-
|
|
95
87
|
return (_parseIconValueFor = parseIconValueFor(this.toolInfo)) === null || _parseIconValueFor === void 0 ? void 0 : _parseIconValueFor.iconUrl;
|
|
96
88
|
}
|
|
97
|
-
|
|
98
89
|
get width() {
|
|
99
90
|
return this.toolInfo.width;
|
|
100
91
|
}
|
|
101
|
-
|
|
102
92
|
get height() {
|
|
103
93
|
return this.toolInfo.height;
|
|
104
94
|
}
|
|
105
|
-
|
|
106
95
|
get use_tray() {
|
|
107
96
|
return this.toolInfo.use_tray;
|
|
108
97
|
}
|
|
109
|
-
|
|
110
98
|
get on_by_default() {
|
|
111
99
|
return this.toolInfo.on_by_default;
|
|
112
100
|
}
|
|
113
|
-
|
|
114
101
|
asToolbarButton() {
|
|
115
102
|
var _this$iconId;
|
|
116
|
-
|
|
117
103
|
return {
|
|
118
104
|
type: 'button',
|
|
119
105
|
icon: (_this$iconId = this.iconId) !== null && _this$iconId !== void 0 ? _this$iconId : undefined,
|
|
@@ -121,10 +107,8 @@ export class RceToolWrapper {
|
|
|
121
107
|
onAction: () => this.openDialog()
|
|
122
108
|
};
|
|
123
109
|
}
|
|
124
|
-
|
|
125
110
|
asMenuItem() {
|
|
126
111
|
var _this$iconId2;
|
|
127
|
-
|
|
128
112
|
return {
|
|
129
113
|
type: 'menuitem',
|
|
130
114
|
text: this.title,
|
|
@@ -132,48 +116,44 @@ export class RceToolWrapper {
|
|
|
132
116
|
onAction: () => this.openDialog()
|
|
133
117
|
};
|
|
134
118
|
}
|
|
135
|
-
|
|
136
119
|
openDialog() {
|
|
137
120
|
addMruToolId(this.id, this.env);
|
|
138
121
|
openToolDialogFor(this);
|
|
139
122
|
}
|
|
140
|
-
|
|
141
123
|
}
|
|
142
124
|
export function parseIconValueFor(toolInfo) {
|
|
143
125
|
const result = {};
|
|
144
|
-
const canvasIconClass = toolInfo.canvas_icon_class;
|
|
126
|
+
const canvasIconClass = toolInfo.canvas_icon_class;
|
|
145
127
|
|
|
128
|
+
// URL embedded in canvas_icon_class, which happens in some cases (see MAT-1354)
|
|
146
129
|
if (typeof canvasIconClass === 'object') {
|
|
147
130
|
const iconUrl = canvasIconClass === null || canvasIconClass === void 0 ? void 0 : canvasIconClass.icon_url;
|
|
148
|
-
|
|
149
131
|
if (typeof iconUrl === 'string' && iconUrl !== '') {
|
|
150
132
|
result.iconUrl = iconUrl;
|
|
151
133
|
}
|
|
152
|
-
}
|
|
153
|
-
|
|
134
|
+
}
|
|
154
135
|
|
|
136
|
+
// URL at the top level takes precedence
|
|
155
137
|
if (typeof toolInfo.icon_url === 'string' && toolInfo.icon_url !== '') {
|
|
156
138
|
result.iconUrl = toolInfo.icon_url;
|
|
157
|
-
}
|
|
158
|
-
|
|
139
|
+
}
|
|
159
140
|
|
|
141
|
+
// Icon class as string
|
|
160
142
|
if (typeof canvasIconClass === 'string' && canvasIconClass !== '') {
|
|
161
143
|
result.canvasIconClass = canvasIconClass;
|
|
162
144
|
}
|
|
163
|
-
|
|
164
145
|
return result;
|
|
165
146
|
}
|
|
166
|
-
|
|
167
147
|
function registerToolIcon(env, toolInfo) {
|
|
168
148
|
if (env.editor == null) return undefined;
|
|
169
149
|
const iconId = 'lti_tool_' + String(toolInfo.id);
|
|
170
150
|
const {
|
|
171
151
|
iconUrl,
|
|
172
152
|
canvasIconClass
|
|
173
|
-
} = parseIconValueFor(toolInfo);
|
|
153
|
+
} = parseIconValueFor(toolInfo);
|
|
174
154
|
|
|
155
|
+
// We need to strip off the icon- or icon_ prefix from the icon class name to match instui icons
|
|
175
156
|
const iconGlyphName = (canvasIconClass !== null && canvasIconClass !== void 0 ? canvasIconClass : '').replace(/^icon[-_]/, '');
|
|
176
|
-
|
|
177
157
|
if (iconUrl != null && iconUrl.length > 0) {
|
|
178
158
|
// Icon image provided
|
|
179
159
|
env.editor.ui.registry.addIcon(iconId, svgImageCache.get(iconUrl));
|
|
@@ -181,18 +161,16 @@ function registerToolIcon(env, toolInfo) {
|
|
|
181
161
|
} else if (iconGlyphName != null && iconGlyphName.length > 0) {
|
|
182
162
|
// InstUI icon used
|
|
183
163
|
const instUiIcon = instUiIconsArray.find(it => it.variant === 'Line' && it.glyphName === iconGlyphName);
|
|
184
|
-
|
|
185
164
|
if (instUiIcon != null) {
|
|
186
165
|
env.editor.ui.registry.addIcon(iconId, instUiIcon.src);
|
|
187
166
|
return iconId;
|
|
188
167
|
}
|
|
189
|
-
}
|
|
190
|
-
|
|
168
|
+
}
|
|
191
169
|
|
|
170
|
+
// Fallback to default icon
|
|
192
171
|
env.editor.ui.registry.addIcon(iconId, IconLtiSolid.src);
|
|
193
172
|
return iconId;
|
|
194
173
|
}
|
|
195
|
-
|
|
196
174
|
const svgImageCache = simpleCache(imageUrl => {
|
|
197
175
|
// Sanitize input against XSS
|
|
198
176
|
const svg = document.createElement('svg');
|
|
@@ -206,32 +184,28 @@ const svgImageCache = simpleCache(imageUrl => {
|
|
|
206
184
|
svg.appendChild(image);
|
|
207
185
|
return svg.outerHTML;
|
|
208
186
|
});
|
|
187
|
+
|
|
209
188
|
/**
|
|
210
189
|
* Loads the list of most recently used external tool ids.
|
|
211
190
|
*/
|
|
212
|
-
|
|
213
191
|
export function loadMruToolIds() {
|
|
214
192
|
let list;
|
|
215
|
-
|
|
216
193
|
try {
|
|
217
194
|
var _window$localStorage$, _window$localStorage;
|
|
218
|
-
|
|
219
195
|
list = JSON.parse((_window$localStorage$ = (_window$localStorage = window.localStorage) === null || _window$localStorage === void 0 ? void 0 : _window$localStorage.getItem('ltimru')) !== null && _window$localStorage$ !== void 0 ? _window$localStorage$ : '[]');
|
|
220
196
|
} catch (ex) {
|
|
221
197
|
// eslint-disable-next-line no-console
|
|
222
198
|
console.warn('Found bad LTI MRU data', ex.message);
|
|
223
199
|
}
|
|
224
|
-
|
|
225
200
|
return Array.isArray(list) ? list.filter(it => it != null).map(it => String(it)) : [];
|
|
226
201
|
}
|
|
202
|
+
|
|
227
203
|
/**
|
|
228
204
|
* Loads the list of most recently used external tool ids.
|
|
229
205
|
*/
|
|
230
|
-
|
|
231
206
|
export function storeMruToolIds(toolIds) {
|
|
232
207
|
try {
|
|
233
208
|
var _window$localStorage2;
|
|
234
|
-
|
|
235
209
|
(_window$localStorage2 = window.localStorage) === null || _window$localStorage2 === void 0 ? void 0 : _window$localStorage2.setItem('ltimru', JSON.stringify(toolIds));
|
|
236
210
|
} catch (ex) {
|
|
237
211
|
// eslint-disable-next-line no-console
|
|
@@ -240,13 +214,11 @@ export function storeMruToolIds(toolIds) {
|
|
|
240
214
|
}
|
|
241
215
|
export function addMruToolId(toolId, env) {
|
|
242
216
|
const initialMruToolIds = loadMruToolIds();
|
|
243
|
-
|
|
244
217
|
if (!initialMruToolIds.includes(toolId)) {
|
|
245
218
|
const newToolIds = [toolId, ...initialMruToolIds.slice(0, env.maxMruTools - 1)];
|
|
246
219
|
storeMruToolIds(newToolIds);
|
|
247
220
|
return newToolIds;
|
|
248
221
|
}
|
|
249
|
-
|
|
250
222
|
return initialMruToolIds;
|
|
251
223
|
}
|
|
252
224
|
export function buildToolMenuItems(availableTools, viewAllItem) {
|