Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

i/5597: Set balloon toolbar's max-width #536

Merged
merged 100 commits into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
bb78e2e
Fix: Set balloon toolbar's max-width to be half of the editable's wid…
panr Jan 14, 2020
82747ef
Tests: Add scenario for a setting toolbar max-width
panr Jan 15, 2020
085c255
Tests: Add scenario to test if toolbar will group items
panr Jan 15, 2020
ac3c31f
Fix: Refactor setting max-width for toolbar as a private method for t…
panr Jan 15, 2020
69560b9
Add maxWidth observable to ToolbarView class
panr Jan 22, 2020
438d844
Refactor toolbar view maxWidth binding
panr Jan 23, 2020
f630220
Move setting toolbar max-width to initializer instead of running it w…
panr Jan 23, 2020
56d7300
Add test for toolbar max-width binding
panr Jan 23, 2020
aaa73fe
Change test for setting balloon toolbar max-width
panr Jan 23, 2020
fd6151a
Refactor access to balloon toolbar config and pass down shouldGroupWh…
panr Jan 23, 2020
d44f716
Add test for checking if grouping items can be disabled from balloon …
panr Jan 23, 2020
08a5058
Increase test timeout while waiting for ResizeObserver
panr Jan 23, 2020
bb97620
Add _enableGroupingOnMaxWidthChange() private method
panr Jan 29, 2020
b3da94f
Update ToolbarView#maxWidth observable with note describing how it ma…
panr Jan 30, 2020
fcc0e29
Fix ballon toolbar code
panr Jan 30, 2020
8e04fe0
Remove obsolete test from ToolbarView tests
panr Jan 30, 2020
6f9eeae
Fix balloon toolbar tests
panr Jan 30, 2020
a316c8d
Add "ck-balloon-toolbar_min-width" class to set default min-width for…
panr Feb 6, 2020
8e4882e
Use ResizeObserver class instead of getResizeObserver helper
panr Feb 21, 2020
09475dc
Make notifications context plugin.
Nov 7, 2019
ffa11c3
Export body collection to the separate file.
Nov 8, 2019
6523052
Applied changes to the body collection API.
Nov 13, 2019
61c5246
Removed console.log.
Nov 13, 2019
4a248ce
Fix broken import.
Nov 19, 2019
38ffe70
Tests: introduce tests for body collection. Update tests broken after…
Nov 20, 2019
872cfcc
Docs: added API docs to the body collection.
Nov 20, 2019
74b6034
Renamed attachToDOM() to attachToDom().
oskarwrobel Dec 19, 2019
7599547
Renamed detachFromDOM() to detachFromDom().
oskarwrobel Dec 19, 2019
9edbdc2
Docs improvements.
oskarwrobel Dec 19, 2019
3ffa6b8
Docs improvements.
oskarwrobel Dec 19, 2019
70c867b
Docs improvements.
oskarwrobel Dec 19, 2019
de73f72
Docs improvements.
oskarwrobel Dec 19, 2019
e577621
Docs improvements.
oskarwrobel Dec 19, 2019
9db89a5
Brought LabeledView. Aligned DropdownView to LabeledView interface.
oleq Jan 14, 2020
59f588f
Added styles for LabeledView.
oleq Jan 14, 2020
949a577
Minor API docs corrections.
Reinmar Jan 16, 2020
34e5189
Internal: Updated new license headers.
Reinmar Jan 16, 2020
672697c
Docs: LabeledView docs.
oleq Jan 16, 2020
3822783
Tests: Added tests for DropdownView#id.
oleq Jan 20, 2020
dcfef67
Tests: Added tests for LabelView#id.
oleq Jan 20, 2020
153449a
Tests: Added tests for the LabeledView class.
oleq Jan 20, 2020
2dee198
Tests: Added tests for LabeledView utils. Added some docs.
oleq Jan 20, 2020
4455327
Aligned BoxedEditorUIView to the new LabelView API.
oleq Jan 20, 2020
0de45e5
Code clean-up.
oleq Jan 21, 2020
c66a579
Docs: Fixed a broken link.
oleq Jan 22, 2020
1498ef2
Fix invalid self imports.
jodator Jan 24, 2020
e31e110
Remove empty afterEach() from labeled input view utils tests.
jodator Jan 24, 2020
e14a9a6
Update src/labeledview/utils.js
jodator Jan 24, 2020
dccfa9a
Internal: Aligned the ToolbarView class (and tests) to the ResizeObse…
oleq Jan 28, 2020
9e27b73
Added the ToolbarView#isCompact property.
oleq Jan 29, 2020
b657ccd
Tests: Added tests for ToolbarView#isCompact.
oleq Jan 30, 2020
72f7c1d
Tests: Fixed failing ToolbarView tests due to interactions with other…
oleq Feb 7, 2020
5b39d04
Docs: Body collection API docs corrected. [skip ci]
AnnaTomanek Feb 7, 2020
638c572
Add #withArrow param to DropdownButtonView
panr Feb 10, 2020
a9b1482
Add safeguard for "hasBorder" option
panr Feb 10, 2020
6e84a6e
Add ColorInputView
panr Feb 10, 2020
6d7f3ae
Code refactoring.
oleq Feb 10, 2020
6ecc076
Move some of the font color utils to the color grid utils
panr Feb 11, 2020
f2772db
Move some of the font utils tests to color grid utils tests
panr Feb 11, 2020
6a9c665
Remove color input files from ui
panr Feb 11, 2020
88ada61
Reverted changes made to ColorGridView.
oleq Feb 11, 2020
cca93b2
Tests: Added tests for the getLocalizedColorOptions() helper.
oleq Feb 11, 2020
b378326
Docs: Added headers to the colorgrid utils module.
oleq Feb 11, 2020
60b878e
Moved the normalizeColorCode helper back to ckeditor5-font.
oleq Feb 12, 2020
88e2f4e
Fix invalid self-import.
jodator Feb 12, 2020
f24a196
Other: Updated translations. [skip ci]
mlewand Feb 13, 2020
be21634
Other: Reverted year 2020 in .po files license header. [skip ci]
mlewand Feb 13, 2020
e22b92a
Fix translations contexts
panr Feb 13, 2020
d922f70
Internal: Adjusted color context descriptions. [skip ci]
mlewand Feb 13, 2020
164b78a
Internal: Optimzied the SVG icons for size. [skip ci]
oleq Feb 13, 2020
993d9c5
Docs: Changelog. [skip ci]
Reinmar Feb 19, 2020
e6b800a
Docs: Corrected the changelog. [skip ci]
Reinmar Feb 19, 2020
58014f1
Internal: Updated dependencies. [skip ci]
mlewand Feb 20, 2020
0bfeb4d
Release: v17.0.0. [skip ci]
mlewand Feb 20, 2020
3aa9833
Add additional postions for anchoring the balloon
panr Feb 24, 2020
9f69492
Remove redundant invocation of resizeObserver.destroy()
panr Feb 24, 2020
7ebdea3
Change balloon toolbar max-width to 90% of editable's width and add `…
panr Feb 24, 2020
eebfe70
Update ballonpanelview tests
panr Feb 24, 2020
0012531
Update balloontoolbar tests
panr Feb 24, 2020
e255a4c
Merge branch master into i/5597
panr Feb 24, 2020
b7ddada
Merge branch 'master' into i/5597
panr Feb 24, 2020
733e30a
Changed the order of default positions used by BalloonPanelView#attac…
oleq Feb 25, 2020
d069d43
Tests: Stabilized the BalloonToolbar that checks items grouping to ma…
oleq Feb 25, 2020
a58ac73
Fix northArrowSouthMiddleWest calculations & rearrange balloonpanelvi…
panr Feb 25, 2020
763e13c
Make resizeObserver protected value
panr Feb 25, 2020
c8ea412
Remove setting min-width class for balloontoolbar and related test as…
panr Feb 25, 2020
24840cb
Fix docs for ToolbarView API
panr Feb 26, 2020
3d5b192
Fix manual test helpers for balloonpanelview
panr Feb 26, 2020
684123c
Fix typo
panr Feb 26, 2020
c2faec9
Remove `.ck-balloon-toolbar_min-width` class from theme css
panr Feb 26, 2020
276e9a0
Fix comma dangles
panr Feb 26, 2020
1c4eb28
Docs: Fixed typos in BalloonPanelView.defaultPositions docs.
oleq Feb 26, 2020
d339b70
Reverted changes to BalloonPanelViews tests made in 733e30acee35.
oleq Feb 26, 2020
964995c
Remove unnecessary checking for editableElement since we use new Resi…
panr Feb 26, 2020
79f7cd1
Tests: Improved the readability of the balloon panel view positioning…
oleq Feb 26, 2020
56cfbe8
Docs and code refactoring in BalloonPanelView and BalloonToolbar clas…
oleq Feb 26, 2020
3c39173
Docs: Improved docs of the ToolbarView class.
oleq Feb 26, 2020
8142f58
Docs: Improved the dev docs in the BalloonToolbar plugin.
oleq Feb 26, 2020
85651a9
Tests: Code refactoring in BalloonPanelView tests.
oleq Feb 26, 2020
0395c4f
Tests: Minor naming improvement in the BalloonToolbar test.
oleq Feb 26, 2020
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
407 changes: 295 additions & 112 deletions src/panel/balloon/balloonpanelview.js

Large diffs are not rendered by default.

77 changes: 72 additions & 5 deletions src/toolbar/balloon/balloontoolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';
import normalizeToolbarConfig from '../normalizetoolbarconfig';
import { debounce } from 'lodash-es';
import ResizeObserver from '@ckeditor/ckeditor5-utils/src/dom/resizeobserver';
import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';

const toPx = toUnit( 'px' );

/**
* The contextual toolbar.
Expand Down Expand Up @@ -44,6 +48,14 @@ export default class BalloonToolbar extends Plugin {
constructor( editor ) {
super( editor );

/**
* A cached and normalized `config.balloonToolbar` object.
*
* @type {module:core/editor/editorconfig~EditorConfig#balloonToolbar}
* @private
*/
this._balloonConfig = normalizeToolbarConfig( editor.config.get( 'balloonToolbar' ) );

/**
* The toolbar view displayed in the balloon.
*
Expand All @@ -66,6 +78,20 @@ export default class BalloonToolbar extends Plugin {
this.focusTracker.add( this.toolbarView.element );
} );

/**
* An instance of the resize observer that allows to respond to changes in editable's geometry
* so the toolbar can stay within its boundaries (and group toolbar items that do not fit).
*
* **Note**: Used only when `shouldNotGroupWhenFull` was **not** set in the
* {@link module:core/editor/editorconfig~EditorConfig#balloonToolbar configuration}.
*
* **Note:** Created in {@link #init}.
*
* @protected
* @member {module:utils/dom/resizeobserver~ResizeObserver}
*/
this._resizeObserver = null;

/**
* The contextual balloon plugin instance.
*
Expand Down Expand Up @@ -125,6 +151,20 @@ export default class BalloonToolbar extends Plugin {
this.show();
}
} );

if ( !this._balloonConfig.shouldNotGroupWhenFull ) {
this.listenTo( editor, 'ready', () => {
const editableElement = editor.ui.view.editable.element;

// Set #toolbarView's max-width on the initialization and update it on the editable resize.
this._resizeObserver = new ResizeObserver( editableElement, () => {
// The max-width equals 90% of the editable's width for the best user experience.
// The value keeps the balloon very close to the boundaries of the editable and limits the cases
// when the balloon juts out from the editable element it belongs to.
this.toolbarView.maxWidth = toPx( new Rect( editableElement ).width * .9 );
} );
} );
}
}

/**
Expand All @@ -134,10 +174,9 @@ export default class BalloonToolbar extends Plugin {
* @inheritDoc
*/
afterInit() {
const config = normalizeToolbarConfig( this.editor.config.get( 'balloonToolbar' ) );
const factory = this.editor.ui.componentFactory;

this.toolbarView.fillFromConfig( config.items, factory );
this.toolbarView.fillFromConfig( this._balloonConfig.items, factory );
}

/**
Expand All @@ -147,7 +186,10 @@ export default class BalloonToolbar extends Plugin {
* @returns {module:ui/toolbar/toolbarview~ToolbarView}
*/
_createToolbarView() {
const toolbarView = new ToolbarView( this.editor.locale );
const shouldGroupWhenFull = !this._balloonConfig.shouldNotGroupWhenFull;
const toolbarView = new ToolbarView( this.editor.locale, {
shouldGroupWhenFull
} );

toolbarView.extendTemplate( {
attributes: {
Expand Down Expand Up @@ -260,6 +302,10 @@ export default class BalloonToolbar extends Plugin {
this._fireSelectionChangeDebounced.cancel();
this.toolbarView.destroy();
this.focusTracker.destroy();

if ( this._resizeObserver ) {
this._resizeObserver.destroy();
}
}

/**
Expand Down Expand Up @@ -289,23 +335,33 @@ function getBalloonPositions( isBackward ) {
defaultPositions.northWestArrowSouth,
defaultPositions.northWestArrowSouthWest,
defaultPositions.northWestArrowSouthEast,
defaultPositions.northWestArrowSouthMiddleEast,
defaultPositions.northWestArrowSouthMiddleWest,
defaultPositions.southWestArrowNorth,
defaultPositions.southWestArrowNorthWest,
defaultPositions.southWestArrowNorthEast
defaultPositions.southWestArrowNorthEast,
defaultPositions.southWestArrowNorthMiddleWest,
defaultPositions.southWestArrowNorthMiddleEast
] : [
defaultPositions.southEastArrowNorth,
defaultPositions.southEastArrowNorthEast,
defaultPositions.southEastArrowNorthWest,
defaultPositions.southEastArrowNorthMiddleEast,
defaultPositions.southEastArrowNorthMiddleWest,
defaultPositions.northEastArrowSouth,
defaultPositions.northEastArrowSouthEast,
defaultPositions.northEastArrowSouthWest
defaultPositions.northEastArrowSouthWest,
defaultPositions.northEastArrowSouthMiddleEast,
defaultPositions.northEastArrowSouthMiddleWest
];
}

/**
* Contextual toolbar configuration. Used by the {@link module:ui/toolbar/balloon/balloontoolbar~BalloonToolbar}
* feature.
*
* ## Configuring toolbar items
*
* const config = {
* balloonToolbar: [ 'bold', 'italic', 'undo', 'redo' ]
* };
Expand All @@ -318,5 +374,16 @@ function getBalloonPositions( isBackward ) {
*
* Read also about configuring the main editor toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.
*
* ## Configuring items grouping
*
* You can prevent automatic items grouping by setting the `shouldNotGroupWhenFull` option:
*
* const config = {
* balloonToolbar: {
* items: [ 'bold', 'italic', 'undo', 'redo' ]
* },
* shouldNotGroupWhenFull: true
* };
*
* @member {Array.<String>|Object} module:core/editor/editorconfig~EditorConfig#balloonToolbar
*/
33 changes: 32 additions & 1 deletion src/toolbar/toolbarview.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ export default class ToolbarView extends View {
*/
this.set( 'ariaLabel', t( 'Editor toolbar' ) );

/**
* The maximum width of the toolbar element.
*
panr marked this conversation as resolved.
Show resolved Hide resolved
* **Note**: When set to a specific value (e.g. `'200px'`), the value will affect the behavior of the
* {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull}
* option by changing the number of {@link #items} that will be displayed in the toolbar at a time.
*
* @observable
* @default 'auto'
* @member {String} #maxWidth
*/
this.set( 'maxWidth', 'auto' );

/**
* A collection of toolbar items (buttons, dropdowns, etc.).
*
Expand Down Expand Up @@ -181,7 +194,10 @@ export default class ToolbarView extends View {
bind.if( 'isCompact', 'ck-toolbar_compact' )
],
role: 'toolbar',
'aria-label': bind.to( 'ariaLabel' )
'aria-label': bind.to( 'ariaLabel' ),
style: {
maxWidth: bind.to( 'maxWidth' )
}
},

children: this.children,
Expand Down Expand Up @@ -570,6 +586,7 @@ class DynamicGrouping {
this.viewElement = view.element;

this._enableGroupingOnResize();
this._enableGroupingOnMaxWidthChange( view );
}

/**
Expand Down Expand Up @@ -694,6 +711,18 @@ class DynamicGrouping {
this._updateGrouping();
}

/**
* Enables the grouping functionality, just like {@link #_enableGroupingOnResize} but the difference is that
* it listens to the changes of {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth} instead.
*
* @private
*/
_enableGroupingOnMaxWidthChange( view ) {
view.on( 'change:maxWidth', () => {
this._updateGrouping();
} );
}

/**
* When called, it will remove the last item from {@link #ungroupedItems} and move it back
* to the {@link #groupedItems} collection.
Expand Down Expand Up @@ -798,6 +827,8 @@ class DynamicGrouping {
* would normally wrap to the next line when there is not enough space to display them in a single row, for
* instance, if the parent container of the toolbar is narrow.
*
* Also see: {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth}.
*
* @member {Boolean} module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull
*/

Expand Down
13 changes: 11 additions & 2 deletions tests/manual/panel/balloon/balloonpanelview.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@
padding: 5em;
}

h1 {
font-size: 22px;
text-align: center;
margin: 70px 0;
}

.target {
width: 125px;
height: 20px;
background: green;
margin: 0 0 0 100px;
background: lightblue;
transform: translateX(-50%);
margin-left: 50%;
}

.target + .target {
Expand All @@ -18,5 +25,7 @@

.ck-balloon-panel {
padding: .3em;
width: 250px;
text-align: center;
}
</style>
31 changes: 31 additions & 0 deletions tests/manual/panel/balloon/balloonpanelview.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,22 @@ import BalloonPanelView from '../../../../src/panel/balloon/balloonpanelview';
const defaultPositions = BalloonPanelView.defaultPositions;
const container = document.querySelector( '#container' );

let currentHeading = '';

for ( const i in defaultPositions ) {
const target = document.createElement( 'div' );
const heading = document.createElement( 'h1' );
const headingText = parseHeadingText( i );

heading.textContent = headingText;
target.classList.add( 'target' );

// Lazy heading
if ( currentHeading !== headingText ) {
container.appendChild( heading );
currentHeading = headingText;
}

container.appendChild( target );

const balloon = new BalloonPanelView();
Expand All @@ -27,3 +40,21 @@ for ( const i in defaultPositions ) {
]
} );
}

function parseHeadingText( text ) {
const normalizedText = getNormalizeHeading( text );
return getCapitalizedHeading( normalizedText );
}

// This helper function creates normalize heading text from a full name of the position,
// removing `ArrowXyz` part, like in the example:
// `southEastArrowNorthMiddleEast` -> `south East`.
function getNormalizeHeading( text ) {
return text
.replace( /(w*)arrow\w*/i, '$1' )
.replace( /([a-z])([A-Z])/, '$1 $2' );
}

function getCapitalizedHeading( text ) {
return text.charAt( 0 ).toUpperCase() + text.slice( 1 );
}
2 changes: 1 addition & 1 deletion tests/manual/panel/balloon/balloonpanelview.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## `BalloonPanelView` and `defaultPositions`

1. A number of green rectangles should be displayed in the page.
1. A number of colorful rectangles should be displayed in the page.
2. Each rectangle should have a panel attached.
3. Make sure the description in each panel matches the location of the panel.
Loading