diff --git a/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.ts b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.ts index d781ae21f9..de880a1e6b 100644 --- a/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.ts +++ b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPlugin.ts @@ -13,13 +13,6 @@ export default function(context) { const token = tokens[idx]; if (token.info !== 'justtesting') return defaultRender(tokens, idx, options, env, self); - const postMessageWithResponseTest = ` - webviewApi.postMessage('${contentScriptId}', 'justtesting').then(function(response) { - console.info('Got response in content script: ' + response); - }); - return false; - `; - // Rich text editor support: // The joplin-editable and joplin-source CSS classes mark the generated div // as a region that needs special processing when converting back to markdown. @@ -38,14 +31,23 @@ export default function(context) { ${richTextEditorMetadata}
JUST TESTING:
${markdownIt.utils.escapeHtml(leftPad(token.content.trim(), 10, 'x'))}
- Click to post a message "justtesting" to plugin and check the response in the console
++ +
`; }; }, assets: function() { return [ - { name: 'markdownItTestPlugin.css' } + { name: 'markdownItTestPlugin.css' }, + { name: 'markdownItTestPluginRuntime.js' }, ]; }, } diff --git a/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPluginRuntime.js b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPluginRuntime.js new file mode 100644 index 0000000000..b3c0150ad0 --- /dev/null +++ b/packages/app-cli/tests/support/plugins/content_script/src/markdownItTestPluginRuntime.js @@ -0,0 +1,14 @@ +const addClickHandlers = () => { + const postMessageLinks = document.querySelectorAll('.post-message-link'); + for (const link of postMessageLinks) { + const contentScriptId = link.getAttribute('data-content-script-id'); + link.onclick = async () => { + const response = await webviewApi.postMessage(contentScriptId, 'justtesting'); + link.textContent = 'Got response in content script: ' + response; + }; + } +}; + +document.addEventListener('joplin-noteDidUpdate', () => { + addClickHandlers(); +}); diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx index 01ed279071..0dc1265dd2 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx @@ -43,6 +43,7 @@ import useKeyboardRefocusHandler from './utils/useKeyboardRefocusHandler'; import useDocument from '../../../hooks/useDocument'; import useEditDialog from './utils/useEditDialog'; import useEditDialogEventListeners from './utils/useEditDialogEventListeners'; +import Setting from '@joplin/lib/models/Setting'; import useTextPatternsLookup from './utils/useTextPatternsLookup'; const logger = Logger.create('TinyMCE'); @@ -728,6 +729,25 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { language_url: ['en_US', 'en_GB'].includes(language) ? undefined : `${bridge().vendorDir()}/lib/tinymce/langs/${language}`, toolbar: toolbar.join(' '), localization_function: _, + // See https://www.tiny.cloud/docs/tinymce/latest/tinymce-and-csp/#content_security_policy + content_security_policy: Setting.value('featureFlag.richText.useStrictContentSecurityPolicy') ? [ + // Media: *: Allow users to include images and videos from the internet (e.g. ). + // Media: blob: Allow loading images/videos/audio from blob URLs. The Rich Text Editor + // replaces certain base64 URLs with blob URLs. + // Media: data: Allow loading images and other media from data: URLs + 'default-src \'self\'', + 'img-src \'self\' blob: data: *', // Images + 'media-src \'self\' blob: data: *', // Audio and video players + + // Disallow certain unused features + 'child-src \'none\'', // Should not contain sub-frames + 'object-src \'none\'', // Objects can be used for script injection + 'form-action \'none\'', // No submitting forms + + // Styles: unsafe-inline: TinyMCE uses inline style="" styles. + // Styles: *: Allow users to include styles from the internet (e.g.