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

Introduced ContextualBalloon class for managing contextual balloons. #177

Merged
merged 17 commits into from
Apr 5, 2017

Conversation

oskarwrobel
Copy link
Contributor

@oskarwrobel oskarwrobel commented Mar 28, 2017

Suggested merge commit message (convention)

Feature: Introduced ContextualBalloon plugin for managing contextual balloons. Closes ckeditor/ckeditor5#5296.


Follow-ups:

@@ -0,0 +1,283 @@
/**
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code of this manual test is no pretty because a lot of various things happens there :)
This code should be reduced when ContextualToolbar will become a CKE5 plugin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See: #185

@oskarwrobel oskarwrobel requested a review from oleq March 28, 2017 18:53
@oskarwrobel oskarwrobel changed the title Introduced ContextualToolbar class for managing contextual balloons. Introduced ContextualBalloon class for managing contextual balloons. Mar 29, 2017
@oleq
Copy link
Member

oleq commented Apr 3, 2017

I see TypeError: Cannot read property 'add' of undefined error in http://localhost:8125/ckeditor5-ui/tests/manual/contextualballoon/contextualballoon.html, unable to play with manual test.

@oleq
Copy link
Member

oleq commented Apr 4, 2017

Not sure if this is a bug, but reporting anyway:
kapture 2017-04-04 at 10 49 14

@oskarwrobel
Copy link
Contributor Author

Hm... this is not a bug of ContextualBalloon class but manual test should be improved.

/**
* Balloon panel view.
*
* @member {module:ui:view~View} #view
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@readonly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, any practical reason why not creating the BalloonPanelView instance directly at this point but assigning it like ctxBalloon.view = new BalloonPanelView() later on instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it to the constructor.

* @param {module:ui/contextualballoon~Panel} panelData Configuration of the panel.
*/
add( panelData ) {
if ( this._stack.get( panelData.view ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this.isPanelInStack( panelData.view ) be cleaner?

Copy link
Contributor Author

@oskarwrobel oskarwrobel Apr 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I added isPanelInstack() after I wrote this code.

/**
* Trying to add configuration of the same panel more than once.
*
* @error contextualballoon-add-item-exist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error id in docs does not match error id in throw new CKEditorError().

* @private
* @member {Map} #_stack
*/
this._stack = new Map();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@readonly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not @private?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good point :P

* Common contextual balloon of the Editor.
*
* This class reuses the same {module:ui/view~View} for each contextual balloon panel in the editor UI, makes
* possible to add multiple panels to the same balloon (stored in the stack, last one in the stack is visible)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why calling it "panels"? They're simply views, aren't they? It's a tool to use a single BalloonPanelView with multiple child views. The word "panel" repeats many times in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed.

* @param {module:ui/view~View} view View of panel which will be removed from the balloon.
*/
remove( view ) {
if ( !this._stack.get( view ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.isPanelInStack( view )

this._stack.delete( view );

// Next we need to check if there is other panel in stack to show.
const lastPanel = Array.from( this._stack ).pop();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using this._stack.values() would let us avoid lastPanel[ 1 ] a couple of lines later.

import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';

/**
* Common contextual balloon of the Editor.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much work would it take to make it a generic utility? I suppose eventually we may end up with other UI components which should manage their children in a similar way. E.g. a dialog, where you edit some fields, then you go deeper to edit some details or internals, then you go back again, etc., without leaving the dialog. Each editing level would be a different child view of the same dialog. If this is a lot of thinking, designing and coding we may think about it as a follow–up, because it's not necessary to MVP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created follow-up #186

@@ -0,0 +1,292 @@
/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to see how to the focus behaves when navigating such structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Focus behave is a matter of feature implementation. In this PR ckeditor/ckeditor5-link#92 balloon uses focus cycler and works fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created issue about simplifying/improving manual test. https://github.com/ckeditor/ckeditor5-ui/issues/185

/**
* Returns `true` when given view is in the stack otherwise returns `false`.
*
* @param {module:ui:view~View} view
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid link.

}

/**
* Adds view to the stack and makes is visible.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/is/it

@oleq
Copy link
Member

oleq commented Apr 5, 2017

I also experienced

Uncaught TypeError: Cannot read property 'view' of null

when pressing Esc when just loaded http://localhost:8125/ckeditor5-ui/tests/manual/contextualballoon/contextualballoon.html.

* This plugin allows reusing a single {module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance
* to display multiple contextual balloon panels in the editor.
*
* Child views of such a panel are stored in the stack and the last one in the stack is visible. When the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An afterthought: Since _stack is private we should not talk in the public docs about it. It is of no concern to the devs how the CB handles views.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I wrote about stack I wasn't thinking about var name but about the way how we store it.

* @param {module:ui/view~View} view
* @returns {Boolean}
*/
isViewInStack( view ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename it to hasView(). As in https://github.com/ckeditor/ckeditor5-ui/pull/177/files#r109897538, _stack is private and it does not concern people in the public API.

*
* @returns {module:ui/contextualballoon~ViewConfig|null}
*/
get visible() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boolean properties and variables are always prefixed by an auxiliary verb:

https://github.com/ckeditor/ckeditor5-design/wiki/Code-Style-Naming-Guidelines

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This getter returns visible view. It's not checking if given view is visible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So get visibleView() maybe? I'm trying to make it less ambiguous.

Copy link
Contributor Author

@oskarwrobel oskarwrobel Apr 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... this returns not only the view but the whole configuration { view, position } https://github.com/ckeditor/ckeditor5-ui/pull/177/files#diff-93d63500d90d723217fc16438b6b32a4R193

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But maybe only the view should be returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... looks like there is no need to return the balloon position configuration because this position is used internally by ContextualBalloon.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@oleq
Copy link
Member

oleq commented Apr 5, 2017

R+ but the master is locked so we're gonna postpone the merge.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants