
Problem/Motivation
Noticed while reviewing #3259179: Split ckeditor5_alignment CKEditor 5 plugin, to allow for more precise upgrade path.
Alignment controls show up twice! They are present as dedicated toolbar buttons for given type of alignment, then they also present in a dropdown that includes all enabled alignment options.
Aside from this being noisy and feeling a bit "broken", this is especially confusing for non-sighted users that don't have the visual context clues to confirm these are duplicated controls in a slightly different package. It could be misinterpreted as a navigation bug - returning to an already-navigated element. It may also lead to the false impression that the control does something different without the visual cue of an identical icon.
CKEditor 5's default appears to be the dropdown https://ckeditor.com/docs/ckeditor5/latest/features/text-alignment.html
Steps to reproduce
Proposed resolution
- Keep the dropdown, lose the buttons
- Make the dropdown configurable (similar to headings), where the user can choose what alignment options will be available in the dropdown.
- Modify the upgrade path in
\Drupal\ckeditor5\Plugin\CKEditor4To5Upgrade\Core::mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem()
to instead generate the dropdown, and then also expand::computeCKEditor5PluginSubsetConfiguration()
to generate the appropriate configuration (much like headings).
Remaining tasks
- Implement UI to configure the alignments in the dropdown
- Implement an upgrade path from CK 4 to 5
- Implement an upgrade for already migrated CKE5 configs (to be defined, see #6)
- Implement test coverage both for the functionality and the CKE version upgrade
- Review that all until RTBC
User interface changes
Adds a configuration for the alignments (similarly to what headings does) in the text format configuration page when the alignment dropdown is added to the page.
API changes
The API will need to change in the CKE 4 to 5 upgrade path methods.
Data model changes
Release notes snippet
CKEditor 5 alignment was previously available via individual toolbar buttons or within a single dropdown. It is now only available via dropdown. Existing text formats using the individual buttons will automatically migrated to using the dropdown.
Comment | File | Size | Author |
---|---|---|---|
#57 | 3259593-57-9.3.x.patch | 1.35 MB | wim leers |
#57 | interdiff.txt | 1.32 MB | wim leers |
#44 | 3259593-44.patch | 28.96 KB | wim leers |
#39 | 3259593-39-93x.patch | 28.93 KB | bnjmnm |
#38 | 3259593-38.patch | 28.95 KB | wim leers |
Issue fork drupal-3259593
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
wim leers+1
Comment #3
wim leersThis change will affect the upgrade path too, so added:
\Drupal\ckeditor5\Plugin\CKEditor4To5Upgrade\Core::mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem()
to instead generate the dropdown, and then also expand::computeCKEditor5PluginSubsetConfiguration()
to generate the appropriate configuration (much like headings).Comment #4
wim leersGetting this done would help #3231328: SmartDefaultSettings should select the CKE5 plugin that minimizes creation of HTML restriction supersets — this is not a blocker, but it'd make things simpler and clearer there.
Comment #5
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedComing here from #3273510: CKEditor 5 crash when multiple alignment buttons are activated due to duplicate configuration.
Comment #7
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedPushed my current work on the subject : provide a configurable setup for the dropdown alignment button.
Updating issue "Remaining tasks" : it now takes a CKE 4 to 5 upgrade path and some tests coverage.
Note 1: it is highly likely that the API for the methods for upgrading from CKE 4 to 5 since we will need to keep track of already migrating plugins (or buttons). This is new as it is the first use case of many buttons in CKE4 turning to 1 only with a configuration associated in CK5.
Note 2: I am not sure an upgrade path is necessary for already migrated CKE5 text formats. Indeed, it is currently not possible to use CKE5 with multiple alignments as it crashes, so it is sure the former CKE4 configs are lost as upgrade already occurred and new CKE5 do not have multiple alignments or it would fail.
Comment #8
tim.plunkettComment #9
wim leersThanks so much for pushing this forward, @Dom.! Here's some pointers to help you finish this up:
Drupal\Tests\quickedit\FunctionalJavascript\QuickEditFileTest
failure is unrelated. Random failure, unfortunately.1) Drupal\Tests\layout_builder\FunctionalJavascript\BlockFormMessagesTest::testValidationMessage
→ simple update of the expectations in that test is all that we need.
→ you'll need to update the
Editor::create()
call in\Drupal\Tests\ckeditor5\Kernel\WildcardHtmlSupportTest::testGhsConfiguration()
to check ifin_array('alignment', $additional_toolbar_items, TRUE)
and if so, add the default configuration for the alignment pluginyou will have to update
→ that needs to become
'alignment'
, and you'll need to configure the alignment plugin to only allowcenter
— then the rest of the test should become trivial to update.This needs to be fixed first, and then
SmartDefaultSettingsTest
should be updated.This can be fixed by updating
\Drupal\ckeditor5\Plugin\CKEditor4To5Upgrade\Core::computeCKEditor5PluginSubsetConfiguration()
, look at thecase 'ckeditor5_heading':
code branch for how to do this, we need something similar forckeditor5_alignment
.I think the logic can be as simple as "if any tag allows the
text-align-left
value on theclass
attribute, enable theleft
checkbox for the Alignment plugin's settings". Same thing for right, center and justify.Comment #10
wim leersFYI: this is using the
enabled_alignments
top-level key for its configuration, which means we could add antags
top-level key in #3259367: [upstream] Allow configuring *which* HTML tags can be aligned, when CKEditor 5 adds upstream support for configuring that.IOW: this issue does not do things in a way that more configuration could not be added anymore in the future, which is very important! 👍
Comment #11
wim leers@Dom. I'll start working on this early next week — no pressure on you at all, just letting you know that if you don't get to it, that's completely fine 😊
Comment #12
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedOne test in SmartDefaultSettingsTest should still fail. I have not yet figured why the
<p>
tag is added.Comment #13
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedSomehow I messed up the branch in the middle. Reverted and rebased on 9.4.x to re-apply cleanly. That make the whole ticket verbose to followers, sorry for that, but easier to take back from here for next developer.
Comment #14
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedDuring the CKE4 to 5 process, multiple buttons from CKE4 can merge to one button only in CKE5, for instance the four alignment types in CKE4 now converts to one button only in CKE5.
That creates duplicates during the
createSettingsFromCKEditor4
process as we will get multiple times the same button as a result ofmapCKEditor4ToolbarButtonToCKEditor5ToolbarItem
.There is two approach:
createSettingsFromCKEditor4
after they are all converted.mapCKEditor4ToolbarButtonToCKEditor5ToolbarItem
aware not only on the current CKE4 button being converted, but also the already converted CKE5 buttons and potentially the other CKE4 buttons to be converted.Approach 2 has many implications:
For this purpose, I preferred to deduplicate afterward in
createSettingsFromCKEditor4
. The resulting code is not particularly elegant, maybe some as-readable but more elegant version can be found of this.The purpose is to remove duplicates and empty values. One of each only must be kept, and the groups '|' must be preserved.
Comment #15
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedNote: I still have the additional
<p>
tag added inSmartDefaultSettingsTest.php
that I don't know how to solve.Comment #16
dom. CreditAttribution: dom. as a volunteer and at ACINO commentedAlso in
ValidatorTest.php
, theSourceEditingRedundantTagsConstraint->availablePluginsMessage
still popups, but with no more 'Alignment' in theoverlapping_tags
which is now empty. I don't suppose that constraint should popup at all I guess.Comment #17
wim leers#15: You discovered a bug outside the scope of this MR 🤓 (In
HTMLRestrictions::fromString()
, called by\Drupal\ckeditor5\SmartDefaultSettings::computeNetNewElementsForPlugin()
.) Pushed ef41c4f5ad2bf8539b5de1fdef8429b71f35938a for that.You have two choices here:
to
Comment #18
wim leersFixing the bug I described in #17 is not stable-blocking. This bug is. So I'm making the decision: reverting the test, and fixing it by working around it, i.e. the second choice in #17.Doing that would require also changing this bit in
\Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getProvidedElements()
:So we have no choice but to fix the bug in
HTMLRestrictions::fromString()
.Comment #19
hooroomooComment #20
hooroomoo1. I can't seem to trigger the "ckeditor5_alignment" case in \Drupal\ckeditor5\Plugin\CKEditor4To5Upgrade\Core::computeCKEditor5PluginSubsetConfiguration. While in CKEditor 4, I dragged the justifyLeft button into the active toolbar, then switched to CKEditor5 and I expected that to work. Am I missing something?
2. in #18, I added the change in \Drupal\ckeditor5\Plugin\CKEditor5PluginManager::getProvidedElements():. I'm assuming you also mean to fix the HTMLRestrictions::fromString() bug in this MR. What exactly is the bug? It's not exactly clear to me from the test failure.
3. What test coverage is left that needs to be added?
Comment #21
wim leersI committed 2db233e0 to make test runs faster. The number of failures remains the same, meaning only CKE5 tests are failing 👍
Will now do the revert I mentioned on the merge request 15 minutes ago. This should reduce the number of failures. It's not making a meaningful change, it's just reverting a step in the wrong direction because of my confusing comment at #18 🙈
Comment #22
wim leersSimply doing the revert I mentioned in #21 fixed most failures! The remaining failures look legitimate: the expectations need to be updated. 👍
#20:
Comment #23
wim leersFollow-up issue created: #3278636: HTMLRestrictions::fromString() bug: multiple occurrences of same tag results in only last one being respected.
Comment #24
wim leersBTW, this will be way better than in CKEditor 4 already — see #2569893: CKEditor alignment buttons can be used even when the align filter is disabled + #2649546: [upstream] Alignment/justify buttons not appearing for CKEditor, <p class="text-align-left text-align-center text-align-right text-align-justify"> not being allowed automatically.
Comment #25
hooroomooComment #26
wim leersLet's get this in! 😄
Comment #27
bnjmnmOne of the pending tasks was
. I tested this manually by enabling a single button alignment on HEAD (multiple buttons are known to not work 👉#3273510: CKEditor 5 crash when multiple alignment buttons are activated due to duplicate configuration) then switching to this branch with all the usual cache clears.
Since CKEditor 5 is experimental, I'm not sure this is mandatory, but it would certainly be nice unless it's prohibitively complex. Seems like something an update hook could address?
Comment #28
hooroomooHook adds configuration I want but editor won't load 🤔
Comment #29
wim leersPosted comment on MR with pointers. We want an update path test — see
UpdatePathTestBase
.Comment #30
hooroomooAdded upgrade path test but it fails with
Drupal\Component\Plugin\Exception\PluginNotFoundException : The "ckeditor5" plugin does not exist. Valid plugin IDs for Drupal\editor\Plugin\EditorManager are: ckeditor
But the update hook works now, tested it manually by doing steps in #27
Comment #32
lauriiiComment #33
wim leersStill two unused
use
statements 😅Comment #34
wim leersComment #35
lauriiiComment #36
bnjmnmI went through this and almost committed but spotted two naming/location related things I'd like changed before this gets in.
Id like this to keep the pattern of if being in a subdirectory of Functional (typically Functional/Update)
This fixture filename should be more specific. There may be future update path tests that require different fixtures and it will make them easier to distinguish,
Comment #37
wim leersDid both of those. #36.2 is an interesting remark — the
JsonApiUpdatePathTest
example I linked to also has this weakness 😅 The only example that does this better in core isActionConfigTest
: it makes it more specific by including the d.o issue number. So matched that example.Comment #38
wim leersComment #39
bnjmnmComment #41
bnjmnmThe file references in
CKEditor5UpdateAlignmentTest
need an additional../
now that they're moved.Comment #42
wim leersThe
9.3.x
patch is not applying only because of #3269657: [drupalMedia] The CKEditor 4 → 5 upgrade path for the media_embed filter should not forcefully allow the `data-view-mode` attribute on `<drupal-media>` not yet having been committed to9.3.x
.And … #41: 🙈 — I was not meticulous enough! This time I ran the update path test locally 😅
Comment #44
wim leersAlright, genuinely green now!
So, back to RTBC, and a patch to test against all branches :)
Comment #45
wim leersNote: not testing #44 against
9.3.x
yet because #3269657: [drupalMedia] The CKEditor 4 → 5 upgrade path for the media_embed filter should not forcefully allow the `data-view-mode` attribute on `<drupal-media>` needs to be cherry-picked first.Comment #46
bnjmnmComment #50
bnjmnmThe update test is failing on 9.3.x. Will investigate what would be needed for a 9.3 backport.
Comment #51
wim leersIt's odd that https://www.drupal.org/pift-ci-job/2380478 lists no useful output at all 🤯
And … I checked out
9.3.x
HEAD locally. That works fine. I tested using PHP 7.4 though. Queued a PHP 7.4 test run. Seems to confirm that the problem is specific to PHP 7.3.Comment #52
lauriiiI think the output is available here: https://dispatcher.drupalci.org/job/drupal_patches/128502/testReport/jun...
Comment #53
wim leers😮 I've never seen that UI before. Odd that it's not available on d.o's usual output page… Since Jenkins results disappear after a while, copy/pasting for posterity:
→ the pattern described in #3152660: Symfony routing problems in 9.01 + #3145563: Route serialization incompatibilities between PHP 7.4 and 7.3 (9.x only).
Comment #54
wim leersUn-RTBC'ing for 9.3 to signal current status correctly.
I won't get to this today, but I will next week. Fine by me if somebody else figures this one out though!
Comment #55
larowlanTo fix that error, you have to dump the DB on php 7.3
Last time this happened, I took some notes for the future https://www.drupal.org/project/drupal/issues/3275093#comment-14481944
So the DB dump needs updating basically
Comment #56
wim leersThanks!
Comment #57
wim leersHah — after attempting to redo the crazy things @larowlan linked in #55, I realized something: its results were committed to
9.4.x
only.So what if I just cherry-pick those two files instead?
That worked! 🤓
So basically this patch is:
→ only the "bare" dump changes.
Comment #58
wim leersPatch applied successfully (wasn't sure about that due to binary diff), so back to RTBC: test should pass on DrupalCI on PHP 7.3 too.
Comment #59
alexpottCommitted a9a0696 and pushed to 9.3.x. Thanks!