From 4e102c0b3d0e5e9c40aff1f19610a08fe0b12300 Mon Sep 17 00:00:00 2001 From: MitchCTiny Date: Wed, 14 Sep 2022 09:56:34 +1000 Subject: [PATCH] TINY-8978: Backport fix for notifications in fullscreen (#8121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 Co-authored-by: Lee Newson --- modules/tinymce/CHANGELOG.md | 2 + .../core/main/ts/api/dom/ControlSelection.ts | 2 +- .../plugins/fullscreen/main/ts/api/Events.ts | 1 + .../test/ts/browser/FullScreenPluginTest.ts | 89 +++++++++++++++---- .../ts/browser/settings/TableGridFalseTest.ts | 5 +- 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/modules/tinymce/CHANGELOG.md b/modules/tinymce/CHANGELOG.md index 99e3d8559ca..726d8a18683 100644 --- a/modules/tinymce/CHANGELOG.md +++ b/modules/tinymce/CHANGELOG.md @@ -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 diff --git a/modules/tinymce/src/core/main/ts/api/dom/ControlSelection.ts b/modules/tinymce/src/core/main/ts/api/dom/ControlSelection.ts index dfd526114c8..45a31a60bd5 100644 --- a/modules/tinymce/src/core/main/ts/api/dom/ControlSelection.ts +++ b/modules/tinymce/src/core/main/ts/api/dom/ControlSelection.ts @@ -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) => { diff --git a/modules/tinymce/src/plugins/fullscreen/main/ts/api/Events.ts b/modules/tinymce/src/plugins/fullscreen/main/ts/api/Events.ts index 31cd71e5d97..a094e2c4e53 100644 --- a/modules/tinymce/src/plugins/fullscreen/main/ts/api/Events.ts +++ b/modules/tinymce/src/plugins/fullscreen/main/ts/api/Events.ts @@ -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 { diff --git a/modules/tinymce/src/plugins/fullscreen/test/ts/browser/FullScreenPluginTest.ts b/modules/tinymce/src/plugins/fullscreen/test/ts/browser/FullScreenPluginTest.ts index f0993fd462e..a27f74c6fec 100644 --- a/modules/tinymce/src/plugins/fullscreen/test/ts/browser/FullScreenPluginTest.ts +++ b/modules/tinymce/src/plugins/fullscreen/test/ts/browser/FullScreenPluginTest.ts @@ -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))); @@ -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) => { @@ -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; + 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 } @@ -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 ]); @@ -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({ + plugins: 'fullscreen link', + base_url: '/project/tinymce/js/tinymce' + }); + editor.execCommand('mceFullScreen'); assertPageState(editor, true); - editor.remove(); + McEditor.remove(editor); assertHtmlAndBodyState(editor, false); }); }); diff --git a/modules/tinymce/src/plugins/table/test/ts/browser/settings/TableGridFalseTest.ts b/modules/tinymce/src/plugins/table/test/ts/browser/settings/TableGridFalseTest.ts index 903a69278bd..9298dffae39 100644 --- a/modules/tinymce/src/plugins/table/test/ts/browser/settings/TableGridFalseTest.ts +++ b/modules/tinymce/src/plugins/table/test/ts/browser/settings/TableGridFalseTest.ts @@ -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'; @@ -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', {