-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
I/9213 enabling caption toolbar #9459
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍
My biggest concern, though, is why was the text alternative button left disabled when the selection is the caption? Is there any reason for that?
export function getImageModelElementAncestor( selection ) { | ||
const selectedElement = selection.getSelectedElement(); | ||
|
||
return isImage( selectedElement ) ? selectedElement : selection.getFirstPosition().findAncestor( 'image' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return isImage( selectedElement ) ? selectedElement : selection.getFirstPosition().findAncestor( 'image' ); | |
return isImage( selectedElement ) ? selectedElement : selection.getFirstPosition().findAncestor( isBlockImage ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that the model element findAncestor
method accepts the element name only: https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_model_element-Element.html#function-findAncestor. Unless I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I must've mistaken it with some other helper. Sorry for the confusion.
it( 'should be false when the selection is on other object', () => { | ||
model.schema.register( 'object', { isObject: true, allowIn: '$root' } ); | ||
editor.conversion.for( 'downcast' ).elementToElement( { model: 'object', view: 'object' } ); | ||
setModelData( model, '[<object></object>]' ); | ||
|
||
expect( inlineCommand.isEnabled ).to.be.false; | ||
} ); | ||
|
||
it( 'should be true when the selection is in a caption', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it( 'should be true when the selection is in a caption', () => { | |
it( 'should be true when the selection is in a block image caption', () => { |
@@ -271,6 +266,18 @@ describe( 'ImageTypeCommand', () => { | |||
'</paragraph>' | |||
); | |||
} ); | |||
|
|||
it( 'should convert and set selection on the new image if the selection is in a caption', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it( 'should convert and set selection on the new image if the selection is in a caption', () => { | |
it( 'should convert and set selection on the new image if the selection is in a block image caption', () => { |
expect( image ).to.be.instanceOf( ModelElement ); | ||
expect( image.name ).to.equal( 'imageInline' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expect( image.is( 'element', 'imageInline' ) ).to.be.true
is enough to check this. The same applies to all tests that follow 👇
@@ -150,6 +150,9 @@ export default class ImageStyleUI extends Plugin { | |||
} | |||
} ); | |||
|
|||
dropdownView.bind( 'isEnabled' ) | |||
.toMany( buttonViews, 'isEnabled', ( ...areEnabled ) => !!areEnabled.find( isEnabled => isEnabled ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.toMany( buttonViews, 'isEnabled', ( ...areEnabled ) => !!areEnabled.find( isEnabled => isEnabled ) ); | |
.toMany( buttonViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) ); |
groups = groups.map( group => { | ||
const items = group.view.toolbarView.items; | ||
|
||
items.map( item => { | ||
item.isEnabled = false; | ||
|
||
return item; | ||
} ); | ||
|
||
const activeButton = items.first; | ||
|
||
activeButton.isEnabled = true; | ||
|
||
return { ...group, activeButton }; | ||
} ); | ||
|
||
for ( const { buttonView } of groups ) { | ||
expect( buttonView.isEnabled ).to.be.true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be way simpler (why map()
and return activeButton
?):
groups = groups.map( group => { | |
const items = group.view.toolbarView.items; | |
items.map( item => { | |
item.isEnabled = false; | |
return item; | |
} ); | |
const activeButton = items.first; | |
activeButton.isEnabled = true; | |
return { ...group, activeButton }; | |
} ); | |
for ( const { buttonView } of groups ) { | |
expect( buttonView.isEnabled ).to.be.true; | |
} | |
for ( const group of groups ) { | |
const groupItems = group.view.toolbarView.items; | |
for ( const item of groupItems ) { | |
item.isEnabled = false; | |
} | |
groupItems.first.isEnabled = true; | |
} | |
for ( const { buttonView, config } of groups ) { | |
expect( buttonView.isEnabled, `Failing group name: "${ config.name }"` ).to.be.true; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to mutate the groups
and mess up the following tests. I missed the fact that each of these tests has its own beforeEach
and thus separate groups
array. Thanks for the catch :)
groups = groups.map( group => { | ||
const items = group.view.toolbarView.items; | ||
|
||
items.map( item => { | ||
item.isEnabled = false; | ||
|
||
return item; | ||
} ); | ||
|
||
return group; | ||
} ); | ||
|
||
for ( const { buttonView } of groups ) { | ||
expect( buttonView.isEnabled ).to.be.false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
groups = groups.map( group => { | |
const items = group.view.toolbarView.items; | |
items.map( item => { | |
item.isEnabled = false; | |
return item; | |
} ); | |
return group; | |
} ); | |
for ( const { buttonView } of groups ) { | |
expect( buttonView.isEnabled ).to.be.false; | |
} | |
for ( const group of groups ) { | |
const groupItems = group.view.toolbarView.items; | |
for ( const item of groupItems ) { | |
item.isEnabled = false; | |
} | |
} | |
for ( const { buttonView, config } of groups ) { | |
expect( buttonView.isEnabled, `Failing group name: "${ config.name }"` ).to.be.false; | |
} |
Yes, my scatterbraining. I fixed it for the text alternative and image resize buttons. |
@@ -65,7 +65,7 @@ export function getSelectedImageWidgetOrAncestor( selection ) { | |||
* @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection | |||
* @returns {module:engine/view/element~Element|null} | |||
*/ | |||
export function getSelectedImageWidgetAncestor( selection ) { | |||
export function getSelectionAncestorImageWidget( selection ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this helper is only used internally by getSelectedOrAncestorImageWidget()
. I think we should merge them.
@@ -86,7 +86,7 @@ export function getSelectedImageWidgetAncestor( selection ) { | |||
* @returns {module:engine/model/element~Element|null} | |||
*/ | |||
|
|||
export function getSelectedImageElementOrAncestor( selection ) { | |||
export function getSelectedOrAncestorImageElement( selection ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about getClosestSelectedImageElement()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, the image element returned by this function doesn't have to be formally selected (<image><caption>[Foo]</caption></image>
), so wouldn't this name be misleading?
However, I don't like the name above either. I was thinking about something like getCorrelatedImageElement
- a bit enigmatic, but still understandable IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe then simply getClosestImageElement()
(getClosestImageWidget()
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I liked the previous version better :) Changed to getClosestSelectedImageElement
.
@@ -49,14 +49,14 @@ export function isImageWidget( viewElement ) { | |||
* @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection | |||
* @returns {module:engine/view/element~Element|null} | |||
*/ | |||
export function getSelectedImageWidgetOrAncestor( selection ) { | |||
export function getSelectedOrAncestorImageWidget( selection ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about getClosestSelectedImageWidget()
?
@oleq could you also refer to the following?
|
Since we're doing tons of breaking changes in this feature branch, I see nothing wrong with removing unused helpers and simplifying the names of the confusing ones. |
Suggested merge commit message (convention)
Fix (image): The buttons in the image toolbar should be enabled when the selection is in a caption. Closes #9213.
Fix (image): Dropdowns in the image toolbar should be disabled when all of the nested buttons are disabled. See #9213.
We actually don't need the getSelectedImageWidget function anymore. Whenever we are looking for an image on which to execute a command, we are also looking for the image ancestor of the selected caption. So I replaced the
getSelectedImageWidget
withgetSelectedOrAncestorImageWidget
.It was a public function, so I'm not sure if it's ok to change its name and behavior. But because of the changes in managing the toolbar state, our integrator probably also should start using the
getSelectedOrAncestorImageWidget
function.BTW, should such renaming be considered a breaking change?