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

Commit

Permalink
Merge 466b92e into 02763b0
Browse files Browse the repository at this point in the history
  • Loading branch information
panr committed Feb 4, 2020
2 parents 02763b0 + 466b92e commit 574a670
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 8 deletions.
6 changes: 5 additions & 1 deletion src/inlineeditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ export default class InlineEditor extends Editor {
secureSourceElement( this );
}

const view = new InlineEditorUIView( this.locale, this.editing.view, this.sourceElement );
const shouldToolbarGroupWhenFull = !this.config.get( 'toolbar.shouldNotGroupWhenFull' );

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

attachToForm( this );
Expand Down
32 changes: 30 additions & 2 deletions src/inlineeditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import EditorUIView from '@ckeditor/ckeditor5-ui/src/editorui/editoruiview';
import InlineEditableUIView from '@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview';
import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview';
import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';
import getResizeObserver from '@ckeditor/ckeditor5-utils/src/dom/getresizeobserver';
import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';

const toPx = toUnit( 'px' );

/**
* Inline editor UI view. Uses an nline editable and a floating toolbar.
Expand All @@ -25,8 +30,9 @@ export default class InlineEditorUIView extends EditorUIView {
* @param {module:engine/view/view~View} editingView The editing view instance this view is related to.
* @param {HTMLElement} [editableElement] The editable element. If not specified, it will be automatically created by
* {@link module:ui/editableui/editableuiview~EditableUIView}. Otherwise, the given element will be used.
* @param {Object} [options={}] Configuration options for the view instance.
*/
constructor( locale, editingView, editableElement ) {
constructor( locale, editingView, editableElement, options = {} ) {
super( locale );

/**
Expand All @@ -35,7 +41,9 @@ export default class InlineEditorUIView extends EditorUIView {
* @readonly
* @member {module:ui/toolbar/toolbarview~ToolbarView}
*/
this.toolbar = new ToolbarView( locale );
this.toolbar = new ToolbarView( locale, {
shouldGroupWhenFull: options.shouldToolbarGroupWhenFull
} );

/**
* The offset from the top edge of the web browser's viewport which makes the
Expand Down Expand Up @@ -144,6 +152,26 @@ export default class InlineEditorUIView extends EditorUIView {
this.body.add( this.panel );
this.registerChild( this.editable );
this.panel.content.add( this.toolbar );

const options = this.toolbar.options;

// Set toolbar's max-width on the initialization and update it on the editable resize,
// if 'shouldToolbarGroupWhenFull' in config is set to 'true'.
if ( options.shouldGroupWhenFull ) {
const editableElement = this.editable.element;
const widthObserver = getResizeObserver( () => {
// We need to check if there's already the editable element in the DOM.
// Otherwise the `Rect` instance will complain that source (editableElement) is not available
// to obtain the element's geometry.
if ( !editableElement.ownerDocument.body.contains( editableElement ) ) {
return;
}

this.toolbar.maxWidth = toPx( new Rect( editableElement ).width );
} );

widthObserver.observe( editableElement );
}
}

/**
Expand Down
16 changes: 16 additions & 0 deletions tests/inlineeditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,22 @@ describe( 'InlineEditor', () => {
} );
} );

it( 'should pass the config.toolbar.shouldNotGroupWhenFull configuration to the view', () => {
const editorElement = document.createElement( 'div' );

return InlineEditor.create( editorElement, {
toolbar: {
shouldNotGroupWhenFull: true
}
} ).then( editor => {
expect( editor.ui.view.toolbar.options.shouldGroupWhenFull ).to.be.false;

return editor.destroy();
} ).then( () => {
editorElement.remove();
} );
} );

it( 'throws if initial data is passed in Editor#create and config.initialData is also used', done => {
InlineEditor.create( '<p>Hello world!</p>', {
initialData: '<p>I am evil!</p>',
Expand Down
14 changes: 9 additions & 5 deletions tests/inlineeditorui.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,6 @@ describe( 'InlineEditorUI', () => {
it( 'pin() is called on editor.ui#update', () => {
const spy = sinon.stub( view.panel, 'pin' );

view.panel.hide();

editor.ui.fire( 'update' );
sinon.assert.notCalled( spy );

view.panel.show();

editor.ui.fire( 'update' );
Expand All @@ -100,6 +95,15 @@ describe( 'InlineEditorUI', () => {
positions: sinon.match.array
} );
} );

it( 'pin() is not called on editor.ui#update when panel is hidden', () => {
const spy = sinon.stub( view.panel, 'pin' );

view.panel.hide();

editor.ui.fire( 'update' );
sinon.assert.notCalled( spy );
} );
} );

describe( 'editable', () => {
Expand Down
33 changes: 33 additions & 0 deletions tests/inlineeditoruiview.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ import BalloonPanelView from '@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpa
import InlineEditableUIView from '@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview';
import Locale from '@ckeditor/ckeditor5-utils/src/locale';
import createRoot from '@ckeditor/ckeditor5-engine/tests/view/_utils/createroot.js';
import Rect from '@ckeditor/ckeditor5-utils/src/dom/rect';
import toUnit from '@ckeditor/ckeditor5-utils/src/dom/tounit';
import global from '@ckeditor/ckeditor5-utils/src/dom/global';

const toPx = toUnit( 'px' );

import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';

/* globals setTimeout */

describe( 'InlineEditorUIView', () => {
let locale, view, editingView, editingViewRoot;

Expand Down Expand Up @@ -76,6 +83,9 @@ describe( 'InlineEditorUIView', () => {

describe( 'render()', () => {
beforeEach( () => {
// We need to set this option explicitly before render phase,
// otherwise it is `undefined` and toolbar items grouping will be skipped in tests.
view.toolbar.options.shouldGroupWhenFull = true;
view.render();
} );

Expand All @@ -91,6 +101,29 @@ describe( 'InlineEditorUIView', () => {
it( 'sets the default value of the #viewportTopOffset attribute', () => {
expect( view.viewportTopOffset ).to.equal( 0 );
} );

// Sometimes this test can fail, due to the fact that it have to wait for async ResizeObserver execution.
it( 'max-width should be set to the width of the editable element', done => {
const viewElement = view.editable.element;

global.document.body.appendChild( viewElement );
expect( global.document.body.contains( viewElement ) ).to.be.true;

viewElement.style.width = '400px';

// Unfortunately we have to wait for async ResizeObserver execution.
// ResizeObserver which has been called after changing width of viewElement,
// needs 2x requestAnimationFrame or timeout to update a layout.
// See more: https://twitter.com/paul_irish/status/912693347315150849/photo/1
setTimeout( () => {
const editableWidthWithPadding = toPx( new Rect( viewElement ).width );
expect( view.toolbar.maxWidth ).to.be.equal( editableWidthWithPadding );

global.document.body.removeChild( viewElement );

done();
}, 500 );
} );
} );

describe( '#panel', () => {
Expand Down

0 comments on commit 574a670

Please sign in to comment.