import {getPlugin as getAboutPlugin} from './plugins-about';
import {getPlugin as getDetailsPlugin} from './plugins-details';
import {getPlugin as getTasklistPlugin} from './plugins-tasklist';
+import {handleEmbedAlignmentChanges} from './fixes';
const styleFormats = [
{title: 'Large Header', format: 'h2', preview: 'color: blue;'},
];
const formats = {
- alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-left'},
- aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-center'},
- alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'},
+ alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img,iframe,video,span', classes: 'align-left'},
+ aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img,iframe,video,span', classes: 'align-center'},
+ alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img,iframe,video,span', classes: 'align-right'},
calloutsuccess: {block: 'p', exact: true, attributes: {class: 'callout success'}},
calloutinfo: {block: 'p', exact: true, attributes: {class: 'callout info'}},
calloutwarning: {block: 'p', exact: true, attributes: {class: 'callout warning'}},
setupFilters(editor);
});
+ handleEmbedAlignmentChanges(editor);
+
// Custom handler hook
window.$events.emitPublic(options.containerElement, 'editor-tinymce::setup', {editor});
--- /dev/null
+/**
+ * Handle alignment for embed (iframe/video) content.
+ * TinyMCE built-in handling doesn't work well for these when classes are used for
+ * alignment, since the editor wraps these elements in a non-editable preview span
+ * which looses tracking and setting of alignment options.
+ * Here we manually manage these properties and formatting events, by effectively
+ * syncing the alignment classes to the parent preview span.
+ * @param {Editor} editor
+ */
+export function handleEmbedAlignmentChanges(editor) {
+ function updateClassesForPreview(previewElem) {
+ const mediaTarget = previewElem.querySelector('iframe, video');
+ if (!mediaTarget) {
+ return;
+ }
+
+ const alignmentClasses = [...mediaTarget.classList.values()].filter(c => c.startsWith('align-'));
+ const previewAlignClasses = [...previewElem.classList.values()].filter(c => c.startsWith('align-'));
+ previewElem.classList.remove(...previewAlignClasses);
+ previewElem.classList.add(...alignmentClasses);
+ }
+
+ editor.on('SetContent', () => {
+ const previewElems = editor.dom.select('span.mce-preview-object');
+ for (const previewElem of previewElems) {
+ updateClassesForPreview(previewElem);
+ }
+ });
+
+ editor.on('FormatApply', event => {
+ const isAlignment = event.format.startsWith('align');
+ if (!event.node || !event.node.matches('.mce-preview-object')) {
+ return;
+ }
+
+ const realTarget = event.node.querySelector('iframe, video');
+ if (isAlignment && realTarget) {
+ const className = (editor.formatter.get(event.format)[0]?.classes || [])[0];
+ const toAdd = !realTarget.classList.contains(className);
+
+ const wrapperClasses = (event.node.getAttribute('data-mce-p-class') || '').split(' ');
+ const wrapperClassesFiltered = wrapperClasses.filter(c => !c.startsWith('align-'));
+ if (toAdd) {
+ wrapperClassesFiltered.push(className);
+ }
+
+ const classesToApply = wrapperClassesFiltered.join(' ');
+ event.node.setAttribute('data-mce-p-class', classesToApply);
+
+ realTarget.setAttribute('class', classesToApply);
+ editor.formatter.apply(event.format, {}, realTarget);
+ updateClassesForPreview(event.node);
+ }
+ });
+}
.align-left {
text-align: left;
}
- img.align-left, table.align-left {
+ img.align-left, table.align-left, iframe.align-left, video.align-left {
float: left !important;
margin: $-xs $-m $-m 0;
}
.align-right {
text-align: right !important;
}
- img.align-right, table.align-right {
+ img.align-right, table.align-right, iframe.align-right, video.align-right {
float: right !important;
margin: $-xs 0 $-xs $-s;
}
.align-center {
text-align: center;
}
- img.align-center {
+ img.align-center, video.align-center, iframe.align-center {
display: block;
}
- img.align-center, table.align-center {
+ img.align-center, table.align-center, iframe.align-center, video.align-center {
margin-left: auto;
margin-right: auto;
}