Skip to content

Commit

Permalink
Merge pull request #16591 from ckeditor/ck/16571-add-menu-bar-to-rema…
Browse files Browse the repository at this point in the history
…ining-editor-types

Feature (editor-balloon, editor-inline): Added support for the menu bar. Closes #16571.
  • Loading branch information
DawidKossowski authored Jul 8, 2024
2 parents b3a9904 + 4c1361f commit 5e4b36a
Show file tree
Hide file tree
Showing 26 changed files with 679 additions and 591 deletions.
8 changes: 4 additions & 4 deletions docs/getting-started/setup/menubar.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ You can easily remove some presets or add more items, including menu items for c

## Enabling the menu bar

The menu bar is currently available in the {@link module:editor-classic/classiceditor~ClassicEditor Classic editor}, {@link module:editor-decoupled/decouplededitor~DecoupledEditor Decoupled editor}, and {@link module:editor-multi-root/multirooteditor~MultiRootEditor Multi-root editor}.
The menu bar is available in all editor types. Usage will vary depending on used editor type.

### Classic editor
### Classic editor and Inline editor

The menu bar is disabled by default. To make it available in your editor, set the `config.menuBar.isVisible` property to `true`. This will turn on the menu bar with a default set of features. The menu bar is located right above the editor toolbar.

Expand All @@ -42,9 +42,9 @@ ClassicEditor
} );
```

### Decoupled editor
### Decoupled editor, Balloon editor and Multi-root editor

When using the Decoupled editor, you will need to insert the menu bar in a desired place yourself. The menu bar HTML element is available under the `editor.ui.menuBarView.element` property.
When using the Decoupled, Balloon or Multi-root editor, you will need to insert the menu bar in a desired place yourself. The menu bar HTML element is available under the `editor.ui.menuBarView.element` property.

```html
<div id="menuBarContainer"></div>
Expand Down
1 change: 1 addition & 0 deletions packages/ckeditor5-editor-balloon/src/ballooneditorui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export default class BalloonEditorUI extends EditorUI {
editingView.attachDomRoot( editableElement );

this._initPlaceholder();
this._initMenuBar( this.view.menuBarView! );
this.fire<EditorUIReadyEvent>( 'ready' );
}

Expand Down
15 changes: 14 additions & 1 deletion packages/ckeditor5-editor-balloon/src/ballooneditoruiview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @module editor-balloon/ballooneditoruiview
*/

import { EditorUIView, InlineEditableUIView } from 'ckeditor5/src/ui.js';
import { EditorUIView, InlineEditableUIView, MenuBarView } from 'ckeditor5/src/ui.js';
import type { Locale } from 'ckeditor5/src/utils.js';
import type { EditingView } from 'ckeditor5/src/engine.js';

Expand Down Expand Up @@ -42,6 +42,18 @@ export default class BalloonEditorUIView extends EditorUIView {
return t( 'Rich Text Editor. Editing area: %0', editableView.name! );
}
} );

this.menuBarView = new MenuBarView( locale );

this.menuBarView.extendTemplate( {
attributes: {
class: [
'ck-reset_all',
'ck-rounded-corners'
],
dir: locale.uiLanguageDirection
}
} );
}

/**
Expand All @@ -51,5 +63,6 @@ export default class BalloonEditorUIView extends EditorUIView {
super.render();

this.registerChild( this.editable );
this.registerChild( this.menuBarView! );
}
}
15 changes: 15 additions & 0 deletions packages/ckeditor5-editor-balloon/tests/ballooneditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import EditingView from '@ckeditor/ckeditor5-engine/src/view/view.js';
import BalloonEditorUIView from '../src/ballooneditoruiview.js';
import InlineEditableUIView from '@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview.js';
import MenuBarView from '@ckeditor/ckeditor5-ui/src/menubar/menubarview.js';
import Locale from '@ckeditor/ckeditor5-utils/src/locale.js';
import createRoot from '@ckeditor/ckeditor5-engine/tests/view/_utils/createroot.js';

Expand Down Expand Up @@ -46,6 +47,20 @@ describe( 'BalloonEditorUIView', () => {
view.destroy();
} );
} );

describe( '#menuBarView', () => {
it( 'is created', () => {
expect( view.menuBarView ).to.be.instanceof( MenuBarView );
} );

it( 'is given a locale object', () => {
expect( view.menuBarView.locale ).to.equal( locale );
} );

it( 'is not rendered', () => {
expect( view.menuBarView.isRendered ).to.be.false;
} );
} );
} );

describe( 'render()', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
<button id="initEditors">Init editors</button>
</p>

<div id="menubar-container-1" class="custom-class"></div>
<div id="editor-1" contenteditable="true" class="custom-class" custom-attr="foo">
<h2>Editor 1</h2>
<p>This is an editor instance. And there's <a href="http://ckeditor.com">some link</a>.</p>
</div>

<br />

<div id="menubar-container-2" class="custom-class"></div>
<div id="editor-2" class="custom-class" custom-attr="foo">
<h2>Editor 2</h2>
<p>This is another editor instance.</p>
Expand All @@ -25,9 +29,7 @@ <h2>Editor 2</h2>
}

.custom-class {
margin-top: 100px;
margin-left: 100px;
margin-bottom: 100px;
width: 450px;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ function initEditors() {
window.editors[ selector ] = editor;
window.editables.push( editor.editing.view.document.getRoot() );

const editorNumber = selector.split( '-' )[ 1 ];
document.querySelector( `#menubar-container-${ editorNumber }` ).appendChild( editor.ui.view.menuBarView.element );

const observer = createObserver();

observer.observe(
Expand All @@ -51,7 +54,11 @@ function initEditors() {

function destroyEditors() {
for ( const selector in window.editors ) {
window.editors[ selector ].destroy().then( () => {
const editor = window.editors[ selector ];

editor.destroy().then( () => {
editor.ui.view.menuBarView.element.remove();

console.log( `${ selector } was destroyed.` );
} );
}
Expand Down
7 changes: 2 additions & 5 deletions packages/ckeditor5-editor-classic/src/classiceditorui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ import {
EditorUI,
DialogView,
normalizeToolbarConfig,
_initMenuBar,
type DialogViewMoveToEvent,
type Dialog,
type EditorUIReadyEvent,
type EditorUIView,
type MenuBarView
type EditorUIReadyEvent
} from 'ckeditor5/src/ui.js';
import {
enablePlaceholder,
Expand Down Expand Up @@ -120,7 +117,7 @@ export default class ClassicEditorUI extends EditorUI {
this._initToolbar();

if ( view.menuBarView ) {
_initMenuBar( editor, view.menuBarView );
this._initMenuBar( view.menuBarView );
}

this._initDialogPluginIntegration();
Expand Down
5 changes: 0 additions & 5 deletions packages/ckeditor5-editor-classic/src/classiceditoruiview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ export default class ClassicEditorUIView extends BoxedEditorUIView {
*/
public readonly toolbar: ToolbarView;

/**
* Menu bar view instance.
*/
public readonly menuBarView?: MenuBarView;

/**
* Editable UI view.
*/
Expand Down
5 changes: 2 additions & 3 deletions packages/ckeditor5-editor-decoupled/src/decouplededitorui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import {

import {
EditorUI,
type EditorUIReadyEvent,
_initMenuBar
type EditorUIReadyEvent
} from 'ckeditor5/src/ui.js';

import { enablePlaceholder } from 'ckeditor5/src/engine.js';
Expand Down Expand Up @@ -81,7 +80,7 @@ export default class DecoupledEditorUI extends EditorUI {

this._initPlaceholder();
this._initToolbar();
_initMenuBar( editor, this.view.menuBarView );
this._initMenuBar( this.view.menuBarView! );
this.fire<EditorUIReadyEvent>( 'ready' );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ export default class DecoupledEditorUIView extends EditorUIView {
*/
public readonly toolbar: ToolbarView;

/**
* Menu bar view instance.
*/
public readonly menuBarView: MenuBarView;

/**
* The editable of the decoupled editor UI.
*/
Expand Down Expand Up @@ -104,6 +99,6 @@ export default class DecoupledEditorUIView extends EditorUIView {
public override render(): void {
super.render();

this.registerChild( [ this.menuBarView, this.toolbar, this.editable ] );
this.registerChild( [ this.menuBarView!, this.toolbar, this.editable ] );
}
}
7 changes: 6 additions & 1 deletion packages/ckeditor5-editor-inline/src/inlineeditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export default class InlineEditor extends /* #__PURE__ */ ElementApiMixin( Edito

super( config );

this.config.define( 'menuBar.isVisible', false );

if ( this.config.get( 'initialData' ) === undefined ) {
this.config.set( 'initialData', getInitialData( sourceElementOrData ) );
}
Expand All @@ -69,8 +71,11 @@ export default class InlineEditor extends /* #__PURE__ */ ElementApiMixin( Edito

const shouldToolbarGroupWhenFull = !this.config.get( 'toolbar.shouldNotGroupWhenFull' );

const menuBarConfig = this.config.get( 'menuBar' )!;

const view = new InlineEditorUIView( this.locale, this.editing.view, this.sourceElement, {
shouldToolbarGroupWhenFull
shouldToolbarGroupWhenFull,
useMenuBar: menuBarConfig.isVisible
} );
this.ui = new InlineEditorUI( this, view );

Expand Down
5 changes: 5 additions & 0 deletions packages/ckeditor5-editor-inline/src/inlineeditorui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ export default class InlineEditorUI extends EditorUI {

this._initPlaceholder();
this._initToolbar();

if ( view.menuBarView ) {
this._initMenuBar( view.menuBarView );
}

this.fire<EditorUIReadyEvent>( 'ready' );
}

Expand Down
16 changes: 15 additions & 1 deletion packages/ckeditor5-editor-inline/src/inlineeditoruiview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
BalloonPanelView,
EditorUIView,
InlineEditableUIView,
MenuBarView,
ToolbarView
} from 'ckeditor5/src/ui.js';
import {
Expand All @@ -22,6 +23,8 @@ import {
} from 'ckeditor5/src/utils.js';
import type { EditingView } from 'ckeditor5/src/engine.js';

import '../theme/inlineeditor.css';

const toPx = /* #__PURE__ */ toUnit( 'px' );

/**
Expand Down Expand Up @@ -138,6 +141,7 @@ export default class InlineEditorUIView extends EditorUIView {
editableElement?: HTMLElement,
options: {
shouldToolbarGroupWhenFull?: boolean;
useMenuBar?: boolean;
} = {}
) {
super( locale );
Expand All @@ -149,6 +153,10 @@ export default class InlineEditorUIView extends EditorUIView {
isFloating: true
} );

if ( options.useMenuBar ) {
this.menuBarView = new MenuBarView( locale );
}

this.set( 'viewportTopOffset', 0 );

this.panel = new BalloonPanelView( locale );
Expand Down Expand Up @@ -177,7 +185,13 @@ export default class InlineEditorUIView extends EditorUIView {

this.body.add( this.panel );
this.registerChild( this.editable );
this.panel.content.add( this.toolbar );

if ( this.menuBarView ) {
// Set toolbar as a child of a stickyPanel and makes toolbar sticky.
this.panel.content.addMany( [ this.menuBarView, this.toolbar ] );
} else {
this.panel.content.add( this.toolbar );
}

const options = this.toolbar.options;

Expand Down
1 change: 1 addition & 0 deletions packages/ckeditor5-editor-inline/tests/inlineeditorui.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ describe( 'Focus handling and navigation between editing root and editor toolbar
editor = await InlineEditor.create( editorElement, {
plugins: [ Paragraph, Image, ImageToolbar, ImageCaption ],
toolbar: [ 'imageTextAlternative' ],
menuBar: { isVisible: true },
image: {
toolbar: [ 'toggleImageCaption' ]
}
Expand Down
37 changes: 37 additions & 0 deletions packages/ckeditor5-editor-inline/tests/inlineeditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ResizeObserver from '@ckeditor/ckeditor5-utils/src/dom/resizeobserver.js'
const toPx = toUnit( 'px' );

import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils.js';
import { MenuBarView } from '@ckeditor/ckeditor5-ui';

describe( 'InlineEditorUIView', () => {
let locale, view, editingView, editingViewRoot;
Expand Down Expand Up @@ -115,6 +116,42 @@ describe( 'InlineEditorUIView', () => {
view.destroy();
} );
} );

describe( '#menuBarView', () => {
it( 'is not created', () => {
expect( view.menuBarView ).to.be.undefined;
} );
} );
} );

describe( 'with menu bar', () => {
let viewWithMenuBar;
testUtils.createSinonSandbox();

beforeEach( () => {
viewWithMenuBar = new InlineEditorUIView( locale, editingView, undefined, { useMenuBar: true } );
viewWithMenuBar.editable.name = editingViewRoot.rootName;
viewWithMenuBar.render();
} );

afterEach( () => {
viewWithMenuBar.destroy();
} );

describe( '#menuBarView', () => {
it( 'is created', () => {
expect( viewWithMenuBar.menuBarView ).to.be.instanceof( MenuBarView );
} );

it( 'is given a locale object', () => {
expect( viewWithMenuBar.menuBarView.locale ).to.equal( locale );
} );

it( 'is put into the "panel.content" collection', () => {
expect( viewWithMenuBar.panel.content.get( 0 ) ).to.equal( viewWithMenuBar.menuBarView );
expect( viewWithMenuBar.panel.content.get( 1 ) ).to.equal( viewWithMenuBar.toolbar );
} );
} );
} );

describe( 'render()', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ function initEditors() {
.create( document.querySelector( selector ), {
image: { toolbar: [ 'toggleImageCaption', 'imageTextAlternative' ] },
plugins: [ ArticlePluginSet ],
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' ]
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' ],
menuBar: { isVisible: true }
} )
.then( editor => {
console.log( `${ selector } has been initialized`, editor );
Expand Down
9 changes: 9 additions & 0 deletions packages/ckeditor5-editor-inline/theme/inlineeditor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

.ck.ck-menu-bar {
border: none;
border-bottom: 1px solid var(--ck-color-toolbar-border);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {

import {
EditorUI,
_initMenuBar,
type EditorUIReadyEvent,
type InlineEditableUIView
} from 'ckeditor5/src/ui.js';
Expand Down Expand Up @@ -85,7 +84,7 @@ export default class MultiRootEditorUI extends EditorUI {
}

this._initToolbar();
_initMenuBar( this.editor, this.view.menuBarView );
this._initMenuBar( this.view.menuBarView! );
this.fire<EditorUIReadyEvent>( 'ready' );
}

Expand Down
Loading

0 comments on commit 5e4b36a

Please sign in to comment.