Skip to content

Commit

Permalink
fix(Composer): avoid transformation of links to relative urls
Browse files Browse the repository at this point in the history
refs: SHELL-2 (#187)
  • Loading branch information
beawar authored Jan 24, 2023
1 parent 3d8085f commit da63bf9
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 135 deletions.
13 changes: 8 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@
"redux-logger": "3.0.6",
"redux-persist": "6.0.0",
"remark-gfm": "3.0.1",
"tinymce": "^5.10.2",
"tinymce": "^5.10.7",
"ua-parser-js": "^1.0.2",
"zustand": "^3.7.2"
},
"peerDependencies": {
"@reduxjs/toolkit": "^1.6.2",
"@zextras/carbonio-design-system": ">=1.0.0",
"@zextras/carbonio-design-system": "^1.0.0",
"core-js": "^3.19.1",
"moment": "^2.29.1",
"node-fetch": "^2.6.6",
Expand Down
2 changes: 0 additions & 2 deletions src/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ type cliSettingsNamespace = {
*/
declare const devUtils: devUtilsNamespace | undefined;
declare const cliSettings: cliSettingsNamespace | undefined;
// declare module '@zextras/carbonio-design-system';
declare module 'tinymce';
declare module '*.svg';
declare module '*.mp3';
declare module '*.png';
272 changes: 146 additions & 126 deletions src/store/integrations/composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@
import { Container } from '@zextras/carbonio-design-system';
import React, { FC, useCallback, useMemo, useRef } from 'react';
import styled from 'styled-components';
import type { EditorSettings, TinyMCE, Ui } from 'tinymce/tinymce';
// TinyMCE so the global var exists
// eslint-disable-next-line no-unused-vars
import tinymce from 'tinymce/tinymce';
// this 'expression' prevents webpack from stripping it, maybe there's a better way
// eslint-disable-next-line no-unused-expressions
tinymce;
// Theme
import 'tinymce/themes/silver';
// Toolbar icons
Expand Down Expand Up @@ -43,22 +40,24 @@ import 'tinymce/plugins/table';
import 'tinymce/plugins/visualblocks';
import 'tinymce/plugins/wordcount';

import { Editor } from '@tinymce/tinymce-react';
import { Editor, IAllProps as EditorProps } from '@tinymce/tinymce-react';
import { useUserSettings } from '../account';
import { getT, useI18nStore } from '../i18n';

type ComposerProps = {
type ComposerProps = EditorProps & {
/** The callback invoked when an edit is performed into the editor. `([text, html]) => {}` */
onEditorChange?: (values: [string, string]) => void;
/** Enable the distraction-free mode */
inline?: boolean;
/** The initial content of the editor */
initialValue?: string;
initialValue?: EditorProps['initialValue'];
/** The content of the editor (controlled mode) */
value?: string;
/** The base url to append to the resource urls */
baseAssetsUrl?: string;
onFileSelect?: (arg: any) => void;
value?: EditorProps['value'];
/**
* Callback called when user choose some file from the os.
* If defined, a menu item to add inline images is added to the composer.
*/
onFileSelect?: (arg: { editor: TinyMCE; files: HTMLInputElement['files'] | undefined }) => void;
};

export const FileInput = styled.input`
Expand All @@ -71,10 +70,9 @@ const Composer: FC<ComposerProps> = ({
inline = false,
value,
initialValue,

...rest
}) => {
const _onEditorChange = useCallback(
const _onEditorChange = useCallback<NonNullable<EditorProps['onEditorChange']>>(
(newContent, editor) => {
onEditorChange?.([
editor.getContent({ format: 'text' }),
Expand All @@ -92,16 +90,147 @@ const Composer: FC<ComposerProps> = ({
}),
[prefs]
);
const inputRef = useRef<any>();
const inputRef = useRef<HTMLInputElement>(null);
const onFileClick = useCallback(() => {
if (inputRef.current) {
inputRef.current.value = null;
inputRef.current.value = '';
inputRef.current.click();
}
}, []);
const t = getT();
const { locale } = useI18nStore.getState();
const inlineLabel = useMemo(() => t('label.add_inline_image', 'Add inline image'), [t]);

const setupCallback = useCallback<NonNullable<EditorSettings['setup']>>(
(editor) => {
if (onFileSelect)
editor.ui.registry.addMenuButton('imageSelector', {
icon: 'gallery',
tooltip: t('label.select_image', 'Select image'),
fetch: (callback) => {
const items: Ui.Menu.MenuItemSpec[] = [
{
type: 'menuitem',
text: inlineLabel,
onAction: (): void => {
onFileClick();
}
}
];
callback(items);
}
});
},
[inlineLabel, onFileClick, onFileSelect, t]
);

const editorInitConfig = useMemo<EditorProps['init']>(
() => ({
content_css: `${BASE_PATH}/tinymce/skins/content/default/content.css`,
language_url: `${BASE_PATH}tinymce/langs/${locale}.js`,
language: locale,
setup: setupCallback,
min_height: 350,
auto_focus: true,
menubar: false,
statusbar: false,
branding: false,
resize: true,
inline,
fontsize_formats:
'8pt 9pt 10pt 11pt 12pt 13pt 14pt 16pt 18pt 24pt 30pt 36pt 48pt 60pt 72pt 96pt',
object_resizing: 'img',
style_formats: [
{
title: 'Headers',
items: [
{ title: 'h1', block: 'h1' },
{ title: 'h2', block: 'h2' },
{ title: 'h3', block: 'h3' },
{ title: 'h4', block: 'h4' },
{ title: 'h5', block: 'h5' },
{ title: 'h6', block: 'h6' }
]
},
{
title: 'Blocks',
items: [
{ title: 'p', block: 'p' },
{ title: 'div', block: 'div' },
{ title: 'pre', block: 'pre' }
]
},
{
title: 'Containers',
items: [
{ title: 'section', block: 'section', wrapper: true, merge_siblings: false },
{ title: 'article', block: 'article', wrapper: true, merge_siblings: false },
{ title: 'blockquote', block: 'blockquote', wrapper: true },
{ title: 'hgroup', block: 'hgroup', wrapper: true },
{ title: 'aside', block: 'aside', wrapper: true },
{ title: 'figure', block: 'figure', wrapper: true }
]
}
],
plugins: [
'advlist',
'autolink',
'lists',
'link',
'image',
'edit',
'file',
'charmap',
'print',
'preview',
'anchor',
'searchreplace',
'code',
'fullscreen',
'insertdatetime',
'media',
'table',
'paste',
'code',
'help',
'quickbars',
'directionality',
'autoresize',
'visualblocks'
],
toolbar: inline
? false
: [
'fontselect fontsizeselect styleselect visualblocks',
'bold italic underline strikethrough',
'removeformat code',
'alignleft aligncenter alignright alignjustify',
'forecolor backcolor',
'bullist numlist outdent indent',
'ltr rtl',
'insertfile image',
'imageSelector'
].join(' | '),
quickbars_insert_toolbar: inline ? 'bullist numlist' : '',
quickbars_selection_toolbar: inline
? 'bold italic underline | forecolor backcolor | removeformat | quicklink'
: 'quicklink',
contextmenu: inline ? '' : '',
toolbar_mode: 'wrap',
forced_root_block: false,
content_style: `body { color: ${defaultStyle?.color}; font-size: ${defaultStyle?.fontSize}; font-family: ${defaultStyle?.font}; }`,
visualblocks_default_state: false,
end_container_on_empty_block: true,
relative_urls: false,
remove_script_host: false
}),
[defaultStyle?.color, defaultStyle?.font, defaultStyle?.fontSize, inline, locale, setupCallback]
);

const fileInputOnChange = useCallback((): void => {
onFileSelect?.({ editor: tinymce, files: inputRef?.current?.files });
}, [onFileSelect]);

return (
<Container
height="100%"
Expand All @@ -113,123 +242,14 @@ const Composer: FC<ComposerProps> = ({
type="file"
ref={inputRef}
accept="image/*"
onChange={(): void => {
onFileSelect && onFileSelect({ editor: tinymce, files: inputRef?.current?.files });
}}
onChange={fileInputOnChange}
multiple
/>

<Editor
initialValue={initialValue}
value={value}
init={{
content_css: `${BASE_PATH}/tinymce/skins/content/default/content.css`,
language_url: `${BASE_PATH}tinymce/langs/${locale}.js`,
language: locale,
setup: (editor: any): void => {
if (onFileSelect)
editor.ui.registry.addMenuButton('imageSelector', {
icon: 'gallery',
tooltip: t('label.select_image', 'Select image'),
fetch: (callback: any) => {
const items = [
{
type: 'menuitem',
text: inlineLabel,
onAction: (): void => {
onFileClick();
}
}
];
callback(items);
}
});
},
min_height: 350,
auto_focus: true,
menubar: false,
statusbar: false,
branding: false,
resize: true,
inline,
fontsize_formats:
'8pt 9pt 10pt 11pt 12pt 13pt 14pt 16pt 18pt 24pt 30pt 36pt 48pt 60pt 72pt 96pt',
object_resizing: 'img',
style_formats: [
{
title: 'Headers',
items: [
{ title: 'h1', block: 'h1' },
{ title: 'h2', block: 'h2' },
{ title: 'h3', block: 'h3' },
{ title: 'h4', block: 'h4' },
{ title: 'h5', block: 'h5' },
{ title: 'h6', block: 'h6' }
]
},
{
title: 'Blocks',
items: [
{ title: 'p', block: 'p' },
{ title: 'div', block: 'div' },
{ title: 'pre', block: 'pre' }
]
},

{
title: 'Containers',
items: [
{ title: 'section', block: 'section', wrapper: true, merge_siblings: false },
{ title: 'article', block: 'article', wrapper: true, merge_siblings: false },
{ title: 'blockquote', block: 'blockquote', wrapper: true },
{ title: 'hgroup', block: 'hgroup', wrapper: true },
{ title: 'aside', block: 'aside', wrapper: true },
{ title: 'figure', block: 'figure', wrapper: true }
]
}
],
plugins: [
'advlist',
'autolink',
'lists',
'link',
'image',
'edit',
'file',
'charmap',
'print',
'preview',
'anchor',
'searchreplace',
'code',
'fullscreen',
'insertdatetime',
'media',
'table',
'paste',
'code',
'help',
'quickbars',
'directionality',
'autoresize',
'visualblocks'
],

toolbar: inline
? false
: // eslint-disable-next-line max-len
'fontselect fontsizeselect styleselect visualblocks| bold italic underline strikethrough | removeformat code | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist outdent indent | ltr rtl | insertfile image | imageSelector ',
quickbars_insert_toolbar: inline ? 'bullist numlist' : '',
quickbars_selection_toolbar: inline
? 'bold italic underline | forecolor backcolor | removeformat | quicklink'
: 'quicklink',
contextmenu: inline ? '' : '',
toolbar_mode: 'wrap',
forced_root_block: false,
content_style: `body { color: ${defaultStyle?.color}; font-size: ${defaultStyle?.fontSize}; font-family: ${defaultStyle?.font}; }`,
visualblocks_default_state: false,
end_container_on_empty_block: true
}}
init={editorInitConfig}
onEditorChange={_onEditorChange}
{...rest}
/>
Expand Down

0 comments on commit da63bf9

Please sign in to comment.