-
-
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
List style feature #7861
List style feature #7861
Conversation
Internal (list): Created the list styles UI. Closes #7803.
Keep in mind that I had some issues with the implementation and the feature could contain some bugs. See #7879. |
@ckeditor/qa-team, could you check how critical are issues described in the #7879 issue? I mean, are we able to merge the feature core and fix bugs later? |
editor.execute( parentCommandName ); | ||
editor.execute( 'listStyles', { type } ); |
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.
Shouldn't we wrap the code in the model#change()
block in order to have single undo step?
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 might do the trick AFAIR. So for now might be OK.
The other thing that came to my mind might be that ListSyyle
command might also do the parentCommand
stuff but as per PR requirements to not-block this PR a wrap will be quicker.
One thing to keep in mind here is that the number of edge cases and weird cases and unclear cases will be significant. I'd heavily prioritize stability over correctness. The other thing is that we're approaching the code freeze, so if the reviewer will stumble upon things that require minor code refactorings, those things should be split to a separate issue, to not block this PR. |
Steps to reproduce
Current resultThe editor crashes. It's interesting, as this manual test doesn't have Bold feature. Error
Can't reproduce it after adding basic styles to the manual tests. Commit: 178ec10. |
Steps to reproduce
Current resultOnly the root item is changed. |
This comment has been minimized.
This comment has been minimized.
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've saw that there are some issues found so maybe checking if using differ
instead of command's events might be relevant.
Abut naming - I've asked that question on the Slack channel as I'm not sure why the plural form and I might be lacking some conversation details.
If I commented something in the UI part - please ignore that. I've forgot instantly that this PR was partially reviewed. I would have some insights for retro though :D
I'll do the jsdocs/tests re-read later on.
To sum up and to not block:
- The feature works, with minor bugs. Which, at least IMHO, we could pass.
- The naming might be the most important one before releasing (PITA to do, but should be fairly fast).
- crashes to be addressed/checked first.
- The event thing (if no time left) should be at least hidden under @Private to have it refactor later as I'm almost 100% sure that we could do the cleanup without it.
* | ||
* @event executeCleanup | ||
*/ | ||
this.fire( 'executeCleanup', itemsToChange ); |
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 would be a new pattern for already existing way of making such cleanups. So I'd say no for this (I might be missing a broader context though).
Ideally, we should make such cleanups using model post-fixer (basically the code that is run in listeners to this event). The itemsToChange
can be obtained from editor.model.document.differ.getChanges()
.
I've used this:
function fixListAfterIndentListCommand( editor ) {
return ( evt, changedItems ) => {
let valueToSet;
const changes = [ ...editor.model.document.differ.getChanges() ];
for ( const change of changes ) {
console.log( change.type, change.attributeKey );
}
const areSame = changedItems.length === changes.length;
console.log( `Event ${ changedItems.length } Differ: ${ changes.length } \t => \tsame? ${ areSame }` );
to check if number of events will be the same as the number of elements touched by the commands. From this perspective it looks like you can obtain changed items from differ without adding an event.
ps.: The number of integration tests might be too small for this (judging just by the number of logged entries when running all list tests):
'attribute', 'listIndent'
'Event 1 Differ: 1 => same? true'
'attribute', 'listIndent'
'attribute', 'listIndent'
'Event 2 Differ: 2 => same? true'
'attribute', 'listIndent'
'Event 1 Differ: 1 => same? true'
'attribute', 'listIndent'
'Event 1 Differ: 1 => same? true'
'attribute', 'listIndent'
'attribute', 'listIndent'
'Event 2 Differ: 2 => same? true'
'attribute', 'listIndent'
'Event 1 Differ: 1 => same? true'
'attribute', 'listIndent'
'Event 1 Differ: 1 => same? true'
'attribute', 'listIndent'
'Event 1 Differ: 1 => same? true'
Process finished with exit code 0
Maybe one test with deeper nesting and/or bigger tree would be nice. So more than 2 items would change.
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 marked the event as private and added _
as prefix. (0143084)
But you're right. Post-fixer could be better solution here.
editor.execute( parentCommandName ); | ||
editor.execute( 'listStyles', { type } ); |
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 might do the trick AFAIR. So for now might be OK.
The other thing that came to my mind might be that ListSyyle
command might also do the parentCommand
stuff but as per PR requirements to not-block this PR a wrap will be quicker.
execute( options = {} ) { | ||
const model = this.editor.model; | ||
const document = model.document; | ||
const position = findPositionInsideList( document.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.
This might cause "single item changed on range selection" issues.
From top of my head:
- Get elements/blocks from selection (to would get all selected list items).
- Use
selection.getFirst/LastPostion()
to get backward/forward siblings.
So I've also found similar issues to the above: The 2-commands action behaves strangely because the first command (list type) changes all items to the other type and the second command (list style) applies style only to the top-most item. So I think that my comment regarding how this command should work is valid (take elements from range or just the same ones as list type command does). ps.: I've might found a bug in the original command as the one item does not change it's type 😮 . |
It's some kind of downcast rendering glitch. I can't reproduce it on fresh content. |
…arked as private.
So as for now, we have three main issues:
Now the feature is called |
@pomek I've updated an unrelated test name as it was bugging me ;) |
Let me add a few tests that you mentioned and I'll check whether |
@jodator, I added missing stuff. It's ready for merge. |
Suggested merge commit message (convention)
Feature (list): Introduced the list styles feature that allows customizing the list's marker of the list item elements. Closes #7801.
Feature (theme-lark): Creates styles for the
ListStylesUI
plugin (see #7803).MINOR BREAKING CHANGE (ui): It is now possible to override existing components when adding new ones to the component factory (previously an error was thrown) (see #7803).
Additional information
UI part of the feature was reviewed in #7845.
Docs: #7881 (can be merged after this PR).