-
Notifications
You must be signed in to change notification settings - Fork 10
T/53a: Split "heading" command into independent commands. #58
Conversation
self.R-. There's no need for |
|
||
for ( let option of options ) { | ||
// Add the option to the collection. | ||
dropdownItems.add( new Model( { |
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.
Does it have to be a model instance? Can't this be a simple object?
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.
Binding requires observable. We could pass an object here and convert it into observable in createlistdropdown. But this is beyond the scope of this issue as it didn't change this part.
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.
OTOH I'm not sure whether would make more sense. There could be cases when a feature using the dropdown might want to play with models in #items
immediately, i.e. bind its attributes to something else.
If we enforce that #items
is Collection.<Object>
, developers would need to pick those models from the dropdown after createListDropdown
was called which is not very convenient.
Besides, what would ListView
look like then if #items
would be Collection.<Object>
? Where to store the "intermediate models" created in createListDropdown()
? Because there must be models for Model->ListItemView
bindings.
src/heading.js
Outdated
// Add the option to the collection. | ||
dropdownItems.add( new Model( { | ||
modelElement: option.modelElement, | ||
label: option.title |
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 label = title
doesn't look good.
I think that the name of the option property should be as generic as possible because we'll have the same problem all around our code. I wonder what's better – label, title or perhaps name. We have the same problem in ImageStyles
and it would be good to find a naming convention fitting all such scenarios.
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 may not look good but OTOH it makes sense. "Label" is a label in DOM, in the UI component. "Title" is any kind of title, it could be a label, but also aria attribute or plain text. This is where two of them meet.
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.
OK, so if you find "title" more generic, then let's use it. Then, we're also fine in the ImageStyles which uses the same property name.
src/heading.js
Outdated
|
||
// Register UI component. | ||
editor.ui.componentFactory.add( 'headings', ( locale ) => { | ||
const dropdown = createListDropdown( dropdownModel, locale ); | ||
|
||
// Execute command when an item from the dropdown is selected. | ||
this.listenTo( dropdown, 'execute', ( { source: { id } } ) => { | ||
editor.execute( 'heading', { id } ); | ||
this.listenTo( dropdown, 'execute', ( { source: { modelElement } } ) => { |
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.
The param of the callback is impossible for me to parse. Please use a more human-readable solution.
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.
Learn destructuring then ;-)
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 know destructuring and it doesn't help. Which means that the code is wrong.
src/heading.js
Outdated
this.listenTo( dropdown, 'execute', ( { source: { id } } ) => { | ||
editor.execute( 'heading', { id } ); | ||
this.listenTo( dropdown, 'execute', ( { source: { modelElement } } ) => { | ||
editor.execute( modelElement ); |
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.
If you execute this, then it's a commandName
not modelElement
.
src/heading.js
Outdated
return editor.config.get( 'heading.options' ).map( option => { | ||
let title; | ||
|
||
if ( option.modelElement == 'paragraph' ) { |
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.
Why this condition? Can't it go through the usual:
title = localizedTitles[ option.title ];
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.
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 meant – why it doesn't have that property? It doesn't make sense that it has viewElement
. It doesn't also make sense that it has modelElement
– it could be replaced with defaultBlock: true
or something (but we can stick to modelElement
– I'm ok with this). But it certainly can have title
.
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.
Actually, without it it's not localizable AFAICS. I mean – it can be localized through translations, but you can't use custom title.
src/headingcommand.js
Outdated
} | ||
} | ||
// When applying new option. | ||
else { | ||
batch.rename( element, id ); | ||
batch.rename( element, this.modelElement ); |
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.
Like in the paragraph command – you can skip renaming elements which are already named correctly.
src/headingcommand.js
Outdated
} | ||
} | ||
|
||
// If range's selection start/end is placed directly in renamed block - we need to restore it's position | ||
// after renaming, because renaming puts new element there. | ||
doc.selection.setRanges( ranges, isSelectionBackward ); | ||
selection.setRanges( ranges, isSelectionBackward ); |
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.
If everything else works correctly, this should be unnecessary. This command does not change the 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.
PS. This might've been necessary in the past when renaming wasn't an operation because then the live selection transformations might not have been able to keep the selection position.
src/headingengine.js
Outdated
.toElement( option.modelElement ); | ||
|
||
// Register the heading command for this option. | ||
command = new HeadingCommand( editor, option ); |
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 variable is unnecessary.
HeadingCommand. Re-enabled command toggle. Renames in config.heading.options.
…ement. Refactoring in Heading after removal of ParagraphCommand#title.
…r paragraph option. Enhanced tests.
Suggested merge commit message (convention)
Feature: Split "heading" command into independent commands. Closes ckeditor/ckeditor5#2435. Closes ckeditor/ckeditor5#2442. Closes ckeditor/ckeditor5#2437.
BREAKING CHANGE: The "heading" command is no longer available. Replaced by "heading1", "heading2", "heading3" and "paragraph".
BREAKING CHANGE:
Heading
plugin requiresParagraph
to work properly (ParagraphCommand
registered as "paragraph" ineditor.commands
).BREAKING CHANGE:
config.heading.options
format has changed. The validHeadingOption
syntax is now{ modelElement: 'heading1', viewElement: 'h1', title: 'Heading 1' }
.Additional information
Requires ckeditor/ckeditor5-paragraph#15.