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