UNPKG

@instructure/canvas-rce

Version:

A component wrapping Canvas's usage of Tinymce

107 lines (103 loc) 3.98 kB
/* * Copyright (C) 2018 - present Instructure, Inc. * * This file is part of Canvas. * * Canvas is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, version 3 of the License. * * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ import tinymce from 'tinymce'; import React from 'react'; import ReactDOM from 'react-dom'; import { RceToolWrapper, buildToolMenuItems } from './RceToolWrapper'; import formatMessage from '../../../format-message'; import { ExternalToolSelectionDialog } from './components/ExternalToolSelectionDialog/ExternalToolSelectionDialog'; import { ensureToolDialogContainerElem } from './dialog-helper'; import { externalToolsEnvFor } from './ExternalToolsEnv'; import { externalToolsForToolbar } from './util/externalToolsForToolbar'; // Register plugin tinymce.PluginManager.add('instructure_rce_external_tools', initExternalToolsLocalPlugin); /** * This plugin adds the "Apps" toolbar button and the "Apps" menu item. It is a rewrite of 'instructure_external_tools' * to live fully in the canvas-rce package. It supports running in an iframe as part of an LTI tool, such as * new quizzes. * * @param editor */ export function initExternalToolsLocalPlugin(editor) { if (RceToolWrapper.forEditorEnv(externalToolsEnvFor(editor)).length === 0) { return; } registerFavoriteAppsToolbarButtons(editor); registerAppsToolbarButton(editor); registerAppsMenu(editor); } /** * Add the "Apps" toolbar button with "View all" and MRU buttons */ function registerAppsMenu(editor) { editor.ui.registry.addNestedMenuItem('lti_tools_menuitem', { text: formatMessage('Apps'), icon: 'lti', getSubmenuItems: () => { const availableTools = RceToolWrapper.forEditorEnv(externalToolsEnvFor(editor)); const toolMenuItems = buildToolMenuItems(availableTools, makeViewAllItem(editor)); return toolMenuItems; } }); } /** * Registers toolbar buttons for favorite apps */ function registerFavoriteAppsToolbarButtons(editor) { const allTools = RceToolWrapper.forEditorEnv(externalToolsEnvFor(editor)); externalToolsForToolbar(allTools).forEach(toolInfo => editor.ui.registry.addButton(`instructure_external_button_${toolInfo.id}`, toolInfo.asToolbarButton())); } function registerAppsToolbarButton(editor) { const tooltip = 'apps-temp'; editor.ui.registry.addMenuButton('lti_mru_button', { tooltip, icon: 'lti', fetch: callback => { const availableTools = RceToolWrapper.forEditorEnv(externalToolsEnvFor(editor)); const toolMenuItems = buildToolMenuItems(availableTools, makeViewAllItem(editor)); callback(toolMenuItems); }, onSetup(_api) { const e = document.querySelector("button[title='apps-temp']"); e?.setAttribute('title', formatMessage('Apps')); e?.setAttribute('id', 'plug-apps-button'); return () => undefined; } }); } function openToolSelectionDialog(editor) { const availableTools = RceToolWrapper.forEditorEnv(externalToolsEnvFor(editor)); const container = ensureToolDialogContainerElem(); const handleDismiss = () => { ReactDOM.unmountComponentAtNode(container); editor.focus(); }; ReactDOM.render(/*#__PURE__*/React.createElement(ExternalToolSelectionDialog, { onDismiss: handleDismiss, ltiButtons: availableTools }), ensureToolDialogContainerElem()); } function makeViewAllItem(editor) { return { type: 'menuitem', text: formatMessage('View All'), onAction() { openToolSelectionDialog(editor); } }; }