Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented a Tooltip plugin to handle the JS-driven tooltip system across the UI #12262

Merged
merged 35 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f09562c
Implemented a Tooltip plugin to handle the JS-driven tooltip system a…
oleq Aug 11, 2022
002c96b
Used new tootlip API in media embed previews.
oleq Aug 11, 2022
3276f46
Code refactoring.
oleq Aug 11, 2022
0a74442
Merge branch 'master' into ck/12067-button-tooltips-for-keyboard
oleq Aug 16, 2022
877fcd6
Adjusted the size of the tip of a tooltip to move it closed to the item.
oleq Aug 16, 2022
3ce12b8
Made the delay before the tooltip shows up longer for less distraction.
oleq Aug 16, 2022
db836e2
The tooltip should move along with the content (toolbar) when collabo…
oleq Aug 16, 2022
6a84103
Moved the logic that delays the tooltip from CSS to JS to make sure i…
oleq Aug 16, 2022
55e1f0e
Hide the split button's arrow tooltip when the dropdown gets open.
oleq Aug 16, 2022
1637a53
Set the right horizontal offset for the tooltip balloon for accuracy …
oleq Aug 16, 2022
716ec2f
Hide tooltips on scrolling in the document.
oleq Aug 16, 2022
88f7a7b
Tooltip plugin has become a helper class in EditorUI.
oleq Aug 17, 2022
14c3ea6
Tests: Added TooltipManager tests.
oleq Aug 17, 2022
c9d6493
Tests: Added tests for westArrowEast and eastArrowWest positions.
oleq Aug 17, 2022
d223766
TooltipManager should cancel queued pinning when destroyed.
oleq Aug 17, 2022
89f78f4
Aligned ButtonView to the new tooltip system that does not depend on …
oleq Aug 17, 2022
10a0c3d
Used data-cke-tooltip-disabled attribute instead of .ck-tooltip_hidde…
oleq Aug 17, 2022
7fefb62
Aligned media embed tests to the new tooltips API.
oleq Aug 17, 2022
fbed194
Make sure tooltips are *really* on top of everything.
oleq Aug 17, 2022
3dbb81e
Allowed setting custom tooltip class via data-cke-tooltip-class attri…
oleq Aug 17, 2022
dd54379
Docs and code refactoring.
oleq Aug 17, 2022
5e06812
Docs.
oleq Aug 17, 2022
bb2f259
Tests: Improved manual test for TooltipManager.
oleq Aug 18, 2022
a07e8f1
Removed obsolete CSS that no longer applies to the new tooltip implem…
oleq Aug 18, 2022
423fd2b
Improved positioning of balloons and tooltips.
oleq Aug 18, 2022
d912cfd
Made TooltipManager a singleton loaded by EditorUI to avoid duplicate…
oleq Aug 18, 2022
e863ffd
Code refactoring in tooltip CSS.
oleq Aug 18, 2022
ebf9e79
Renamed BalloonPanelView.arrowVertical offset to heightOffset and arr…
oleq Aug 18, 2022
053764b
Docs.
oleq Aug 18, 2022
6ea5bf4
(Hack) Excluded the TooltipManager singleton from the ContextWatchdog…
oleq Aug 18, 2022
50c0801
Documented the changes made ContextWatchdog in order to handle the To…
oleq Aug 19, 2022
21c6e4a
Docs.
oleq Aug 19, 2022
45a23c1
Merge branch 'master' into ck/12067-button-tooltips-for-keyboard
oleq Aug 22, 2022
cee9529
Tests: Made TooltipManager tests independent from the rest of the suite.
oleq Aug 22, 2022
04288fa
Misc. fixes
arkflpc Aug 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/ckeditor5-core/src/editor/editorui.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';
import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
import TooltipManager from '@ckeditor/ckeditor5-ui/src/tooltipmanager';

import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
import mix from '@ckeditor/ckeditor5-utils/src/mix';
Expand Down Expand Up @@ -54,6 +55,14 @@ export default class EditorUI {
*/
this.focusTracker = new FocusTracker();

/**
* Manages the tooltips displayed on mouseover and focus across the UI.
*
* @readonly
* @member {module:ui/tooltipmanager~TooltipManager}
*/
this.tooltipManager = new TooltipManager( editor );

/**
* Stores viewport offsets from every direction.
*
Expand Down Expand Up @@ -157,6 +166,7 @@ export default class EditorUI {
this.stopListening();

this.focusTracker.destroy();
this.tooltipManager.destroy( this.editor );

// Clean–up the references to the CKEditor instance stored in the native editable DOM elements.
for ( const domElement of this._editableElementsMap.values() ) {
Expand Down
24 changes: 23 additions & 1 deletion packages/ckeditor5-core/tests/editor/editorui.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import EditorUI from '../../src/editor/editorui';
import Editor from '../../src/editor/editor';

import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';
import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
import TooltipManager from '@ckeditor/ckeditor5-ui/src/tooltipmanager';

import testUtils from '../_utils/utils';

Expand Down Expand Up @@ -42,6 +43,10 @@ describe( 'EditorUI', () => {
expect( ui.focusTracker ).to.be.instanceOf( FocusTracker );
} );

it( 'should create #tooltipManager', () => {
expect( ui.tooltipManager ).to.be.instanceOf( TooltipManager );
} );

it( 'should have #element getter', () => {
expect( ui.element ).to.null;
} );
Expand Down Expand Up @@ -121,6 +126,23 @@ describe( 'EditorUI', () => {
expect( fooElement.ckeditorInstance ).to.be.null;
expect( barElement.ckeditorInstance ).to.be.null;
} );

it( 'should destroy #focusTracker', () => {
const destroySpy = sinon.spy( ui.focusTracker, 'destroy' );

ui.destroy();

sinon.assert.calledOnce( destroySpy );
} );

it( 'should destroy #tooltipManager', () => {
const destroySpy = sinon.spy( ui.tooltipManager, 'destroy' );

ui.destroy();

sinon.assert.calledOnce( destroySpy );
sinon.assert.calledWithExactly( destroySpy, editor );
} );
} );

describe( 'setEditableElement()', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ The HTML structure of every non-previewable media in the editor is as follows:
</div>
<a class="ck-media__placeholder__url" target="new" href="[ URL of the media]">
<span class="ck-media__placeholder__url__text">[ URL of the media]</span>
<span class="ck ck-tooltip ck-tooltip_s">...</span>
</a>
</div>
</div>
Expand Down
13 changes: 6 additions & 7 deletions packages/ckeditor5-media-embed/src/mediaregistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @module media-embed/mediaregistry
*/

import { TooltipView, IconView, Template } from 'ckeditor5/src/ui';
import { IconView, Template } from 'ckeditor5/src/ui';
import { logWarning, toArray } from 'ckeditor5/src/utils';

import mediaPlaceholderIcon from '../theme/icons/media-placeholder.svg';
Expand Down Expand Up @@ -185,7 +185,7 @@ class Media {
* @see module:utils/locale~Locale#t
* @method
*/
this._t = locale.t;
this._locale = locale;

/**
* The output of the `RegExp.match` which validated the {@link #url} of this media.
Expand Down Expand Up @@ -271,10 +271,9 @@ class Media {
* @returns {String}
*/
_getPlaceholderHtml() {
const tooltip = new TooltipView();
const icon = new IconView();
const t = this._locale.t;

tooltip.text = this._t( 'Open media in new tab' );
icon.content = mediaPlaceholderIcon;
icon.viewBox = mediaPlaceholderIconViewBox;

Expand All @@ -297,7 +296,8 @@ class Media {
class: 'ck-media__placeholder__url',
target: '_blank',
rel: 'noopener noreferrer',
href: this.url
href: this.url,
'data-cke-tooltip-text': t( 'Open media in new tab' )
},
children: [
{
Expand All @@ -306,8 +306,7 @@ class Media {
class: 'ck-media__placeholder__url__text'
},
children: [ this.url ]
},
tooltip
}
]
}
]
Expand Down
13 changes: 8 additions & 5 deletions packages/ckeditor5-media-embed/tests/mediaembedediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -1272,11 +1272,14 @@ describe( 'MediaEmbedEditing', () => {
'<div[^>]+>' +
'<div class="ck ck-media__placeholder ck-reset_all">' +
'<div class="ck-media__placeholder__icon">.*</div>' +
`<a class="ck-media__placeholder__url" href="${ expectedUrl }" rel="noopener noreferrer" target="_blank">` +
`<span class="ck-media__placeholder__url__text">${ expectedUrl }</span>` +
'<span class="ck ck-tooltip ck-tooltip_s">' +
'<span class="ck ck-tooltip__text">Open media in new tab</span>' +
'</span>' +
'<a ' +
'class="ck-media__placeholder__url" ' +
'data-cke-tooltip-text="Open media in new tab" ' +
`href="${ expectedUrl }" ` +
'rel="noopener noreferrer" ' +
'target="_blank"' +
'>' +
`<span class="ck-media__placeholder__url__text">${ expectedUrl }</span>` +
'</a>' +
'</div>' +
'</div>' +
Expand Down
8 changes: 0 additions & 8 deletions packages/ckeditor5-media-embed/theme/mediaembedediting.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,18 @@
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

@import "@ckeditor/ckeditor5-ui/theme/components/tooltip/mixins/_tooltip.css";

.ck-media__wrapper {
& .ck-media__placeholder {
display: flex;
flex-direction: column;
align-items: center;

& .ck-media__placeholder__url {
@mixin ck-tooltip_enabled;

/* Otherwise the URL will overflow when the content is very narrow. */
max-width: 100%;

position: relative;

&:hover {
@mixin ck-tooltip_visible;
}

& .ck-media__placeholder__url__text {
overflow: hidden;
display: block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

@import "@ckeditor/ckeditor5-ui/theme/components/tooltip/mixins/_tooltip.css";
@import "@ckeditor/ckeditor5-ui/theme/mixins/_unselectable.css";
@import "@ckeditor/ckeditor5-ui/theme/mixins/_dir.css";
@import "../mixins/_focus.css";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@import "../../../mixins/_shadow.css";

:root {
--ck-balloon-border-width: 1px;
--ck-balloon-arrow-offset: 2px;
--ck-balloon-arrow-height: 10px;
--ck-balloon-arrow-half-width: 8px;
Expand All @@ -20,7 +21,7 @@
min-height: 15px;

background: var(--ck-color-panel-background);
border: 1px solid var(--ck-color-panel-border);
border: var(--ck-balloon-border-width) solid var(--ck-color-panel-border);

&.ck-balloon-panel_with-arrow {
&::before,
Expand All @@ -39,11 +40,12 @@

&::before {
border-color: transparent transparent var(--ck-color-panel-border) transparent;
margin-top: calc( -1 * var(--ck-balloon-border-width) );
}

&::after {
border-color: transparent transparent var(--ck-color-panel-background) transparent;
margin-top: var(--ck-balloon-arrow-offset);
margin-top: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) );
}
}

Expand All @@ -56,11 +58,46 @@
&::before {
border-color: var(--ck-color-panel-border) transparent transparent;
filter: drop-shadow(var(--ck-balloon-arrow-drop-shadow));
margin-bottom: calc( -1 * var(--ck-balloon-border-width) );
}

&::after {
border-color: var(--ck-color-panel-background) transparent transparent transparent;
margin-bottom: var(--ck-balloon-arrow-offset);
margin-bottom: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) );
}
}

&[class*="arrow_e"] {
&::before,
&::after {
border-width: var(--ck-balloon-arrow-half-width) 0 var(--ck-balloon-arrow-half-width) var(--ck-balloon-arrow-height);
}

&::before {
border-color: transparent transparent transparent var(--ck-color-panel-border);
margin-right: calc( -1 * var(--ck-balloon-border-width) );
}

&::after {
border-color: transparent transparent transparent var(--ck-color-panel-background);
margin-right: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) );
}
}

&[class*="arrow_w"] {
&::before,
&::after {
border-width: var(--ck-balloon-arrow-half-width) var(--ck-balloon-arrow-height) var(--ck-balloon-arrow-half-width) 0;
}

&::before {
border-color: transparent var(--ck-color-panel-border) transparent transparent;
margin-left: calc( -1 * var(--ck-balloon-border-width) );
}

&::after {
border-color: transparent var(--ck-color-panel-background) transparent transparent;
margin-left: calc( var(--ck-balloon-arrow-offset) - var(--ck-balloon-border-width) );
}
}

Expand Down Expand Up @@ -149,4 +186,22 @@
top: calc(-1 * var(--ck-balloon-arrow-height));
}
}

&.ck-balloon-panel_arrow_e {
&::before,
&::after {
right: calc(-1 * var(--ck-balloon-arrow-height));
margin-top: calc(-1 * var(--ck-balloon-arrow-half-width));
top: 50%;
}
}

&.ck-balloon-panel_arrow_w {
&::before,
&::after {
left: calc(-1 * var(--ck-balloon-arrow-height));
margin-top: calc(-1 * var(--ck-balloon-arrow-half-width));
top: 50%;
}
}
}
Loading