@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
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
|
|
3
1
|
/*
|
|
4
2
|
* Copyright (C) 2019 - present Instructure, Inc.
|
|
5
3
|
*
|
|
@@ -17,10 +15,14 @@
|
|
|
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
|
*/
|
|
20
|
-
|
|
18
|
+
|
|
19
|
+
import { IconArrowOpenDownLine, IconAttachMediaLine, IconBoldLine, IconBulletListAlphaLine, IconBulletListCircleOutlineLine, IconBulletListLine, IconBulletListRomanLine, IconBulletListSquareLine, IconClearTextFormattingLine, IconDocumentLine, IconExitFullScreenLine, IconFullScreenLine, IconImageLine, IconIndentLine, IconItalicLine, IconLinkLine, IconLtiLine, IconNumberedListLine, IconOutdentLine, IconRemoveLinkLine, IconStrikethroughLine, IconTextCenteredLine, IconTextDirectionLtrLine, IconTextDirectionRtlLine, IconTextEndLine, IconTextStartLine, IconTextSubscriptLine, IconTextSuperscriptLine, IconUnderlineLine
|
|
20
|
+
// @ts-expect-error
|
|
21
|
+
} from '@instructure/ui-icons/es/svg';
|
|
21
22
|
import tinymce from 'tinymce';
|
|
22
23
|
tinymce.PluginManager.add('instructure-ui-icons', function (editor) {
|
|
23
24
|
// the keys here are what tinymce calls it. the values are the svgs from instUI
|
|
25
|
+
|
|
24
26
|
// there are few things here that are commented out that are things that we
|
|
25
27
|
// might want to have our own icon for but one doesn't exist in @instructure/ui-icons
|
|
26
28
|
const icons = {
|
|
@@ -55,6 +57,7 @@ tinymce.PluginManager.add('instructure-ui-icons', function (editor) {
|
|
|
55
57
|
// that tinyMCE uses that we'd want to match our table icon. So unless we get instUI versions of all
|
|
56
58
|
// those too, it probably makes sense to just use TinyMCE's for everything table related.
|
|
57
59
|
// table: IconTableLine,
|
|
60
|
+
|
|
58
61
|
// The `tox-icon-*` path ids on these 2 are important. It is what tinyMCE
|
|
59
62
|
// looks for to update the color when you select a new one
|
|
60
63
|
'text-color': {
|
|
@@ -75,6 +78,20 @@ tinymce.PluginManager.add('instructure-ui-icons', function (editor) {
|
|
|
75
78
|
</g>
|
|
76
79
|
</svg>`
|
|
77
80
|
},
|
|
81
|
+
// the new color UI
|
|
82
|
+
color: {
|
|
83
|
+
src: `<svg data-id="color-button" width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
84
|
+
<g clip-path="url(#clip0_13_7929)">
|
|
85
|
+
<path d="M5.52715 0L4.48118 1.01914L5.82475 2.33149L0.672221 7.36027C-0.224074 8.23479 -0.224074 9.6186 0.672221 10.4931L0.74662 10.5671L5.45129 15.1575C6.34759 16.032 7.7673 16.032 8.6636 15.1575L14.3398 9.61917L14.8636 9.1096L7.61763 2.0397L7.02097 1.45754L6.87072 1.31093L5.52715 0ZM6.87072 3.35205L12.7716 9.1096L11.129 10.7123H2.9859L1.71673 9.47398C1.41797 9.18248 1.41797 8.67234 1.71673 8.38083L6.87072 3.35205ZM15.7593 11.6603L15.1611 12.5342C15.1611 12.5342 14.788 13.1167 14.3398 13.7726C14.1158 14.137 13.967 14.4288 13.8176 14.7931C13.6682 15.1575 13.5185 15.3764 13.5185 15.8137C13.5185 16.9797 14.5642 18 15.7593 18C16.9543 18 18 16.9797 18 15.8137C18 15.3764 17.8503 15.0849 17.7009 14.7205C17.5516 14.3562 17.3281 13.9915 17.1787 13.7C16.8052 13.0441 16.3574 12.4616 16.3574 12.4616L15.7593 11.6603Z" fill="currentColor"/>
|
|
86
|
+
</g>
|
|
87
|
+
<defs>
|
|
88
|
+
<clipPath id="clip0_13_7929">
|
|
89
|
+
<rect width="18" height="18" fill="white"/>
|
|
90
|
+
</clipPath>
|
|
91
|
+
</defs>
|
|
92
|
+
</svg>
|
|
93
|
+
`
|
|
94
|
+
},
|
|
78
95
|
unlink: IconRemoveLinkLine,
|
|
79
96
|
'unordered-list': IconBulletListLine,
|
|
80
97
|
ltr: IconTextDirectionLtrLine,
|
|
@@ -117,6 +134,7 @@ tinymce.PluginManager.add('instructure-ui-icons', function (editor) {
|
|
|
117
134
|
}
|
|
118
135
|
};
|
|
119
136
|
Object.keys(icons).forEach(key => {
|
|
137
|
+
// @ts-expect-error
|
|
120
138
|
editor.ui.registry.addIcon(key, icons[key].src);
|
|
121
139
|
});
|
|
122
140
|
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2023 - present Instructure, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Canvas.
|
|
5
|
+
*
|
|
6
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
+
* Software Foundation, version 3 of the License.
|
|
9
|
+
*
|
|
10
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
+
* details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import React from 'react';
|
|
20
|
+
import { createRoot } from 'react-dom/client';
|
|
21
|
+
import tinycolor from 'tinycolor2';
|
|
22
|
+
import { ColorPopup } from './components/ColorPopup';
|
|
23
|
+
const CONTAINER_ID = 'instructure-color-popup-container';
|
|
24
|
+
export default function (editor) {
|
|
25
|
+
let container = document.getElementById(CONTAINER_ID);
|
|
26
|
+
if (container == null) {
|
|
27
|
+
container = document.createElement('div');
|
|
28
|
+
container.id = CONTAINER_ID;
|
|
29
|
+
document.body.appendChild(container);
|
|
30
|
+
}
|
|
31
|
+
const handleDismiss = () => {
|
|
32
|
+
if (container) {
|
|
33
|
+
container._reactRoot?.unmount();
|
|
34
|
+
container._reactRoot = null;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const handleChange = newcolors => {
|
|
38
|
+
editor.undoManager.transact(() => {
|
|
39
|
+
if (newcolors.fgcolor) {
|
|
40
|
+
editor.execCommand('forecolor', false, newcolors.fgcolor);
|
|
41
|
+
}
|
|
42
|
+
if (newcolors.bgcolor) {
|
|
43
|
+
editor.execCommand('hilitecolor', false, newcolors.bgcolor);
|
|
44
|
+
}
|
|
45
|
+
if (newcolors.fgcolor || newcolors.bgcolor) {
|
|
46
|
+
editor.nodeChanged();
|
|
47
|
+
}
|
|
48
|
+
handleDismiss();
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
if (container?._reactRoot) {
|
|
52
|
+
handleDismiss();
|
|
53
|
+
document.removeEventListener('rce-text-block-popup-close', handleDismiss);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
document.addEventListener('rce-text-block-popup-close', handleDismiss);
|
|
57
|
+
const defaultTextColor = window.getComputedStyle(editor.getBody()).getPropertyValue('--ic-brand-font-color-dark').toLowerCase();
|
|
58
|
+
const styl = window.getComputedStyle(editor.selection.getNode());
|
|
59
|
+
const textColor = tinycolor(styl.getPropertyValue('color')).toHexString();
|
|
60
|
+
const bgColor_ = tinycolor(styl.getPropertyValue('background-color'));
|
|
61
|
+
const bgColor = bgColor_.getAlpha() === 1 ? bgColor_.toHexString() : bgColor_.toHex8String();
|
|
62
|
+
const target = document.querySelector('svg[data-id="color-button"]');
|
|
63
|
+
const root = createRoot(container);
|
|
64
|
+
container._reactRoot = root;
|
|
65
|
+
root.render(/*#__PURE__*/React.createElement(ColorPopup, {
|
|
66
|
+
tabs: {
|
|
67
|
+
foreground: {
|
|
68
|
+
color: textColor,
|
|
69
|
+
default: defaultTextColor
|
|
70
|
+
},
|
|
71
|
+
background: {
|
|
72
|
+
color: bgColor,
|
|
73
|
+
default: '#ffffff'
|
|
74
|
+
},
|
|
75
|
+
effectiveBgColor: '#ffffff'
|
|
76
|
+
},
|
|
77
|
+
open: true,
|
|
78
|
+
positionTarget: target,
|
|
79
|
+
onCancel: handleDismiss,
|
|
80
|
+
onChange: handleChange
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import _pt from "prop-types";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2024 - present Instructure, Inc.
|
|
4
|
+
*
|
|
5
|
+
* This file is part of Canvas.
|
|
6
|
+
*
|
|
7
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
|
8
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
|
9
|
+
* Software Foundation, version 3 of the License.
|
|
10
|
+
*
|
|
11
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
12
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
13
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
14
|
+
* details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License along
|
|
17
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import React, { useCallback, useState } from 'react';
|
|
21
|
+
import tinycolor from 'tinycolor2';
|
|
22
|
+
import formatMessage from '../../../../format-message';
|
|
23
|
+
import { Button } from '@instructure/ui-buttons';
|
|
24
|
+
import { ColorPreset, ColorMixer, ColorContrast } from '@instructure/ui-color-picker';
|
|
25
|
+
import { Flex } from '@instructure/ui-flex';
|
|
26
|
+
import { Pill } from '@instructure/ui-pill';
|
|
27
|
+
import { RadioInputGroup, RadioInput } from '@instructure/ui-radio-input';
|
|
28
|
+
import { Tabs } from '@instructure/ui-tabs';
|
|
29
|
+
import { Text } from '@instructure/ui-text';
|
|
30
|
+
import { ToggleDetails } from '@instructure/ui-toggle-details';
|
|
31
|
+
import { View } from '@instructure/ui-view';
|
|
32
|
+
import { isTransparent, getContrastStatus, getDefaultColors } from './colorUtils';
|
|
33
|
+
|
|
34
|
+
// A custom type constraint that enforces at least one key is present
|
|
35
|
+
|
|
36
|
+
const ColorPicker = ({
|
|
37
|
+
tabs,
|
|
38
|
+
colorsInUse,
|
|
39
|
+
onCancel,
|
|
40
|
+
onSave
|
|
41
|
+
}) => {
|
|
42
|
+
const [currFgColor, setCurrFgColor] = useState(tabs.foreground?.color);
|
|
43
|
+
const [currBgColor, setCurrBgColor] = useState(isTransparent(tabs.background?.color) ? tabs.effectiveBgColor || '#ffffff' : tabs.background?.color);
|
|
44
|
+
const [currBorderColor, setCurrBorderColor] = useState(tabs.border?.color);
|
|
45
|
+
const [activeTab, setActiveTab] = useState(() => {
|
|
46
|
+
if (tabs.foreground) return 'foreground';
|
|
47
|
+
if (tabs.background) return 'background';
|
|
48
|
+
return 'border';
|
|
49
|
+
});
|
|
50
|
+
const [defaultColors] = useState(getDefaultColors());
|
|
51
|
+
const [customForeground, setCustomForeground] = useState(!!tabs.foreground?.color && tabs.foreground.color !== tabs.foreground.default);
|
|
52
|
+
const [customBackground, setCustomBackground] = useState(!isTransparent(tabs.background?.color) && tabs.background?.color !== tabs.background?.default);
|
|
53
|
+
const [customBorder, setCustomBorder] = useState(!isTransparent(tabs.border?.color) && tabs.border?.color !== tabs.border?.default);
|
|
54
|
+
const handleFgColorChange = useCallback(newColor => {
|
|
55
|
+
setCurrFgColor(newColor);
|
|
56
|
+
}, []);
|
|
57
|
+
const handleBgColorChange = useCallback(newColor => {
|
|
58
|
+
const c = tinycolor(newColor).toHexString();
|
|
59
|
+
setCurrBgColor(c);
|
|
60
|
+
}, []);
|
|
61
|
+
const handleBorderColorChange = useCallback(newColor => {
|
|
62
|
+
setCurrBorderColor(newColor);
|
|
63
|
+
}, []);
|
|
64
|
+
const handleTabChange = useCallback((_event, tabData) => {
|
|
65
|
+
setActiveTab(tabData.id);
|
|
66
|
+
}, []);
|
|
67
|
+
const handleChangePickAColor = useCallback((_e, value) => {
|
|
68
|
+
const isCustom = value === 'custom';
|
|
69
|
+
if (activeTab === 'foreground') {
|
|
70
|
+
setCustomForeground(isCustom);
|
|
71
|
+
if (!isCustom) {
|
|
72
|
+
setCurrFgColor(undefined);
|
|
73
|
+
}
|
|
74
|
+
} else if (activeTab === 'background') {
|
|
75
|
+
setCustomBackground(isCustom);
|
|
76
|
+
if (!isCustom) {
|
|
77
|
+
setCurrBgColor(undefined);
|
|
78
|
+
}
|
|
79
|
+
} else if (activeTab === 'border') {
|
|
80
|
+
setCustomBorder(isCustom);
|
|
81
|
+
if (!isCustom) {
|
|
82
|
+
setCurrBorderColor('#00000000');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, [activeTab]);
|
|
86
|
+
const handleCancel = useCallback(() => {
|
|
87
|
+
onCancel();
|
|
88
|
+
}, [onCancel]);
|
|
89
|
+
const handleSubmit = useCallback(() => {
|
|
90
|
+
setActiveTab(currFgColor ? 'foreground' : 'background');
|
|
91
|
+
const newcolors = {};
|
|
92
|
+
if (customForeground && currFgColor) {
|
|
93
|
+
const c = tinycolor(currFgColor).toHexString();
|
|
94
|
+
newcolors.fgcolor = c;
|
|
95
|
+
}
|
|
96
|
+
if (customBackground && currBgColor) {
|
|
97
|
+
const c = tinycolor(currBgColor).toHexString();
|
|
98
|
+
newcolors.bgcolor = c;
|
|
99
|
+
}
|
|
100
|
+
if (currBorderColor) {
|
|
101
|
+
newcolors.bordercolor = customBorder && !isTransparent(currBorderColor) ? currBorderColor : undefined;
|
|
102
|
+
if (newcolors.bordercolor) {
|
|
103
|
+
const c = tinycolor(newcolors.bordercolor).toHexString();
|
|
104
|
+
newcolors.bordercolor = c;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
onSave(newcolors);
|
|
108
|
+
}, [currBgColor, currBorderColor, currFgColor, customBackground, customBorder, customForeground, onSave]);
|
|
109
|
+
const getColorPresets = variant => {
|
|
110
|
+
const defaults = defaultColors;
|
|
111
|
+
if (tabs.background?.default) {
|
|
112
|
+
defaults[0] = tabs.background.default;
|
|
113
|
+
}
|
|
114
|
+
if (tabs.foreground?.default) {
|
|
115
|
+
defaults[1] = tabs.foreground.default;
|
|
116
|
+
}
|
|
117
|
+
// return only unique colors
|
|
118
|
+
return [...defaults, ...(colorsInUse?.[variant] || [])].filter((c, i, a) => a.indexOf(c) === i && !isTransparent(c));
|
|
119
|
+
};
|
|
120
|
+
const renderColorMixer = (variant, enabled) => {
|
|
121
|
+
let value = currBgColor;
|
|
122
|
+
let onSelectColor = handleBgColorChange;
|
|
123
|
+
if (variant === 'foreground') {
|
|
124
|
+
value = currFgColor;
|
|
125
|
+
onSelectColor = handleFgColorChange;
|
|
126
|
+
}
|
|
127
|
+
if (variant === 'border') {
|
|
128
|
+
value = currBorderColor;
|
|
129
|
+
onSelectColor = handleBorderColorChange;
|
|
130
|
+
}
|
|
131
|
+
if (isTransparent(value)) value = '#fff'; // or the ColorMixer will return a transparent color
|
|
132
|
+
|
|
133
|
+
return /*#__PURE__*/React.createElement(ColorMixer, {
|
|
134
|
+
"data-testid": "color-mixer",
|
|
135
|
+
disabled: !enabled,
|
|
136
|
+
value: value,
|
|
137
|
+
withAlpha: false,
|
|
138
|
+
onChange: onSelectColor,
|
|
139
|
+
rgbRedInputScreenReaderLabel: formatMessage('Input field for red'),
|
|
140
|
+
rgbGreenInputScreenReaderLabel: formatMessage('Input field for green'),
|
|
141
|
+
rgbBlueInputScreenReaderLabel: formatMessage('Input field for blue'),
|
|
142
|
+
rgbAlphaInputScreenReaderLabel: formatMessage('Input field for alpha'),
|
|
143
|
+
colorSliderNavigationExplanationScreenReaderLabel: formatMessage("You are on a color slider. To navigate the slider left or right, use the 'A' and 'D' buttons respectively"),
|
|
144
|
+
alphaSliderNavigationExplanationScreenReaderLabel: formatMessage("You are on an alpha slider. To navigate the slider left or right, use the 'A' and 'D' buttons respectively"),
|
|
145
|
+
colorPaletteNavigationExplanationScreenReaderLabel: formatMessage("You are on a color palette. To navigate on the palette up, left, down or right, use the 'W', 'A', 'S' and 'D' buttons respectively")
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
const renderColorPreset = (variant, enabled) => {
|
|
149
|
+
let currColor = currBgColor;
|
|
150
|
+
if (variant === 'foreground') currColor = currFgColor || defaultColors[1];
|
|
151
|
+
if (variant === 'border') currColor = currBorderColor || '#00000000';
|
|
152
|
+
let onSelectColor = handleBgColorChange;
|
|
153
|
+
if (variant === 'foreground') onSelectColor = handleFgColorChange;
|
|
154
|
+
if (variant === 'border') onSelectColor = handleBorderColorChange;
|
|
155
|
+
return /*#__PURE__*/React.createElement(ColorPreset, {
|
|
156
|
+
"data-testid": "color-preset",
|
|
157
|
+
disabled: !enabled,
|
|
158
|
+
label: formatMessage('Previously chosen colors'),
|
|
159
|
+
colors: getColorPresets(variant),
|
|
160
|
+
selected: currColor,
|
|
161
|
+
onSelect: onSelectColor
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// this will only get called if either tabs.foreground or tabs.border is defined
|
|
166
|
+
const getFirstColor = () => {
|
|
167
|
+
let firstColor, firstColorLabel;
|
|
168
|
+
if (activeTab === 'foreground' || activeTab === 'background' && !!tabs.foreground) {
|
|
169
|
+
firstColor = currFgColor || tabs.foreground?.default || defaultColors[0];
|
|
170
|
+
firstColorLabel = formatMessage('Color');
|
|
171
|
+
} else if (activeTab === 'border' || activeTab === 'background' && !!tabs.border) {
|
|
172
|
+
firstColor = currBorderColor || tabs.border?.default || defaultColors[0];
|
|
173
|
+
firstColorLabel = formatMessage('Border');
|
|
174
|
+
}
|
|
175
|
+
// @ts-expect-error
|
|
176
|
+
return {
|
|
177
|
+
firstColor,
|
|
178
|
+
firstColorLabel
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
const renderColorContrastSummary = () => {
|
|
182
|
+
const {
|
|
183
|
+
firstColor
|
|
184
|
+
} = getFirstColor();
|
|
185
|
+
const ok = getContrastStatus(firstColor, currBgColor || tabs.effectiveBgColor || '#fff');
|
|
186
|
+
return /*#__PURE__*/React.createElement(Flex, {
|
|
187
|
+
as: "div",
|
|
188
|
+
gap: "x-large"
|
|
189
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
190
|
+
weight: "bold"
|
|
191
|
+
}, formatMessage('Color Contrast')), /*#__PURE__*/React.createElement(Pill, {
|
|
192
|
+
color: ok ? 'success' : 'danger'
|
|
193
|
+
}, ok ? formatMessage('PASS') : formatMessage('FAIL')));
|
|
194
|
+
};
|
|
195
|
+
const renderColorContrast = () => {
|
|
196
|
+
if (!(tabs.background || tabs.effectiveBgColor)) return null;
|
|
197
|
+
if (!(tabs.foreground || tabs.border)) return null;
|
|
198
|
+
if (!currBgColor) return null;
|
|
199
|
+
const {
|
|
200
|
+
firstColor,
|
|
201
|
+
firstColorLabel
|
|
202
|
+
} = getFirstColor();
|
|
203
|
+
if (firstColor === null) return null;
|
|
204
|
+
return /*#__PURE__*/React.createElement(ToggleDetails, {
|
|
205
|
+
summary: renderColorContrastSummary(),
|
|
206
|
+
"data-testid": "color-contrast-summary"
|
|
207
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
208
|
+
as: "div",
|
|
209
|
+
margin: "small 0 0 0"
|
|
210
|
+
}, /*#__PURE__*/React.createElement(ColorContrast, {
|
|
211
|
+
"data-testid": "color-contrast",
|
|
212
|
+
firstColor: firstColor,
|
|
213
|
+
secondColor: currBgColor || tabs.effectiveBgColor || '#fff',
|
|
214
|
+
label: formatMessage('Color Contrast Ratio'),
|
|
215
|
+
successLabel: formatMessage('PASS'),
|
|
216
|
+
failureLabel: formatMessage('FAIL'),
|
|
217
|
+
normalTextLabel: formatMessage('Normal text'),
|
|
218
|
+
largeTextLabel: formatMessage('Large text'),
|
|
219
|
+
graphicsTextLabel: formatMessage('Graphics text'),
|
|
220
|
+
firstColorLabel: firstColorLabel,
|
|
221
|
+
secondColorLabel: formatMessage('Background')
|
|
222
|
+
})));
|
|
223
|
+
};
|
|
224
|
+
const renderTab = variant => {
|
|
225
|
+
let choosersEnabled = true;
|
|
226
|
+
if (variant === 'foreground') {
|
|
227
|
+
choosersEnabled = customForeground;
|
|
228
|
+
} else if (variant === 'background') {
|
|
229
|
+
choosersEnabled = customBackground;
|
|
230
|
+
} else if (variant === 'border') {
|
|
231
|
+
choosersEnabled = customBorder;
|
|
232
|
+
}
|
|
233
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
|
|
234
|
+
as: "div",
|
|
235
|
+
margin: "0 0 small 0"
|
|
236
|
+
}, /*#__PURE__*/React.createElement(RadioInputGroup, {
|
|
237
|
+
layout: "columns",
|
|
238
|
+
name: "pickcolor",
|
|
239
|
+
description: formatMessage('Pick a color'),
|
|
240
|
+
size: "small",
|
|
241
|
+
value: choosersEnabled ? 'custom' : 'none',
|
|
242
|
+
onChange: handleChangePickAColor
|
|
243
|
+
}, /*#__PURE__*/React.createElement(RadioInput, {
|
|
244
|
+
label: formatMessage('Default'),
|
|
245
|
+
value: "none"
|
|
246
|
+
}), /*#__PURE__*/React.createElement(RadioInput, {
|
|
247
|
+
label: formatMessage('Custom'),
|
|
248
|
+
value: "custom"
|
|
249
|
+
}))), renderColorMixer(variant, choosersEnabled), renderColorPreset(variant, choosersEnabled));
|
|
250
|
+
};
|
|
251
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
252
|
+
as: "div",
|
|
253
|
+
"data-testid": "color-picker"
|
|
254
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
255
|
+
as: "div",
|
|
256
|
+
padding: "small",
|
|
257
|
+
"data-mce-component": true
|
|
258
|
+
}, /*#__PURE__*/React.createElement(Tabs, {
|
|
259
|
+
onRequestTabChange: handleTabChange
|
|
260
|
+
}, !!tabs.foreground && /*#__PURE__*/React.createElement(Tabs.Panel, {
|
|
261
|
+
id: "foreground",
|
|
262
|
+
renderTitle: formatMessage('Color'),
|
|
263
|
+
isSelected: activeTab === 'foreground'
|
|
264
|
+
}, renderTab('foreground')), !!tabs.background && /*#__PURE__*/React.createElement(Tabs.Panel, {
|
|
265
|
+
id: "background",
|
|
266
|
+
renderTitle: formatMessage('Background'),
|
|
267
|
+
isSelected: activeTab === 'background'
|
|
268
|
+
}, renderTab('background')), !!tabs.border && /*#__PURE__*/React.createElement(Tabs.Panel, {
|
|
269
|
+
id: "border",
|
|
270
|
+
renderTitle: formatMessage('Border'),
|
|
271
|
+
isSelected: activeTab === 'border'
|
|
272
|
+
}, renderTab('border'))), renderColorContrast()), /*#__PURE__*/React.createElement(View, {
|
|
273
|
+
as: "div",
|
|
274
|
+
background: "secondary",
|
|
275
|
+
padding: "small",
|
|
276
|
+
textAlign: "end"
|
|
277
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
278
|
+
onClick: handleCancel
|
|
279
|
+
}, formatMessage('Cancel')), /*#__PURE__*/React.createElement(Button, {
|
|
280
|
+
onClick: handleSubmit,
|
|
281
|
+
margin: "0 0 0 small",
|
|
282
|
+
color: "primary"
|
|
283
|
+
}, formatMessage('Apply'))));
|
|
284
|
+
};
|
|
285
|
+
ColorPicker.propTypes = {
|
|
286
|
+
colorsInUse: _pt.shape({
|
|
287
|
+
foreground: _pt.arrayOf(_pt.string).isRequired,
|
|
288
|
+
background: _pt.arrayOf(_pt.string).isRequired,
|
|
289
|
+
border: _pt.arrayOf(_pt.string).isRequired
|
|
290
|
+
}),
|
|
291
|
+
onCancel: _pt.func.isRequired,
|
|
292
|
+
onSave: _pt.func.isRequired
|
|
293
|
+
};
|
|
294
|
+
export { ColorPicker };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import _pt from "prop-types";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2024 - present Instructure, Inc.
|
|
4
|
+
*
|
|
5
|
+
* This file is part of Canvas.
|
|
6
|
+
*
|
|
7
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
|
8
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
|
9
|
+
* Software Foundation, version 3 of the License.
|
|
10
|
+
*
|
|
11
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
12
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
13
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
14
|
+
* details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Affero General Public License along
|
|
17
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import React, { useCallback, useState } from 'react';
|
|
21
|
+
import { Popover } from '@instructure/ui-popover';
|
|
22
|
+
import { ColorPicker } from './ColorPicker';
|
|
23
|
+
import formatMessage from '../../../../format-message';
|
|
24
|
+
const ColorPopup = ({
|
|
25
|
+
tabs,
|
|
26
|
+
open,
|
|
27
|
+
positionTarget,
|
|
28
|
+
onCancel,
|
|
29
|
+
onChange
|
|
30
|
+
}) => {
|
|
31
|
+
const [recreateKey, setRecreateKey] = useState(0);
|
|
32
|
+
const handleHideContent = useCallback(() => {
|
|
33
|
+
onCancel();
|
|
34
|
+
setRecreateKey(Date.now());
|
|
35
|
+
}, [onCancel]);
|
|
36
|
+
const handleSubmit = useCallback(newcolors => {
|
|
37
|
+
onChange(newcolors);
|
|
38
|
+
}, [onChange]);
|
|
39
|
+
const handleKey = useCallback(e => {
|
|
40
|
+
if (e.key === 'Escape') {
|
|
41
|
+
onCancel();
|
|
42
|
+
}
|
|
43
|
+
}, [onCancel]);
|
|
44
|
+
return /*#__PURE__*/React.createElement(Popover, {
|
|
45
|
+
key: recreateKey,
|
|
46
|
+
isShowingContent: open,
|
|
47
|
+
onHideContent: handleHideContent,
|
|
48
|
+
on: "click",
|
|
49
|
+
positionTarget: positionTarget,
|
|
50
|
+
screenReaderLabel: formatMessage('Color popup'),
|
|
51
|
+
shouldContainFocus: true,
|
|
52
|
+
shouldReturnFocus: true,
|
|
53
|
+
shouldCloseOnDocumentClick: true
|
|
54
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
55
|
+
onKeyDown: handleKey
|
|
56
|
+
}, /*#__PURE__*/React.createElement(ColorPicker, {
|
|
57
|
+
tabs: tabs,
|
|
58
|
+
onCancel: onCancel,
|
|
59
|
+
onSave: handleSubmit
|
|
60
|
+
})));
|
|
61
|
+
};
|
|
62
|
+
ColorPopup.propTypes = {
|
|
63
|
+
open: _pt.bool.isRequired,
|
|
64
|
+
onCancel: _pt.func.isRequired,
|
|
65
|
+
onChange: _pt.func.isRequired
|
|
66
|
+
};
|
|
67
|
+
export { ColorPopup };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2024 - present Instructure, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Canvas.
|
|
5
|
+
*
|
|
6
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
+
* Software Foundation, version 3 of the License.
|
|
9
|
+
*
|
|
10
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
+
* details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import conversions, { contrast } from '@instructure/ui-color-utils';
|
|
20
|
+
import tinycolor from 'tinycolor2';
|
|
21
|
+
const isTransparent = color => {
|
|
22
|
+
if (!color) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
const c = tinycolor(color);
|
|
26
|
+
return c.isValid() && c.getAlpha() === 0;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// the following is copied from the INSTUI ColorContrast component
|
|
30
|
+
// a function to handle this will eventually be exported
|
|
31
|
+
// from @instructure/ui-color-utils
|
|
32
|
+
const INSTUIcalcBlendedColor = (c1, c2) => {
|
|
33
|
+
const alpha = 1 - (1 - c1.a) * (1 - c2.a);
|
|
34
|
+
return {
|
|
35
|
+
r: c2.r * c2.a / alpha + c1.r * c1.a * (1 - c2.a) / alpha,
|
|
36
|
+
g: c2.g * c2.a / alpha + c1.g * c1.a * (1 - c2.a) / alpha,
|
|
37
|
+
b: c2.b * c2.a / alpha + c1.b * c1.a * (1 - c2.a) / alpha,
|
|
38
|
+
a: 1
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const INSTUIcalcContrast = (firstColor, secondColor) => {
|
|
42
|
+
const c1RGBA = conversions.colorToRGB(firstColor);
|
|
43
|
+
const c2RGBA = conversions.colorToRGB(secondColor);
|
|
44
|
+
const c1OnWhite = INSTUIcalcBlendedColor({
|
|
45
|
+
r: 255,
|
|
46
|
+
g: 255,
|
|
47
|
+
b: 255,
|
|
48
|
+
a: 1
|
|
49
|
+
}, c1RGBA);
|
|
50
|
+
const c2OnC1OnWhite = INSTUIcalcBlendedColor(c1OnWhite, c2RGBA);
|
|
51
|
+
return contrast(conversions.colorToHex8(c1OnWhite), conversions.colorToHex8(c2OnC1OnWhite), 2);
|
|
52
|
+
};
|
|
53
|
+
const getContrastStatus = (color1, color2) => {
|
|
54
|
+
return INSTUIcalcContrast(color1, color2) >= 4.5;
|
|
55
|
+
};
|
|
56
|
+
const getDefaultColors = () => {
|
|
57
|
+
const fontcolor = window.getComputedStyle(document.documentElement).getPropertyValue('--ic-brand-font-color-dark') || '#000000';
|
|
58
|
+
return [fontcolor.toLowerCase(), '#ffffff'];
|
|
59
|
+
};
|
|
60
|
+
export { getContrastStatus, isTransparent, getDefaultColors };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2024 - present Instructure, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Canvas.
|
|
5
|
+
*
|
|
6
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
+
* Software Foundation, version 3 of the License.
|
|
9
|
+
*
|
|
10
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
+
* details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import tinymce from 'tinymce';
|
|
20
|
+
import formatMessage from '../../../format-message';
|
|
21
|
+
import clickCallback from './clickCallback';
|
|
22
|
+
tinymce.PluginManager.add('instructure_color', function (editor) {
|
|
23
|
+
editor.addCommand('launch_instructure_color', () => {
|
|
24
|
+
clickCallback(editor);
|
|
25
|
+
});
|
|
26
|
+
editor.ui.registry.addMenuItem('instructure_color', {
|
|
27
|
+
text: formatMessage('Color'),
|
|
28
|
+
icon: 'color',
|
|
29
|
+
onAction() {
|
|
30
|
+
editor.execCommand('launch_instructure_color');
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
editor.ui.registry.addButton('instructure_color', {
|
|
34
|
+
onAction() {
|
|
35
|
+
editor.execCommand('launch_instructure_color');
|
|
36
|
+
},
|
|
37
|
+
icon: 'color',
|
|
38
|
+
tooltip: formatMessage('Color')
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
* For LGPL see License.txt in the project root for license information.
|
|
5
5
|
* For commercial licenses see https://www.tiny.cloud/
|
|
6
6
|
*/
|
|
7
|
-
const isChildOfBody = (editor, node) => !!editor.$.contains(editor.getBody(), node);
|
|
8
7
|
|
|
8
|
+
const isChildOfBody = (editor, node) => !!editor.$.contains(editor.getBody(), node);
|
|
9
9
|
export const isTableCellNode = node => node && /^(TH|TD)$/.test(node.nodeName);
|
|
10
10
|
export const isListNode = editor => node => node && /^(OL|UL|DL)$/.test(node.nodeName) && isChildOfBody(editor, node);
|
|
11
11
|
export function listStyleForSelectionOfEditor(editor) {
|
|
12
12
|
const listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
|
|
13
|
-
|
|
14
13
|
if (listElm) {
|
|
15
14
|
return {
|
|
16
15
|
// This is not type safe, but the above getParent selector enforces that this will be
|
|
@@ -21,4 +20,12 @@ export function listStyleForSelectionOfEditor(editor) {
|
|
|
21
20
|
} else {
|
|
22
21
|
return undefined;
|
|
23
22
|
}
|
|
24
|
-
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Valid values of the "list-style-type" property.
|
|
27
|
+
*
|
|
28
|
+
* NOTE: Not all these types are supported by the RCE. For that, see `ListStyleTypeValue`
|
|
29
|
+
*
|
|
30
|
+
* From https://www.w3schools.com/cssref/pr_list-style-type.php
|
|
31
|
+
*/
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* You should have received a copy of the GNU Affero General Public License along
|
|
16
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
+
|
|
18
19
|
import registerAlignmentButton from './ui/alignment-button';
|
|
19
20
|
import registerIndentOutdentButton from './ui/indent-outdent-button';
|
|
20
21
|
import registerListButton from './ui/list-button';
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* You should have received a copy of the GNU Affero General Public License along
|
|
16
16
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
+
|
|
18
19
|
import formatMessage from '../../../../format-message';
|
|
19
20
|
import { toolbarIconHelperFor } from '../../../../util/tinymce-plugin-util';
|
|
20
21
|
export default function (editor) {
|
|
@@ -47,14 +48,12 @@ export default function (editor) {
|
|
|
47
48
|
}))),
|
|
48
49
|
onSetup: api => {
|
|
49
50
|
const iconHelper = toolbarIconHelperFor(editor, alignButtonLabel);
|
|
50
|
-
|
|
51
51
|
function nodeChangeHandler() {
|
|
52
52
|
const activeAlignment = alignToolbarButtons.find(b => editor.formatter.match(b.name));
|
|
53
53
|
const icon = activeAlignment ? activeAlignment.icon : 'align-left';
|
|
54
54
|
api.setActive(!!activeAlignment);
|
|
55
55
|
iconHelper.updateIcon(icon);
|
|
56
56
|
}
|
|
57
|
-
|
|
58
57
|
nodeChangeHandler();
|
|
59
58
|
editor.on('NodeChange', nodeChangeHandler);
|
|
60
59
|
return () => editor.off('NodeChange', nodeChangeHandler);
|