Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desktop: Resolves #3535: Configure tinymce to handle the first table row as header #8163

Merged
merged 4 commits into from Jun 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 35 additions & 6 deletions packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx
Expand Up @@ -25,6 +25,7 @@ import { themeStyle } from '@joplin/lib/theme';
import { loadScript } from '../../../utils/loadScript';
import bridge from '../../../../services/bridge';
import { TinyMceEditorEvents } from './utils/types';
import type { Editor } from 'tinymce';
const { clipboard } = require('electron');
const supportedLocales = require('./supportedLocales');

Expand Down Expand Up @@ -557,7 +558,15 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
'bold', 'italic', 'joplinHighlight', 'joplinStrikethrough', 'formattingExtras', '|',
'link', 'joplinInlineCode', 'joplinCodeBlock', 'joplinAttach', '|',
'bullist', 'numlist', 'joplinChecklist', '|',
'h1', 'h2', 'h3', 'hr', 'blockquote', 'table', `joplinInsertDateTime${toolbarPluginButtons}`,
'h1', 'h2', 'h3', 'hr', 'blockquote', 'inserttable', `joplinInsertDateTime${toolbarPluginButtons}`,
];

// Available table toolbar buttons:
// https://www.tiny.cloud/docs/advanced/available-toolbar-buttons/#tableplugin
const tableToolbar = [
'tabledelete',
'tableinsertrowafter tablecopyrow tablepasterowafter tabledeleterow',
'tableinsertcolafter tablecopycol tablepastecolafter tabledeletecol',
];

const editors = await (window as any).tinymce.init({
Expand All @@ -576,6 +585,10 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
branding: false,
statusbar: false,
target_list: false,
// Handle the first table row as table header.
// https://www.tiny.cloud/docs/plugins/table/#table_header_type
table_header_type: 'sectionCells',
table_toolbar: tableToolbar.join(' | '),
table_resize_bars: false,
language_url: ['en_US', 'en_GB'].includes(language) ? undefined : `${bridge().vendorDir()}/lib/tinymce/langs/${language}`,
toolbar: toolbar.join(' '),
Expand All @@ -589,7 +602,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
joplinSub: { inline: 'sub', remove: 'all' },
joplinSup: { inline: 'sup', remove: 'all' },
},
setup: (editor: any) => {
setup: (editor: Editor) => {
editor.ui.registry.addButton('joplinAttach', {
tooltip: _('Attach file'),
icon: 'paperclip',
Expand All @@ -614,7 +627,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
onAction: function() {
editor.execCommand('mceToggleFormat', false, 'code', { class: 'inline-code' });
},
onSetup: function(api: any) {
onSetup: function(api) {
api.setActive(editor.formatter.match('code'));
const unbind = editor.formatter.formatChanged('code', api.setActive).unbind;

Expand All @@ -624,6 +637,22 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
},
});

editor.ui.registry.addMenuButton('inserttable', {
icon: 'table',
tooltip: 'Table',
fetch: (callback) => {
callback([
{
type: 'fancymenuitem',
fancytype: 'inserttable',
onAction: (data) => {
editor.execCommand('mceInsertTable', false, { rows: data.numRows, columns: data.numColumns, options: { headerRows: 1 } });
},
},
]);
},
});

editor.ui.registry.addButton('joplinInsertDateTime', {
tooltip: _('Insert time'),
icon: 'insert-time',
Expand All @@ -647,13 +676,13 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
editor.addShortcut('Meta+Shift+9', '', () => editor.execCommand('InsertJoplinChecklist'));

// TODO: remove event on unmount?
editor.on('DblClick', (event: any) => {
editor.on('DblClick', (event) => {
const editable = findEditableContainer(event.target);
if (editable) openEditDialog(editor, markupToHtml, dispatchDidUpdate, editable);
});

// This is triggered when an external file is dropped on the editor
editor.on('drop', (event: any) => {
editor.on('drop', (event) => {
// Prevent the message "Dropped file type is not
// supported" to show up. It was added in a recent
// TinyMCE version and doesn't apply since we do support
Expand All @@ -664,7 +693,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
props_onDrop.current(event);
});

editor.on('ObjectResized', (event: any) => {
editor.on('ObjectResized', (event) => {
if (event.target.nodeName === 'IMG') {
editor.fire(TinyMceEditorEvents.JoplinChange);
dispatchDidUpdate(editor);
Expand Down