@instructure/canvas-rce 5.14.2 → 5.15.1
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 +10 -0
- package/DEVELOPMENT.md +1 -1
- package/es/bridge/Bridge.js +10 -17
- package/es/canvasFileBrowser/FileBrowser.js +10 -19
- package/es/common/FlashAlert.js +8 -11
- package/es/common/fileUrl.js +6 -10
- package/es/common/incremental-loading/LoadMoreButton.js +3 -4
- package/es/common/incremental-loading/LoadingStatus.js +4 -11
- package/es/common/indicate.js +1 -2
- package/es/defaultTinymceConfig.js +1 -1
- package/es/enhance-user-content/doc_previews.js +10 -10
- package/es/enhance-user-content/enhance_user_content.js +4 -7
- package/es/enhance-user-content/external_links.js +1 -1
- package/es/enhance-user-content/instructure_helper.js +11 -17
- package/es/enhance-user-content/mathml.js +15 -27
- package/es/enhance-user-content/media_comment_thumbnail.js +3 -10
- package/es/format-message.js +2 -2
- package/es/index.js +3 -5
- package/es/rce/AlertMessageArea.js +15 -16
- package/es/rce/KeyboardShortcutModal.js +2 -2
- package/es/rce/RCE.js +6 -8
- package/es/rce/RCEVariants.js +2 -4
- package/es/rce/RCEWrapper.js +397 -289
- package/es/rce/RCEWrapper.utils.js +131 -0
- package/es/rce/RCEWrapperProps.js +2 -3
- package/es/rce/RceHtmlEditor.js +12 -11
- package/es/rce/ResizeHandle.js +1 -2
- package/es/rce/ShowOnFocusButton/index.js +2 -2
- package/es/rce/StatusBar.js +5 -10
- package/es/rce/contentInsertion.js +1 -2
- package/es/rce/contentRendering.js +6 -5
- package/es/rce/editorLanguage.js +1 -1
- package/es/rce/indicatorRegion.js +1 -2
- package/es/rce/normalizeProps.js +4 -4
- package/es/rce/plugins/instructure_color/clickCallback.js +2 -4
- package/es/rce/plugins/instructure_color/components/ColorPicker.js +17 -22
- package/es/rce/plugins/instructure_color/components/ColorPopup.js +7 -8
- package/es/rce/plugins/instructure_condensed_buttons/ui/list-button.js +4 -10
- package/es/rce/plugins/instructure_condensed_buttons/ui/subscript-superscript-button.js +1 -1
- package/es/rce/plugins/instructure_documents/components/Link.js +1 -2
- package/es/rce/plugins/instructure_equation/EquationEditorModal/index.js +5 -8
- package/es/rce/plugins/instructure_equation/EquationEditorModal/latexTextareaUtil.js +3 -3
- package/es/rce/plugins/instructure_equation/EquationEditorModal/parseLatex.js +3 -3
- package/es/rce/plugins/instructure_equation/EquationEditorToolbar/buttons.js +2 -2
- package/es/rce/plugins/instructure_equation/EquationEditorToolbar/index.js +9 -11
- package/es/rce/plugins/instructure_equation/MathIcon/index.js +3 -4
- package/es/rce/plugins/instructure_equation/mathlive/index.js +167 -16
- package/es/rce/plugins/instructure_fullscreen/plugin.js +0 -2
- package/es/rce/plugins/instructure_icon_maker/clickCallback.js +3 -4
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ColorSection.js +46 -49
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/CreateIconMakerForm.js +9 -10
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Footer.js +10 -11
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Group.js +5 -6
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Header.js +7 -8
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Course.js +7 -9
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageOptions.js +19 -26
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ImageSection.js +8 -12
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/ModeSelect.js +6 -7
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/MultiColor/index.js +5 -6
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGList.js +6 -7
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SVGThumbnail.js +8 -10
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/index.js +5 -6
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/SingleColor/svg.js +32 -80
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/Upload.js +7 -8
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ImageSection/utils.js +4 -5
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/Preview.js +3 -4
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/ShapeSection.js +4 -5
- package/es/rce/plugins/instructure_icon_maker/components/CreateIconMakerForm/TextSection.js +4 -5
- package/es/rce/plugins/instructure_icon_maker/components/IconMakerTray.js +22 -29
- package/es/rce/plugins/instructure_icon_maker/registerEditToolbar.js +1 -1
- package/es/rce/plugins/instructure_icon_maker/svg/image.js +5 -7
- package/es/rce/plugins/instructure_icon_maker/svg/index.js +6 -9
- package/es/rce/plugins/instructure_icon_maker/svg/settings.js +17 -20
- package/es/rce/plugins/instructure_icon_maker/svg/shape.js +4 -5
- package/es/rce/plugins/instructure_icon_maker/svg/text.js +28 -32
- package/es/rce/plugins/instructure_icon_maker/svg/utils.js +2 -4
- package/es/rce/plugins/instructure_icon_maker/utils/IconMakerClose.js +2 -3
- package/es/rce/plugins/instructure_icon_maker/utils/iconValidation.js +1 -2
- package/es/rce/plugins/instructure_image/ImageEmbedOptions.js +3 -7
- package/es/rce/plugins/instructure_image/ImageList/Image.js +7 -8
- package/es/rce/plugins/instructure_image/ImageList/index.js +7 -8
- package/es/rce/plugins/instructure_image/ImageOptionsTray/TrayController.js +2 -4
- package/es/rce/plugins/instructure_image/ImageOptionsTray/index.js +3 -3
- package/es/rce/plugins/instructure_image/plugin.js +1 -2
- package/es/rce/plugins/instructure_links/components/AccordionSection.js +7 -8
- package/es/rce/plugins/instructure_links/components/Link.js +61 -65
- package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/LinkOptionsDialogController.js +1 -2
- package/es/rce/plugins/instructure_links/components/LinkOptionsDialog/index.js +2 -2
- package/es/rce/plugins/instructure_links/components/LinkOptionsTray/index.js +2 -2
- package/es/rce/plugins/instructure_links/components/LinkSet.js +28 -37
- package/es/rce/plugins/instructure_links/components/LinksPanel.js +21 -8
- package/es/rce/plugins/instructure_links/components/NoResults.js +6 -7
- package/es/rce/plugins/instructure_links/plugin.js +6 -9
- package/es/rce/plugins/instructure_media_embed/clickCallback.js +3 -4
- package/es/rce/plugins/instructure_media_embed/components/Embed.js +6 -7
- package/es/rce/plugins/instructure_paste/plugin.js +5 -7
- package/es/rce/plugins/instructure_rce_external_tools/ExternalToolsEnv.js +24 -33
- package/es/rce/plugins/instructure_rce_external_tools/RceToolWrapper.js +7 -38
- package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolDialog/ExternalToolDialog.js +30 -29
- package/es/rce/plugins/instructure_rce_external_tools/components/ExternalToolSelectionDialog/ExternalToolSelectionDialog.js +3 -4
- package/es/rce/plugins/instructure_rce_external_tools/dialog-helper.js +1 -2
- package/es/rce/plugins/instructure_rce_external_tools/jquery/jquery.dropdownList.js +3 -4
- package/es/rce/plugins/instructure_rce_external_tools/lti11-content-items/RceLti11ContentItem.js +17 -24
- package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/RceLti13ContentItem.js +2 -2
- package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/models/BaseLinkContentItem.js +4 -5
- package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/processEditorContentItems.js +8 -9
- package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/rceLti13ContentItemFromJson.js +0 -1
- package/es/rce/plugins/instructure_rce_external_tools/plugin.js +4 -4
- package/es/rce/plugins/instructure_rce_external_tools/util/externalToolsForToolbar.js +42 -0
- package/es/rce/plugins/instructure_record/AudioOptionsTray/TrayController.js +5 -10
- package/es/rce/plugins/instructure_record/AudioOptionsTray/index.js +12 -13
- package/es/rce/plugins/instructure_record/VideoOptionsTray/TrayController.js +8 -15
- package/es/rce/plugins/instructure_record/VideoOptionsTray/index.js +19 -20
- package/es/rce/plugins/instructure_record/clickCallback.js +26 -30
- package/es/rce/plugins/instructure_search_and_replace/clickCallback.js +2 -3
- package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTray.js +14 -16
- package/es/rce/plugins/instructure_search_and_replace/components/FindReplaceTrayController.js +9 -12
- package/es/rce/plugins/instructure_search_and_replace/plugin.js +1 -2
- package/es/rce/plugins/instructure_wordcount/clickCallback.js +3 -4
- package/es/rce/plugins/instructure_wordcount/components/WordCountModal.js +26 -33
- package/es/rce/plugins/instructure_wordcount/utils/countContent.js +3 -3
- package/es/rce/plugins/instructure_wordcount/utils/tableContent.js +5 -8
- package/es/rce/plugins/shared/CanvasContentTray.js +9 -16
- package/es/rce/plugins/shared/ColorInput.js +22 -25
- package/es/rce/plugins/shared/ConditionalTooltip.js +5 -6
- package/es/rce/plugins/shared/ContentSelection.js +12 -20
- package/es/rce/plugins/shared/DimensionUtils.js +2 -4
- package/es/rce/plugins/shared/EventUtils.js +1 -1
- package/es/rce/plugins/shared/FixedContentTray.js +13 -14
- package/es/rce/plugins/shared/ImageCropper/DirectionRegion.js +3 -4
- package/es/rce/plugins/shared/ImageCropper/Modal.js +12 -13
- package/es/rce/plugins/shared/ImageCropper/Preview.js +11 -13
- package/es/rce/plugins/shared/ImageCropper/controls/CustomNumberInput.js +8 -9
- package/es/rce/plugins/shared/ImageCropper/controls/ResetControls.js +3 -4
- package/es/rce/plugins/shared/ImageCropper/controls/RotationControls.js +4 -5
- package/es/rce/plugins/shared/ImageCropper/controls/ShapeControls.js +7 -11
- package/es/rce/plugins/shared/ImageCropper/controls/ZoomControls.js +4 -5
- package/es/rce/plugins/shared/ImageCropper/controls/index.js +4 -5
- package/es/rce/plugins/shared/ImageCropper/controls/useDebouncedNumericValue.js +13 -15
- package/es/rce/plugins/shared/ImageCropper/imageCropUtils.js +18 -21
- package/es/rce/plugins/shared/ImageCropper/svg/shape.js +4 -5
- package/es/rce/plugins/shared/ImageCropper/svg/utils.js +2 -4
- package/es/rce/plugins/shared/ImageCropper/useKeyMouseEvents.js +1 -4
- package/es/rce/plugins/shared/ImageOptionsForm.js +17 -18
- package/es/rce/plugins/shared/LinkDisplay.js +8 -9
- package/es/rce/plugins/shared/PreviewIcon.js +8 -9
- package/es/rce/plugins/shared/RceFileBrowser.js +2 -3
- package/es/rce/plugins/shared/StoreContext.js +8 -10
- package/es/rce/plugins/shared/StudioLtiSupportUtils.js +5 -6
- package/es/rce/plugins/shared/Upload/CanvasContentPanel.js +6 -7
- package/es/rce/plugins/shared/Upload/CategoryProcessor.js +1 -2
- package/es/rce/plugins/shared/Upload/ComputerPanel.js +11 -14
- package/es/rce/plugins/shared/Upload/PanelFilter.js +7 -8
- package/es/rce/plugins/shared/Upload/UploadFile.js +19 -22
- package/es/rce/plugins/shared/Upload/UploadFileModal.js +28 -34
- package/es/rce/plugins/shared/Upload/UrlPanel.js +4 -5
- package/es/rce/plugins/shared/Upload/UsageRightsSelectBox.js +18 -24
- package/es/rce/plugins/shared/Upload/doFileUpload.js +6 -7
- package/es/rce/plugins/shared/ai_tools/AIResponseModal.js +7 -8
- package/es/rce/plugins/shared/ai_tools/AIToolsTray.js +14 -17
- package/es/rce/plugins/shared/ai_tools/aiicons.js +2 -2
- package/es/rce/plugins/shared/canvasContentUtils.js +1 -2
- package/es/rce/plugins/shared/compressionUtils.js +17 -20
- package/es/rce/plugins/shared/do-fetch-api-effect/doFetchApi.js +12 -15
- package/es/rce/plugins/shared/do-fetch-api-effect/get-cookie.js +1 -1
- package/es/rce/plugins/shared/fileTypeUtils.js +3 -6
- package/es/rce/plugins/shared/round.js +1 -2
- package/es/rce/plugins/shared/trayUtils.js +3 -0
- package/es/rce/plugins/shared/useDataUrl.js +4 -5
- package/es/rce/plugins/tinymce-a11y-checker/components/ColorField.js +2 -2
- package/es/rce/plugins/tinymce-a11y-checker/components/checker.js +8 -10
- package/es/rce/plugins/tinymce-a11y-checker/node-checker.js +1 -3
- package/es/rce/plugins/tinymce-a11y-checker/plugin.js +14 -17
- package/es/rce/plugins/tinymce-a11y-checker/rules/headings-start-at-h2.js +1 -2
- package/es/rce/plugins/tinymce-a11y-checker/rules/large-text-contrast.js +1 -2
- package/es/rce/plugins/tinymce-a11y-checker/rules/small-text-contrast.js +1 -2
- package/es/rce/plugins/tinymce-a11y-checker/utils/dom.js +2 -4
- package/es/rce/plugins/tinymce-a11y-checker/utils/indicate.js +2 -3
- package/es/rce/plugins/tinymce-a11y-checker/utils/rgb-hex.js +1 -4
- package/es/rce/root.js +9 -9
- package/es/rce/tinyRCE.js +1 -0
- package/es/rce/transformContent.js +1 -1
- package/es/rcs/api.js +39 -55
- package/es/rcs/buildError.js +3 -3
- package/es/rcs/fake.js +5 -7
- package/es/sidebar/actions/documents.js +10 -12
- package/es/sidebar/actions/files.js +18 -22
- package/es/sidebar/actions/filter.js +4 -5
- package/es/sidebar/actions/images.js +20 -26
- package/es/sidebar/actions/media.js +15 -18
- package/es/sidebar/actions/session.js +1 -2
- package/es/sidebar/actions/upload.js +26 -37
- package/es/sidebar/containers/sidebarHandlers.js +6 -12
- package/es/sidebar/dragHtml.js +6 -2
- package/es/sidebar/reducers/all_files.js +1 -3
- package/es/sidebar/reducers/collection.js +1 -3
- package/es/sidebar/reducers/collections.js +1 -3
- package/es/sidebar/reducers/documents.js +1 -3
- package/es/sidebar/reducers/files.js +1 -3
- package/es/sidebar/reducers/filter.js +7 -15
- package/es/sidebar/reducers/flickr.js +1 -3
- package/es/sidebar/reducers/folder.js +1 -3
- package/es/sidebar/reducers/folders.js +1 -3
- package/es/sidebar/reducers/images.js +1 -3
- package/es/sidebar/reducers/media.js +1 -3
- package/es/sidebar/reducers/newPageLinkExpanded.js +1 -3
- package/es/sidebar/reducers/noop.js +1 -2
- package/es/sidebar/reducers/rootFolderId.js +1 -3
- package/es/sidebar/reducers/session.js +1 -3
- package/es/sidebar/reducers/ui.js +3 -9
- package/es/sidebar/reducers/upload.js +8 -24
- package/es/sidebar/store/initialState.js +1 -2
- package/es/translations/locales/ar.js +6 -0
- package/es/translations/locales/ca.js +6 -0
- package/es/translations/locales/cy.js +6 -0
- package/es/translations/locales/da-x-k12.js +6 -0
- package/es/translations/locales/da.js +6 -0
- package/es/translations/locales/de.js +6 -0
- package/es/translations/locales/en-AU-x-unimelb.js +6 -0
- package/es/translations/locales/en-GB-x-ukhe.js +6 -0
- package/es/translations/locales/en_AU.js +6 -0
- package/es/translations/locales/en_CA.js +6 -0
- package/es/translations/locales/en_CY.js +6 -0
- package/es/translations/locales/en_GB.js +6 -0
- package/es/translations/locales/es.js +6 -0
- package/es/translations/locales/es_ES.js +6 -0
- package/es/translations/locales/fi.js +6 -0
- package/es/translations/locales/fr.js +6 -0
- package/es/translations/locales/fr_CA.js +6 -0
- package/es/translations/locales/hi.js +6 -0
- package/es/translations/locales/ht.js +6 -0
- package/es/translations/locales/id.js +6 -0
- package/es/translations/locales/is.js +6 -0
- package/es/translations/locales/it.js +6 -0
- package/es/translations/locales/ja.js +6 -0
- package/es/translations/locales/mi.js +6 -0
- package/es/translations/locales/ms.js +6 -0
- package/es/translations/locales/nb-x-k12.js +6 -0
- package/es/translations/locales/nb.js +6 -0
- package/es/translations/locales/nl.js +6 -0
- package/es/translations/locales/pl.js +6 -0
- package/es/translations/locales/pt.js +6 -0
- package/es/translations/locales/pt_BR.js +6 -0
- package/es/translations/locales/ru.js +6 -0
- package/es/translations/locales/sl.js +6 -0
- package/es/translations/locales/sv-x-k12.js +6 -0
- package/es/translations/locales/sv.js +6 -0
- package/es/translations/locales/th.js +6 -0
- package/es/translations/locales/vi.js +6 -0
- package/es/translations/locales/zh-Hans.js +6 -0
- package/es/translations/locales/zh-Hant.js +6 -0
- package/es/translations/locales/zh.js +6 -0
- package/es/translations/locales/zh_HK.js +6 -0
- package/es/util/elem-util.js +1 -1
- package/es/util/file-url-util.js +1 -1
- package/es/util/fullscreenHelpers.js +6 -9
- package/es/util/loadingPlaceholder.js +2 -3
- package/es/util/simpleCache.js +1 -2
- package/es/util/url-util.js +5 -5
- package/eslint.config.js +15 -4
- package/locales/en.json +190 -10
- package/package.json +56 -55
- package/scripts/installTranslations.js +7 -8
- package/tsconfig.json +1 -1
- package/types/format-message-generate-id.d.ts +22 -0
- package/types/js-beautify.d.ts +21 -0
|
@@ -20,41 +20,14 @@ import { openToolDialogFor } from './dialog-helper';
|
|
|
20
20
|
import { simpleCache } from '../../../util/simpleCache';
|
|
21
21
|
import { instUiIconsArray } from '../../../util/instui-icon-helper';
|
|
22
22
|
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
23
24
|
// @ts-ignore
|
|
24
25
|
import { IconLtiSolid } from '@instructure/ui-icons/es/svg';
|
|
25
|
-
export function externalToolsForToolbar(tools) {
|
|
26
|
-
// Limit of not on_by_default but favorited tools is 2
|
|
27
|
-
const favorited = tools.filter(it => it.favorite && !it.on_by_default).slice(0, 2) || [];
|
|
28
|
-
const onByDefault = tools.filter(it => it.on_by_default && it.favorite) || [];
|
|
29
|
-
const set = new Map();
|
|
30
|
-
|
|
31
|
-
// Remove possible overlaps between favorited and onByDefault, otherwise
|
|
32
|
-
// we'd have duplicate buttons in the toolbar.
|
|
33
|
-
for (const toolInfo of favorited.concat(onByDefault)) {
|
|
34
|
-
set.set(toolInfo.id, toolInfo);
|
|
35
|
-
}
|
|
36
|
-
return Array.from(set.values()).sort((a, b) => {
|
|
37
|
-
if (a.on_by_default && !b.on_by_default) {
|
|
38
|
-
return -1;
|
|
39
|
-
} else if (!a.on_by_default && b.on_by_default) {
|
|
40
|
-
return 1;
|
|
41
|
-
} else {
|
|
42
|
-
// This *should* always be a string, but there might be cases where it isn't,
|
|
43
|
-
// especially when this method is used outside of TypeScript files.
|
|
44
|
-
return a.id.toString().localeCompare(b.id.toString(), undefined, {
|
|
45
|
-
numeric: true
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
26
|
/**
|
|
52
27
|
* Helper class for the connection between an external tool registration and a particular TinyMCE instance.
|
|
53
28
|
*/
|
|
54
29
|
export class RceToolWrapper {
|
|
55
|
-
static forEditorEnv(env) {
|
|
56
|
-
let toolConfigs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : env.availableRceLtiTools;
|
|
57
|
-
let mruIds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : loadMruToolIds();
|
|
30
|
+
static forEditorEnv(env, toolConfigs = env.availableRceLtiTools, mruIds = loadMruToolIds()) {
|
|
58
31
|
return toolConfigs.map(it => new RceToolWrapper(env, it, mruIds));
|
|
59
32
|
}
|
|
60
33
|
get editor() {
|
|
@@ -83,8 +56,7 @@ export class RceToolWrapper {
|
|
|
83
56
|
return (_this$toolInfo$favori = this.toolInfo.favorite) !== null && _this$toolInfo$favori !== void 0 ? _this$toolInfo$favori : false;
|
|
84
57
|
}
|
|
85
58
|
get image() {
|
|
86
|
-
|
|
87
|
-
return (_parseIconValueFor = parseIconValueFor(this.toolInfo)) === null || _parseIconValueFor === void 0 ? void 0 : _parseIconValueFor.iconUrl;
|
|
59
|
+
return parseIconValueFor(this.toolInfo)?.iconUrl;
|
|
88
60
|
}
|
|
89
61
|
get width() {
|
|
90
62
|
return this.toolInfo.width;
|
|
@@ -127,7 +99,7 @@ export function parseIconValueFor(toolInfo) {
|
|
|
127
99
|
|
|
128
100
|
// URL embedded in canvas_icon_class, which happens in some cases (see MAT-1354)
|
|
129
101
|
if (typeof canvasIconClass === 'object') {
|
|
130
|
-
const iconUrl = canvasIconClass
|
|
102
|
+
const iconUrl = canvasIconClass?.icon_url;
|
|
131
103
|
if (typeof iconUrl === 'string' && iconUrl !== '') {
|
|
132
104
|
result.iconUrl = iconUrl;
|
|
133
105
|
}
|
|
@@ -191,10 +163,9 @@ const svgImageCache = simpleCache(imageUrl => {
|
|
|
191
163
|
export function loadMruToolIds() {
|
|
192
164
|
let list;
|
|
193
165
|
try {
|
|
194
|
-
var _window$localStorage
|
|
195
|
-
list = JSON.parse((_window$localStorage$ =
|
|
166
|
+
var _window$localStorage$;
|
|
167
|
+
list = JSON.parse((_window$localStorage$ = window.localStorage?.getItem('ltimru')) !== null && _window$localStorage$ !== void 0 ? _window$localStorage$ : '[]');
|
|
196
168
|
} catch (ex) {
|
|
197
|
-
// eslint-disable-next-line no-console
|
|
198
169
|
console.warn('Found bad LTI MRU data', ex.message);
|
|
199
170
|
}
|
|
200
171
|
return Array.isArray(list) ? list.filter(it => it != null).map(it => String(it)) : [];
|
|
@@ -205,10 +176,8 @@ export function loadMruToolIds() {
|
|
|
205
176
|
*/
|
|
206
177
|
export function storeMruToolIds(toolIds) {
|
|
207
178
|
try {
|
|
208
|
-
|
|
209
|
-
(_window$localStorage2 = window.localStorage) === null || _window$localStorage2 === void 0 ? void 0 : _window$localStorage2.setItem('ltimru', JSON.stringify(toolIds));
|
|
179
|
+
window.localStorage?.setItem('ltimru', JSON.stringify(toolIds));
|
|
210
180
|
} catch (ex) {
|
|
211
|
-
// eslint-disable-next-line no-console
|
|
212
181
|
console.warn('Cannot save LTI MRU list', ex.message);
|
|
213
182
|
}
|
|
214
183
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import _pt from "prop-types";
|
|
2
|
-
// @ts-nocheck
|
|
3
2
|
// TODO: we get complaints about <Overlay> because it can be either a Modal or a Tray
|
|
4
3
|
// and they have different props. I don't have time to fix this the right way now.
|
|
5
4
|
/*
|
|
@@ -29,14 +28,14 @@ import ToolLaunchIframe from '../util/ToolLaunchIframe';
|
|
|
29
28
|
import processEditorContentItems from '../../lti13-content-items/processEditorContentItems';
|
|
30
29
|
import { RceLti11ContentItem } from '../../lti11-content-items/RceLti11ContentItem';
|
|
31
30
|
import formatMessage from '../../../../../format-message';
|
|
32
|
-
import {
|
|
31
|
+
import { instuiPopupMountNodeFn } from '../../../../../util/fullscreenHelpers';
|
|
33
32
|
import { ExternalToolDialogTray } from './ExternalToolDialogTray';
|
|
34
33
|
import { ExternalToolDialogModal } from './ExternalToolDialogModal';
|
|
35
34
|
import { showFlashAlert } from '../../../../../common/FlashAlert';
|
|
36
35
|
import { parseUrlOrNull } from '../../../../../util/url-util';
|
|
37
36
|
export default class ExternalToolDialog extends React.Component {
|
|
38
|
-
constructor() {
|
|
39
|
-
super(...
|
|
37
|
+
constructor(...args) {
|
|
38
|
+
super(...args);
|
|
40
39
|
this.state = {
|
|
41
40
|
open: false,
|
|
42
41
|
button: null,
|
|
@@ -61,17 +60,19 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
61
60
|
}
|
|
62
61
|
const contentItems = data.contentItems;
|
|
63
62
|
if (contentItems.length === 1 && contentItems[0]['@type'] === 'lti_replace') {
|
|
64
|
-
var _env$rceWrapper;
|
|
65
63
|
const code = contentItems[0].text;
|
|
66
|
-
|
|
64
|
+
|
|
65
|
+
// @ts-expect-error
|
|
66
|
+
env.rceWrapper?.setCode(code);
|
|
67
67
|
} else {
|
|
68
68
|
contentItems.forEach(contentData => {
|
|
69
|
-
var _env$rceWrapper2;
|
|
70
69
|
const code = RceLti11ContentItem.fromJSON({
|
|
71
70
|
...contentData,
|
|
72
71
|
class: 'lti-embed'
|
|
73
72
|
}, env).codePayload;
|
|
74
|
-
|
|
73
|
+
|
|
74
|
+
// @ts-expect-error
|
|
75
|
+
env.rceWrapper?.insertCode(code);
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
this.close();
|
|
@@ -79,9 +80,9 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
79
80
|
this.handlePostedMessage = ev => {
|
|
80
81
|
if (ev.origin === this.resourceSelectionOrigin) {
|
|
81
82
|
const data = ev.data;
|
|
82
|
-
if (
|
|
83
|
+
if (data?.subject === 'LtiDeepLinkingResponse') {
|
|
83
84
|
processEditorContentItems(ev, this.props.env, this);
|
|
84
|
-
} else if (
|
|
85
|
+
} else if (data?.subject === 'externalContentReady') {
|
|
85
86
|
// 'externalContentReady' is EXTERNAL_CONTENT_READY in
|
|
86
87
|
// ui/shared/external-tools/externalContentEvents.ts
|
|
87
88
|
// where events are also described/used
|
|
@@ -91,21 +92,18 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
91
92
|
};
|
|
92
93
|
this.handleClose = () => {
|
|
93
94
|
const msg = formatMessage('Are you sure you want to cancel? Changes you made may not be saved.');
|
|
94
|
-
// eslint-disable-next-line no-alert
|
|
95
95
|
if (window.confirm(msg)) {
|
|
96
96
|
this.close();
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
this.handleOpen = () => {
|
|
100
|
-
|
|
101
|
-
if (this.state.open) (_this$formRef$current = this.formRef.current) === null || _this$formRef$current === void 0 ? void 0 : _this$formRef$current.submit();
|
|
100
|
+
if (this.state.open) this.formRef.current?.submit();
|
|
102
101
|
};
|
|
103
102
|
this.handleRemove = () => {
|
|
104
|
-
var _this$props$env$edito;
|
|
105
103
|
this.setState({
|
|
106
104
|
button: null
|
|
107
105
|
});
|
|
108
|
-
|
|
106
|
+
this.props.env.editor?.focus();
|
|
109
107
|
|
|
110
108
|
// force tinyMCE to redraw sticky toolbar otherwise it never goes away
|
|
111
109
|
window.dispatchEvent(new Event('resize'));
|
|
@@ -117,11 +115,10 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
117
115
|
infoAlert: null
|
|
118
116
|
});
|
|
119
117
|
this.calcIFrameHeight = () => {
|
|
120
|
-
|
|
121
|
-
if ((_this$state$button = this.state.button) !== null && _this$state$button !== void 0 && _this$state$button.use_tray) {
|
|
118
|
+
if (this.state.button?.use_tray) {
|
|
122
119
|
return '100%';
|
|
123
120
|
}
|
|
124
|
-
const toolDefinedHeight =
|
|
121
|
+
const toolDefinedHeight = this.state.button?.height;
|
|
125
122
|
const iFrameHeight = toolDefinedHeight !== null && toolDefinedHeight !== void 0 ? toolDefinedHeight : Math.max(Math.min(window.innerHeight - 100, 550), 100);
|
|
126
123
|
const modalMaxHeight = '95';
|
|
127
124
|
const modalHeaderHeightWithPadding = '5.5rem';
|
|
@@ -140,8 +137,8 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
140
137
|
resourceSelectionUrlOverride
|
|
141
138
|
} = this.props;
|
|
142
139
|
let urlStr = replaceTags(resourceSelectionUrlOverride, 'id', button.id);
|
|
143
|
-
const selection = (_env$editorSelection = env
|
|
144
|
-
const contents = (_env$editorContent = env
|
|
140
|
+
const selection = (_env$editorSelection = env?.editorSelection) !== null && _env$editorSelection !== void 0 ? _env$editorSelection : '';
|
|
141
|
+
const contents = (_env$editorContent = env?.editorContent) !== null && _env$editorContent !== void 0 ? _env$editorContent : '';
|
|
145
142
|
if (urlStr == null) {
|
|
146
143
|
// if we don't have a url on the page, build one using the current context.
|
|
147
144
|
// url should look like: /courses/2/external_tools/15/resource_selection?editor=1
|
|
@@ -193,11 +190,11 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
193
190
|
return this.props.env.canvasOrigin;
|
|
194
191
|
}
|
|
195
192
|
render() {
|
|
196
|
-
var _state$button
|
|
193
|
+
var _state$button$title, _state$button$width;
|
|
197
194
|
const state = this.state;
|
|
198
195
|
const props = this.props;
|
|
199
196
|
const label = formatMessage('Embed content from External Tool');
|
|
200
|
-
const Overlay =
|
|
197
|
+
const Overlay = state.button?.use_tray ? ExternalToolDialogTray : ExternalToolDialogModal;
|
|
201
198
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("form", {
|
|
202
199
|
ref: this.formRef,
|
|
203
200
|
method: "POST",
|
|
@@ -220,24 +217,28 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
220
217
|
value: state.form.contents
|
|
221
218
|
}), /*#__PURE__*/React.createElement("input", {
|
|
222
219
|
type: "hidden",
|
|
223
|
-
name: "com_instructure_course_canvas_resource_type"
|
|
224
|
-
|
|
220
|
+
name: "com_instructure_course_canvas_resource_type"
|
|
221
|
+
// @ts-expect-error
|
|
222
|
+
,
|
|
223
|
+
value: props.env.rceWrapper?.getResourceIdentifiers().resourceType
|
|
225
224
|
}), /*#__PURE__*/React.createElement("input", {
|
|
226
225
|
type: "hidden",
|
|
227
|
-
name: "com_instructure_course_canvas_resource_id"
|
|
228
|
-
|
|
226
|
+
name: "com_instructure_course_canvas_resource_id"
|
|
227
|
+
// @ts-expect-error
|
|
228
|
+
,
|
|
229
|
+
value: props.env.rceWrapper?.getResourceIdentifiers().resourceId
|
|
229
230
|
}), state.form.parent_frame_context != null && /*#__PURE__*/React.createElement("input", {
|
|
230
231
|
type: "hidden",
|
|
231
232
|
name: "parent_frame_context",
|
|
232
233
|
value: state.form.parent_frame_context
|
|
233
234
|
})), /*#__PURE__*/React.createElement(Overlay, {
|
|
234
235
|
open: state.open,
|
|
235
|
-
mountNode:
|
|
236
|
+
mountNode: instuiPopupMountNodeFn(),
|
|
236
237
|
label: label,
|
|
237
238
|
onOpen: this.handleOpen,
|
|
238
239
|
onClose: this.handleRemove,
|
|
239
240
|
onCloseButton: this.handleClose,
|
|
240
|
-
name: (_state$button$title =
|
|
241
|
+
name: (_state$button$title = state.button?.title) !== null && _state$button$title !== void 0 ? _state$button$title : ' '
|
|
241
242
|
}, /*#__PURE__*/React.createElement("div", {
|
|
242
243
|
ref: this.beforeInfoAlertRef,
|
|
243
244
|
tabIndex: 0 // eslint-disable-line jsx-a11y/no-noninteractive-tabindex
|
|
@@ -262,7 +263,7 @@ export default class ExternalToolDialog extends React.Component {
|
|
|
262
263
|
id: "external_tool_button_frame",
|
|
263
264
|
style: {
|
|
264
265
|
height: this.calcIFrameHeight(),
|
|
265
|
-
width:
|
|
266
|
+
width: state.button?.use_tray ? '100%' : (_state$button$width = state.button?.width) !== null && _state$button$width !== void 0 ? _state$button$width : 800,
|
|
266
267
|
border: '0',
|
|
267
268
|
display: 'block',
|
|
268
269
|
visibility: state.iframeLoaded ? 'visible' : 'hidden'
|
|
@@ -30,7 +30,7 @@ import { IconSearchLine } from '@instructure/ui-icons';
|
|
|
30
30
|
import { Alert } from '@instructure/ui-alerts';
|
|
31
31
|
import formatMessage from '../../../../../format-message';
|
|
32
32
|
import ExternalToolSelectionItem from './ExternalToolSelectionItem';
|
|
33
|
-
import {
|
|
33
|
+
import { instuiPopupMountNodeFn } from '../../../../../util/fullscreenHelpers';
|
|
34
34
|
// TODO: we really need a way for the client to pass this to the RCE
|
|
35
35
|
const getLiveRegion = () => document.getElementById('flash_screenreader_holder');
|
|
36
36
|
|
|
@@ -54,8 +54,7 @@ export function ExternalToolSelectionDialog(props) {
|
|
|
54
54
|
const [filterTerm, setFilterTerm] = useState('');
|
|
55
55
|
const [filteredResults, setFilteredResults] = useState(props.ltiButtons);
|
|
56
56
|
const handleFilterChange = e => {
|
|
57
|
-
|
|
58
|
-
setFilterTerm((_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.value);
|
|
57
|
+
setFilterTerm(e.target?.value);
|
|
59
58
|
setFilteredResults(filterItemsByTitleSubstring(e.target.value, props.ltiButtons));
|
|
60
59
|
};
|
|
61
60
|
const filterEmpty = filteredResults.length <= 0;
|
|
@@ -67,7 +66,7 @@ export function ExternalToolSelectionDialog(props) {
|
|
|
67
66
|
mediumMaxWidth: '42rem'
|
|
68
67
|
},
|
|
69
68
|
label: formatMessage('Apps'),
|
|
70
|
-
mountNode:
|
|
69
|
+
mountNode: instuiPopupMountNodeFn(),
|
|
71
70
|
onDismiss: props.onDismiss,
|
|
72
71
|
open: true,
|
|
73
72
|
shouldCloseOnDocumentClick: false
|
|
@@ -38,7 +38,6 @@ export function openToolDialogFor(toolHelper) {
|
|
|
38
38
|
iframeAllowances: env.ltiIframeAllowPolicy,
|
|
39
39
|
resourceSelectionUrlOverride: env.resourceSelectionUrlOverride
|
|
40
40
|
}), ensureToolDialogContainerElem(), () => {
|
|
41
|
-
|
|
42
|
-
(_dialogRef$current = dialogRef.current) === null || _dialogRef$current === void 0 ? void 0 : _dialogRef$current.open(toolHelper);
|
|
41
|
+
dialogRef.current?.open(toolHelper);
|
|
43
42
|
});
|
|
44
43
|
}
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
// @ts-expect-error
|
|
42
42
|
function (options) {
|
|
43
43
|
if (this.length) {
|
|
44
|
-
var _this$offset, _this$outerHeight, _$div$offset$left, _$div$
|
|
44
|
+
var _this$offset, _this$outerHeight, _$div$offset$left, _$div$width, _$$width;
|
|
45
45
|
let $div = $('#instructure_dropdown_list');
|
|
46
46
|
if (options === 'hide' || options === 'remove' || $div.data('current_dropdown_initiator') === this[0]) {
|
|
47
47
|
$div.remove().data('current_dropdown_initiator', null);
|
|
@@ -70,9 +70,8 @@
|
|
|
70
70
|
if ($current.length && $current.prev().length) {
|
|
71
71
|
$current.removeClass('ui-state-hover ui-state-active').addClass('minimal').prev().addClass('ui-state-hover').removeClass('minimal').find('span').focus();
|
|
72
72
|
} else {
|
|
73
|
-
var _$item;
|
|
74
73
|
;
|
|
75
|
-
|
|
74
|
+
window.$item?.focus();
|
|
76
75
|
}
|
|
77
76
|
return false;
|
|
78
77
|
} else if (event.keyCode === 40) {
|
|
@@ -147,7 +146,7 @@
|
|
|
147
146
|
}).hide().show();
|
|
148
147
|
|
|
149
148
|
// this is a fix so that if the dropdown ends up being off the page then move it back in so that it is on the page.
|
|
150
|
-
if (((_$div$offset$left =
|
|
149
|
+
if (((_$div$offset$left = $div.offset()?.left) !== null && _$div$offset$left !== void 0 ? _$div$offset$left : 0) + ((_$div$width = $div.width()) !== null && _$div$width !== void 0 ? _$div$width : 0) > ((_$$width = $(window).width()) !== null && _$$width !== void 0 ? _$$width : 0)) {
|
|
151
150
|
$div.css({
|
|
152
151
|
left: '',
|
|
153
152
|
right: 0
|
package/es/rce/plugins/instructure_rce_external_tools/lti11-content-items/RceLti11ContentItem.js
CHANGED
|
@@ -30,12 +30,10 @@ function maybeAddPx(value) {
|
|
|
30
30
|
return strVal;
|
|
31
31
|
}
|
|
32
32
|
export class RceLti11ContentItem {
|
|
33
|
-
static fromJSON(contentItem) {
|
|
34
|
-
let env = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : externalToolsEnvFor(tinymce.activeEditor);
|
|
33
|
+
static fromJSON(contentItem, env = externalToolsEnvFor(tinymce.activeEditor)) {
|
|
35
34
|
return new RceLti11ContentItem(contentItem, env);
|
|
36
35
|
}
|
|
37
|
-
constructor(contentItem) {
|
|
38
|
-
let env = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : externalToolsEnvFor(tinymce.activeEditor);
|
|
36
|
+
constructor(contentItem, env = externalToolsEnvFor(tinymce.activeEditor)) {
|
|
39
37
|
this.contentItem = void 0;
|
|
40
38
|
this.env = void 0;
|
|
41
39
|
this.contentItem = contentItem;
|
|
@@ -49,35 +47,30 @@ export class RceLti11ContentItem {
|
|
|
49
47
|
return LTI_MIME_TYPES.includes((_this$contentItem$med = this.contentItem.mediaType) !== null && _this$contentItem$med !== void 0 ? _this$contentItem$med : '');
|
|
50
48
|
}
|
|
51
49
|
get isOverriddenForThumbnail() {
|
|
52
|
-
|
|
53
|
-
return this.isLTI && this.contentItem.thumbnail && ((_this$contentItem$pla = this.contentItem.placementAdvice) === null || _this$contentItem$pla === void 0 ? void 0 : _this$contentItem$pla.presentationDocumentTarget) === 'iframe';
|
|
50
|
+
return this.isLTI && this.contentItem.thumbnail && this.contentItem.placementAdvice?.presentationDocumentTarget === 'iframe';
|
|
54
51
|
}
|
|
55
52
|
get isImage() {
|
|
56
|
-
|
|
57
|
-
return ((_this$contentItem$med2 = this.contentItem.mediaType) === null || _this$contentItem$med2 === void 0 ? void 0 : (_this$contentItem$med3 = _this$contentItem$med2.startsWith) === null || _this$contentItem$med3 === void 0 ? void 0 : _this$contentItem$med3.call(_this$contentItem$med2, 'image')) === true;
|
|
53
|
+
return this.contentItem.mediaType?.startsWith?.('image') === true;
|
|
58
54
|
}
|
|
59
55
|
get linkClassName() {
|
|
60
56
|
return this.isOverriddenForThumbnail ? 'lti-thumbnail-launch' : '';
|
|
61
57
|
}
|
|
62
58
|
get url() {
|
|
63
|
-
|
|
64
|
-
return (_ref = this.isLTI ? this.contentItem.canvasURL : this.contentItem.url) === null || _ref === void 0 ? void 0 : _ref.replace(/^(data:text\/html|javascript:)/, '#$1');
|
|
59
|
+
return (this.isLTI ? this.contentItem.canvasURL : this.contentItem.url)?.replace(/^(data:text\/html|javascript:)/, '#$1');
|
|
65
60
|
}
|
|
66
61
|
get linkTarget() {
|
|
67
|
-
var _this$contentItem, _this$contentItem$pla2, _this$contentItem$pla3;
|
|
68
62
|
if (this.isOverriddenForThumbnail) {
|
|
69
63
|
return JSON.stringify(this.contentItem.placementAdvice);
|
|
70
64
|
}
|
|
71
|
-
return
|
|
65
|
+
return this.contentItem?.placementAdvice?.presentationDocumentTarget?.toLowerCase() === 'window' ? '_blank' : null;
|
|
72
66
|
}
|
|
73
67
|
get docTarget() {
|
|
74
|
-
|
|
75
|
-
if (((_this$contentItem2 = this.contentItem) === null || _this$contentItem2 === void 0 ? void 0 : (_this$contentItem2$pl = _this$contentItem2.placementAdvice) === null || _this$contentItem2$pl === void 0 ? void 0 : _this$contentItem2$pl.presentationDocumentTarget) === 'embed' && !this.isImage) {
|
|
68
|
+
if (this.contentItem?.placementAdvice?.presentationDocumentTarget === 'embed' && !this.isImage) {
|
|
76
69
|
return 'text';
|
|
77
70
|
} else if (this.isOverriddenForThumbnail) {
|
|
78
71
|
return 'link';
|
|
79
72
|
}
|
|
80
|
-
return
|
|
73
|
+
return this.contentItem?.placementAdvice?.presentationDocumentTarget?.toLowerCase();
|
|
81
74
|
}
|
|
82
75
|
get codePayload() {
|
|
83
76
|
switch (this.docTarget) {
|
|
@@ -98,14 +91,14 @@ export class RceLti11ContentItem {
|
|
|
98
91
|
return this.env.editorSelection;
|
|
99
92
|
}
|
|
100
93
|
generateCodePayloadIframe() {
|
|
101
|
-
var _addParentFrameContex, _this$contentItem$tit, _this$
|
|
94
|
+
var _addParentFrameContex, _this$contentItem$tit, _this$contentItem$pla, _this$contentItem$pla2;
|
|
102
95
|
const iframe = document.createElement('iframe');
|
|
103
96
|
iframe.src = (_addParentFrameContex = addParentFrameContextToUrl(this.url, this.containingCanvasLtiToolId)) !== null && _addParentFrameContex !== void 0 ? _addParentFrameContex : '';
|
|
104
97
|
iframe.title = (_this$contentItem$tit = this.contentItem.title) !== null && _this$contentItem$tit !== void 0 ? _this$contentItem$tit : '';
|
|
105
98
|
iframe.setAttribute('allowfullscreen', 'true');
|
|
106
99
|
iframe.setAttribute('webkitallowfullscreen', 'true');
|
|
107
100
|
iframe.setAttribute('mozallowfullscreen', 'true');
|
|
108
|
-
if (
|
|
101
|
+
if (this.env?.ltiIframeAllowPolicy !== undefined) {
|
|
109
102
|
iframe.setAttribute('allow', this.env.ltiIframeAllowPolicy);
|
|
110
103
|
} else if (this.isLTI) {
|
|
111
104
|
iframe.setAttribute('allow', 'microphone; camera; midi');
|
|
@@ -113,8 +106,8 @@ export class RceLti11ContentItem {
|
|
|
113
106
|
if (this.contentItem.class) {
|
|
114
107
|
iframe.className = this.contentItem.class;
|
|
115
108
|
}
|
|
116
|
-
const w = maybeAddPx((_this$contentItem$
|
|
117
|
-
const h = maybeAddPx((_this$contentItem$
|
|
109
|
+
const w = maybeAddPx((_this$contentItem$pla = this.contentItem.placementAdvice?.displayWidth) !== null && _this$contentItem$pla !== void 0 ? _this$contentItem$pla : undefined);
|
|
110
|
+
const h = maybeAddPx((_this$contentItem$pla2 = this.contentItem.placementAdvice?.displayHeight) !== null && _this$contentItem$pla2 !== void 0 ? _this$contentItem$pla2 : undefined);
|
|
118
111
|
if (w) {
|
|
119
112
|
iframe.style.width = w;
|
|
120
113
|
iframe.setAttribute('width', w.replace('px', ''));
|
|
@@ -139,12 +132,12 @@ export class RceLti11ContentItem {
|
|
|
139
132
|
return div.innerHTML;
|
|
140
133
|
}
|
|
141
134
|
generateCodePayloadEmbed() {
|
|
142
|
-
var _this$contentItem$
|
|
135
|
+
var _this$contentItem$pla3, _this$contentItem$pla4;
|
|
143
136
|
const img = document.createElement('img');
|
|
144
137
|
if (this.url) img.src = this.url;
|
|
145
138
|
if (this.text) img.alt = this.text;
|
|
146
|
-
const w = maybeAddPx((_this$contentItem$
|
|
147
|
-
const h = maybeAddPx((_this$contentItem$
|
|
139
|
+
const w = maybeAddPx((_this$contentItem$pla3 = this.contentItem.placementAdvice?.displayWidth) !== null && _this$contentItem$pla3 !== void 0 ? _this$contentItem$pla3 : undefined);
|
|
140
|
+
const h = maybeAddPx((_this$contentItem$pla4 = this.contentItem.placementAdvice?.displayHeight) !== null && _this$contentItem$pla4 !== void 0 ? _this$contentItem$pla4 : undefined);
|
|
148
141
|
if (w) img.style.width = w;
|
|
149
142
|
if (h) img.style.height = h;
|
|
150
143
|
const div = document.createElement('div');
|
|
@@ -184,8 +177,8 @@ export class RceLti11ContentItem {
|
|
|
184
177
|
return div.innerHTML;
|
|
185
178
|
}
|
|
186
179
|
generateLinkHtml() {
|
|
187
|
-
var
|
|
188
|
-
return (
|
|
180
|
+
var _ref, _emptyAsNull;
|
|
181
|
+
return (_ref = (_emptyAsNull = emptyAsNull(this.currentTinyMceSelection)) !== null && _emptyAsNull !== void 0 ? _emptyAsNull : emptyAsNull(this.contentItem.text?.trim())) !== null && _ref !== void 0 ? _ref : this.contentItem?.title?.trim();
|
|
189
182
|
}
|
|
190
183
|
}
|
|
191
184
|
const LTI_MIME_TYPES = ['application/vnd.ims.lti.v1.ltilink', 'application/vnd.ims.lti.v1.launch+json'];
|
package/es/rce/plugins/instructure_rce_external_tools/lti13-content-items/RceLti13ContentItem.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1
2
|
// @ts-nocheck
|
|
2
3
|
/*
|
|
3
4
|
* Copyright (C) 2018 - present Instructure, Inc.
|
|
@@ -88,7 +89,6 @@ export class RceLti13ContentItem {
|
|
|
88
89
|
return anchorTag.outerHTML;
|
|
89
90
|
}
|
|
90
91
|
get safeUrl() {
|
|
91
|
-
|
|
92
|
-
return ((_this$buildUrl = this.buildUrl()) === null || _this$buildUrl === void 0 ? void 0 : _this$buildUrl.replace(/^(data:text\/html|javascript:)/, '#$1')) || '';
|
|
92
|
+
return this.buildUrl()?.replace(/^(data:text\/html|javascript:)/, '#$1') || '';
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -20,17 +20,16 @@ import { RceLti13ContentItem } from '../RceLti13ContentItem';
|
|
|
20
20
|
// Base content item type
|
|
21
21
|
export default class BaseLinkContentItem extends RceLti13ContentItem {
|
|
22
22
|
toHtmlString() {
|
|
23
|
-
|
|
24
|
-
if (((_this$iframe = this.iframe) === null || _this$iframe === void 0 ? void 0 : _this$iframe.src) != null) {
|
|
23
|
+
if (this.iframe?.src != null) {
|
|
25
24
|
return this.iframeTag();
|
|
26
25
|
} else {
|
|
27
26
|
return this.anchorTag(this.linkBody());
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
linkText() {
|
|
31
|
-
var _this$buildText$trim, _this$
|
|
32
|
-
const text = (_this$buildText$trim =
|
|
33
|
-
const title = (_this$buildTitle$trim =
|
|
30
|
+
var _this$buildText$trim, _this$buildTitle$trim;
|
|
31
|
+
const text = (_this$buildText$trim = this.buildText()?.trim()) !== null && _this$buildText$trim !== void 0 ? _this$buildText$trim : '';
|
|
32
|
+
const title = (_this$buildTitle$trim = this.buildTitle()?.trim()) !== null && _this$buildTitle$trim !== void 0 ? _this$buildTitle$trim : '';
|
|
34
33
|
return text.length > 0 ? text : title.length > 0 ? title : undefined;
|
|
35
34
|
}
|
|
36
35
|
linkBody() {
|
|
@@ -21,10 +21,10 @@ import { showFlashAlert } from '../../../../common/FlashAlert';
|
|
|
21
21
|
import formatMessage from '../../../../format-message';
|
|
22
22
|
export default function processEditorContentItems(event, env, dialog) {
|
|
23
23
|
try {
|
|
24
|
-
var _event$data
|
|
25
|
-
const ltiEndpoint =
|
|
24
|
+
var _event$data$content_i;
|
|
25
|
+
const ltiEndpoint = event.data?.ltiEndpoint;
|
|
26
26
|
const selection = env.editorSelection;
|
|
27
|
-
const eventContentItems = (_event$data$content_i =
|
|
27
|
+
const eventContentItems = (_event$data$content_i = event.data?.content_items) !== null && _event$data$content_i !== void 0 ? _event$data$content_i : [];
|
|
28
28
|
let unsupportedItemWarningShown = false;
|
|
29
29
|
for (const inputItem of eventContentItems) {
|
|
30
30
|
const parsedItem = rceLti13ContentItemFromJson(inputItem, {
|
|
@@ -34,8 +34,7 @@ export default function processEditorContentItems(event, env, dialog) {
|
|
|
34
34
|
ltiIframeAllowPolicy: env.ltiIframeAllowPolicy
|
|
35
35
|
});
|
|
36
36
|
if (parsedItem != null) {
|
|
37
|
-
|
|
38
|
-
if ((_event$data3 = event.data) !== null && _event$data3 !== void 0 && _event$data3.replaceEditorContents) {
|
|
37
|
+
if (event.data?.replaceEditorContents) {
|
|
39
38
|
env.replaceCode(parsedItem.toHtmlString());
|
|
40
39
|
} else {
|
|
41
40
|
env.insertCode(parsedItem.toHtmlString());
|
|
@@ -54,17 +53,17 @@ export default function processEditorContentItems(event, env, dialog) {
|
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
// Remove "unsaved changes" warnings and close modal
|
|
57
|
-
if (
|
|
58
|
-
dialog
|
|
56
|
+
if (event.data?.content_items) {
|
|
57
|
+
dialog?.close();
|
|
59
58
|
}
|
|
60
|
-
if (
|
|
59
|
+
if (event.data?.msg !== undefined) {
|
|
61
60
|
// @ts-expect-error
|
|
62
61
|
showFlashAlert({
|
|
63
62
|
message: event.data.msg.toString()
|
|
64
63
|
});
|
|
65
64
|
}
|
|
66
65
|
// @ts-expect-error
|
|
67
|
-
if (
|
|
66
|
+
if (event.data?.errormsg !== undefined) {
|
|
68
67
|
// @ts-expect-error
|
|
69
68
|
showFlashAlert({
|
|
70
69
|
message: event.data.errormsg.toString(),
|
|
@@ -32,7 +32,6 @@ import ResourceLinkContentItem from './models/ResourceLinkContentItem';
|
|
|
32
32
|
export function rceLti13ContentItemFromJson(itemJson, context) {
|
|
33
33
|
if (!itemJson.type) return null;
|
|
34
34
|
const clazz = typeRegistry[itemJson.type];
|
|
35
|
-
// eslint-disable-next-line new-cap
|
|
36
35
|
return clazz ? new clazz(itemJson, context) : null;
|
|
37
36
|
}
|
|
38
37
|
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
import tinymce from 'tinymce';
|
|
20
20
|
import React from 'react';
|
|
21
21
|
import ReactDOM from 'react-dom';
|
|
22
|
-
import { RceToolWrapper, buildToolMenuItems
|
|
22
|
+
import { RceToolWrapper, buildToolMenuItems } from './RceToolWrapper';
|
|
23
23
|
import formatMessage from '../../../format-message';
|
|
24
24
|
import { ExternalToolSelectionDialog } from './components/ExternalToolSelectionDialog/ExternalToolSelectionDialog';
|
|
25
25
|
import { ensureToolDialogContainerElem } from './dialog-helper';
|
|
26
26
|
import { externalToolsEnvFor } from './ExternalToolsEnv';
|
|
27
|
-
|
|
27
|
+
import { externalToolsForToolbar } from './util/externalToolsForToolbar';
|
|
28
28
|
// Register plugin
|
|
29
29
|
tinymce.PluginManager.add('instructure_rce_external_tools', initExternalToolsLocalPlugin);
|
|
30
30
|
|
|
@@ -78,8 +78,8 @@ function registerAppsToolbarButton(editor) {
|
|
|
78
78
|
},
|
|
79
79
|
onSetup(_api) {
|
|
80
80
|
const e = document.querySelector("button[title='apps-temp']");
|
|
81
|
-
e
|
|
82
|
-
e
|
|
81
|
+
e?.setAttribute('title', formatMessage('Apps'));
|
|
82
|
+
e?.setAttribute('id', 'plug-apps-button');
|
|
83
83
|
return () => undefined;
|
|
84
84
|
}
|
|
85
85
|
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2025 - present Instructure, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This file is part of Canvas.
|
|
5
|
+
*
|
|
6
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
|
7
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
|
8
|
+
* Software Foundation, version 3 of the License.
|
|
9
|
+
*
|
|
10
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
11
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
12
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
13
|
+
* details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License along
|
|
16
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export function externalToolsForToolbar(tools) {
|
|
20
|
+
// Limit of not on_by_default but favorited tools is 2
|
|
21
|
+
const favorited = tools.filter(it => it.favorite && !it.on_by_default).slice(0, 2) || [];
|
|
22
|
+
const onByDefault = tools.filter(it => it.on_by_default && it.favorite) || [];
|
|
23
|
+
const set = new Map();
|
|
24
|
+
// Remove possible overlaps between favorited and onByDefault, otherwise
|
|
25
|
+
// we'd have duplicate buttons in the toolbar.
|
|
26
|
+
for (const toolInfo of favorited.concat(onByDefault)) {
|
|
27
|
+
set.set(toolInfo.id, toolInfo);
|
|
28
|
+
}
|
|
29
|
+
return Array.from(set.values()).sort((a, b) => {
|
|
30
|
+
if (a.on_by_default && !b.on_by_default) {
|
|
31
|
+
return -1;
|
|
32
|
+
} else if (!a.on_by_default && b.on_by_default) {
|
|
33
|
+
return 1;
|
|
34
|
+
} else {
|
|
35
|
+
// This *should* always be a string, but there might be cases where it isn't,
|
|
36
|
+
// especially when this method is used outside of TypeScript files.
|
|
37
|
+
return a.id.toString().localeCompare(b.id.toString(), undefined, {
|
|
38
|
+
numeric: true
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|