Skip to content

Commit

Permalink
TINY-8978: Backport fix for notifications in fullscreen (#8121)
Browse files Browse the repository at this point in the history
* TINY-8701: Ensure fullscreen fires a ResizeEditor event (#7819)

* TINY-9098: Fixed test that was failing on Chrome v105

* TINY-8978: Review fixes

TINY-8978: Remove TinyContentActions

TINY-8978: Update changelog

Co-authored-by: Hannes Frimmel Moström <hannes.mostrom@tiny.cloud>
Co-authored-by: Lee Newson <lee.newson@tiny.cloud>
  • Loading branch information
3 people committed Sep 13, 2022
1 parent 64f16eb commit 4e102c0
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 18 deletions.
2 changes: 2 additions & 0 deletions modules/tinymce/CHANGELOG.md
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed
- The `name` and `id` attributes of some elements were incorrectly removed during serialization #TINY-8773
- Notifications would not properly reposition when toggling fullscreen mode #TINY-8701
- Toggling fullscreen mode with the `fullscreen` plugin now also fires the `ResizeEditor` event #TINY-8701

## 5.10.5 - 2022-05-25

Expand Down
Expand Up @@ -541,7 +541,7 @@ const ControlSelection = (selection: EditorSelection, editor: Editor): ControlSe
}
});

editor.on('nodechange ResizeEditor ResizeWindow ResizeContent drop FullscreenStateChanged', throttledUpdateResizeRect);
editor.on('NodeChange ResizeEditor ResizeWindow ResizeContent drop', throttledUpdateResizeRect);

// Update resize rect while typing in a table
editor.on('keyup compositionend', (e) => {
Expand Down
Expand Up @@ -9,6 +9,7 @@ import Editor from 'tinymce/core/api/Editor';

const fireFullscreenStateChanged = (editor: Editor, state: boolean): void => {
editor.fire('FullscreenStateChanged', { state });
editor.fire('ResizeEditor');
};

export {
Expand Down
@@ -1,17 +1,22 @@
import { UiFinder } from '@ephox/agar';
import { context, describe, it } from '@ephox/bedrock-client';
import { Arr, Cell } from '@ephox/katamari';
import { Attribute, Classes, Css, Html, SelectorFind, SugarBody, SugarDocument, SugarShadowDom, Traverse } from '@ephox/sugar';
import { TinyDom, TinyHooks, TinyUiActions } from '@ephox/wrap-mcagar';
import { afterEach, context, describe, it } from '@ephox/bedrock-client';
import { Arr, Type } from '@ephox/katamari';
import { Attribute, Classes, Css, Html, SelectorFind, SugarBody, SugarDocument, SugarElement, SugarShadowDom, Traverse } from '@ephox/sugar';
import { McEditor, TinyDom, TinyHooks, TinyUiActions } from '@ephox/wrap-mcagar';
import { assert } from 'chai';

import Editor from 'tinymce/core/api/Editor';
import { NotificationApi } from 'tinymce/core/api/NotificationManager';
import FullscreenPlugin from 'tinymce/plugins/fullscreen/Plugin';
import LinkPlugin from 'tinymce/plugins/link/Plugin';
import Theme from 'tinymce/themes/silver/Theme';

describe('browser.tinymce.plugins.fullscreen.FullScreenPluginTest', () => {
const lastEventArgs = Cell(null);
let firedEvents: string[] = [];

afterEach(() => {
firedEvents = [];
});

const getContentContainer = (editor: Editor) =>
SugarShadowDom.getContentContainer(SugarShadowDom.getRootNode(TinyDom.targetElement(editor)));
Expand All @@ -34,9 +39,9 @@ describe('browser.tinymce.plugins.fullscreen.FullScreenPluginTest', () => {
}
};

const assertApiAndLastEvent = (editor: Editor, state: boolean) => {
const assertApiAndEvents = (editor: Editor, state: boolean) => {
assert.equal(editor.plugins.fullscreen.isFullscreen(), state, 'Editor isFullscreen state');
assert.equal(lastEventArgs.get().state, state, 'FullscreenStateChanged event state');
assert.deepEqual(firedEvents, [ 'fullscreenstatechanged:' + state, 'resizeeditor' ], 'Should be expected events and state');
};

const assertHtmlAndBodyState = (editor: Editor, shouldExist: boolean) => {
Expand Down Expand Up @@ -74,6 +79,25 @@ describe('browser.tinymce.plugins.fullscreen.FullScreenPluginTest', () => {
assertShadowHostState(editor, shouldExist);
};

const createNotification = (editor: Editor) =>
editor.notificationManager.open({
text: 'This is an informational notification.',
type: 'info'
});

const getNotificationPosition = (notification: NotificationApi) => {
const elem = Traverse.parent(SugarElement.fromDom(notification.getEl())).getOrDie() as SugarElement<HTMLElement>;
return {
top: elem.dom.offsetTop,
left: elem.dom.offsetLeft
};
};

const assertPositionChanged = (notification: NotificationApi, oldPos: { left: number; top: number }) => {
const position = getNotificationPosition(notification);
assert.isFalse(position.top === oldPos.top && position.left === oldPos.left, 'Notification position not updated as expected');
};

Arr.each([
{ label: 'Iframe Editor', setup: TinyHooks.bddSetup },
{ label: 'Shadow Dom Editor', setup: TinyHooks.bddSetupInShadowRoot }
Expand All @@ -83,9 +107,13 @@ describe('browser.tinymce.plugins.fullscreen.FullScreenPluginTest', () => {
plugins: 'fullscreen link',
base_url: '/project/tinymce/js/tinymce',
setup: (editor: Editor) => {
lastEventArgs.set(null);
editor.on('FullscreenStateChanged', (e: Editor) => {
lastEventArgs.set(e);
firedEvents = [];
editor.on('FullscreenStateChanged ResizeEditor', (e: any) => {
if (Type.isBoolean(e.state)) {
firedEvents.push(`${e.type}:${e.state}`);
} else {
firedEvents.push(e.type);
}
});
}
}, [ FullscreenPlugin, LinkPlugin, Theme ]);
Expand All @@ -94,23 +122,54 @@ describe('browser.tinymce.plugins.fullscreen.FullScreenPluginTest', () => {
const editor = hook.editor();
assertPageState(editor, false);
editor.execCommand('mceFullScreen');
assertApiAndLastEvent(editor, true);
assertApiAndEvents(editor, true);
firedEvents = [];
assertPageState(editor, true);
editor.execCommand('mceLink');
await pWaitForDialog(editor, 'Insert/Edit Link');
closeOnlyWindow(editor);
assertPageState(editor, true);
editor.execCommand('mceFullScreen');
assertApiAndLastEvent(editor, false);
assertApiAndEvents(editor, false);
assertPageState(editor, false);
});

it('TBA: Toggle fullscreen and cleanup editor should clean up classes', () => {
it('TINY-8701: notifications are properly updated when notification is created before fullscreen', () => {
const editor = hook.editor();
const notification = createNotification(editor);
const positions = getNotificationPosition(notification);
editor.execCommand('mceFullScreen');
assertPositionChanged(notification, positions);
notification.close();
assertApiAndEvents(editor, true);
assertPageState(editor, true);
editor.execCommand('mceFullScreen');
});

it('TINY-8701: notifications are properly updated when notification is created after fullscreen', () => {
const editor = hook.editor();
editor.execCommand('mceFullScreen');
assertApiAndLastEvent(editor, true);
firedEvents = [];
const notification = createNotification(editor);
const positions = getNotificationPosition(notification);
editor.execCommand('mceFullScreen');
assertPositionChanged(notification, positions);
notification.close();
assertApiAndEvents(editor, false);
assertPageState(editor, false);
});
});

context(tester.label + ', removal test', () => {
// This test removes the editor. No tests can or should be added after this test.
it('TBA: Toggle fullscreen and cleanup editor should clean up classes', async () => {
const editor = await McEditor.pFromSettings<Editor>({
plugins: 'fullscreen link',
base_url: '/project/tinymce/js/tinymce'
});
editor.execCommand('mceFullScreen');
assertPageState(editor, true);
editor.remove();
McEditor.remove(editor);
assertHtmlAndBodyState(editor, false);
});
});
Expand Down
@@ -1,4 +1,4 @@
import { Assertions, Waiter } from '@ephox/agar';
import { Assertions, UiFinder, Waiter } from '@ephox/agar';
import { describe, it } from '@ephox/bedrock-client';
import { TinyHooks, TinyUiActions } from '@ephox/wrap-mcagar';

Expand All @@ -19,7 +19,8 @@ describe('browser.tinymce.plugins.table.TableGridFalse', () => {
await Waiter.pTryUntil('click table menu', () =>
TinyUiActions.clickOnUi(editor, 'div.tox-menu div.tox-collection__item .tox-collection__item-label:contains("Table")')
);
const dialog = await TinyUiActions.pWaitForDialog(editor, 'div.tox-dialog:has(div.tox-dialog__title:contains("Table Properties"))');
const dialog = await TinyUiActions.pWaitForDialog(editor);
UiFinder.exists(dialog, 'div.tox-dialog__title:contains("Table Properties")');
Assertions.assertPresence(
'assert presence of col and row input',
{
Expand Down

0 comments on commit 4e102c0

Please sign in to comment.