Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
SourceEditingRedundantTagsConstraintValidator
currently only ensures that tags listed explicitly for source editing indeed has no available CKEditor 5 plugin that supports that tag.
We need to do the same for attributes and attribute values.
With the introduction of #3228334: Refactor HTMLRestrictionsUtilities to a HtmlRestrictions value object, that becomes simple.
Steps to reproduce
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#58 | 3260857-58-9.3.x.patch | 16.84 KB | Wim Leers |
#51 | 3260857-51-9.3.patch | 16.84 KB | Wim Leers |
#51 | 3260857-51.patch | 16.82 KB | Wim Leers |
| |||
#51 | interdiff.txt | 3.19 KB | Wim Leers |
#51 | Screenshot 2022-03-25 at 14.26.02.png | 151.26 KB | Wim Leers |
Comments
Comment #2
Wim LeersComment #3
Wim Leers#3228334: Refactor HTMLRestrictionsUtilities to a HtmlRestrictions value object is in!
We can now proceed here. This patch is for now just deleting the early return that was necessary up until we'd start working on this issue. We should begin with adding more test coverage.
Comment #5
Wim LeersComment #6
Wim LeersOnly CKE5 tests.
Should fail just like #3, perhaps in more places, because >1 month worth of new tests have been added since then.
Comment #7
Wim LeersTest attribute already provided by enabled plugin.
❌ This new test should fail!
Note: this is not yet enough to remove
— we also still need to test the "disabled plugin" case.Comment #8
Wim LeersSupport attribute detection.
✅ Should pass the test added in #7.
Comment #12
Wim LeersHuh, the patches in #7 and #8 are wrong, but the interdiffs are right 🙈
Comment #15
Wim LeersThat's better 😊😅
We can see now that the (correct) #7 patch causes one additional failure thanks to its extra test coverage, and the (correct) #8 patch fixes that one failure.
Progress! 🥳
Comment #16
Wim LeersNow it's time to add the test coverage that #7 mentioned is still needed. Which allows us to remove the tag.
❌ This new test should fail!
Note: this not only tests the "support for this manually enabled attribute can be provided by some disabled plugin" case, but simultaneously verifies that
SourceEditingRedundantTagsConstraintValidator
finds such plugins even if it's provided by a wildcard element. 👍Comment #18
Wim LeersMake the
SmartDefaultSettingsTest
failures easier to debug.(This copies the pattern from
\Drupal\Tests\ckeditor5\Kernel\ValidatorsTest::test()
.)Comment #20
Wim Leers#18 made it clear that
\Drupal\ckeditor5\Plugin\Validation\Constraint\SourceEditingRedundantTagsConstraintValidator::validate()
is too eager.Comment #22
Wim LeersWe're almost there — it seems all of the failures are for the tricky wildcard case that #16 added.
This also made me realize that the existing test coverage is not clear enough and does not yet quite cover all edge cases. Expand it.
(For this interdiff,
git diff --color-words
would've been a lot clearer.)Comment #24
Wim Leers#22 caused
ValidatorsTest
to fail … "harder".This will make the
<img src>
test case added in #22 pass, so that we're back at the same exact set of failures as in #20. But now more firmly in the final stretch 🤓Comment #26
Wim LeersIn scrutinizing #24 I realized there was one more missing test that would not need a violation message: the case of an attribute not supported by any plugin.
Comment #28
Wim LeersCKEditor5AllowedTagsTest::testFullHtml()
has been failing because<img src alt height width data-entity-type data-entity-uuid data-align data-caption>
is in the source editing list, becauseSmartDefaultSettings
cannot enable it. This has been the case all along, but we simply didn't have the validation logic nor the test coverage up until now!It resulted in a validation error like this:
The following tag(s) are already supported by available plugins and should not be added to the Source Editing "Manually editable HTML tags" field. Instead, enable the following plugins to support these tags: .
First, let's add a kernel test equivalent of
CKEditor5AllowedTagsTest::testFullHtml()
— to test explicitly what was tested implicitly until now.Comment #29
Wim LeersThe fix for
CKEditor5AllowedTagsTest::testFullHtml()
and the test case added in #28.Comment #30
Wim LeersAnd finally, the fix for the tricky edge case for which a failing test was added in #16!
✅ Should pass all tests now!
Comment #34
Wim LeersThe two remaining failures in the one failing test have existed since the beginning, since #3. They're very similar:
+
in both cases, the validation constraint is complaining that a particular plugin is already enabled. But … that is impossible.
Turns out that this has been a subtle bug in
SmartDefaultSettingsTest
for all this time! 🙃 The bug: it was using the storedFilterFormat
rather than the updated one.Comment #35
Wim Leers… and #34 fixed the two failing test cases, but it broke two others. Turns out that there's been another bug hiding in
SmartDefaultSettingsTest
's infrastructure for a long time! 🙃A bug never comes alone.
Comment #36
Wim Leers🤓🤓🤓🤓🤓🤓🤓🤓 All of this is reminding me an awful lot about
SmartDefaultSettings
.Just look at this:
Especially now that we just finished #3231328: SmartDefaultSettings should select the CKE5 plugin that minimizes creation of HTML restriction supersets.
… and this is pretty much a less advanced version of
\Drupal\ckeditor5\SmartDefaultSettings::computeNetNewElementsForPlugin()
!What
SourceEditingRedundantTagsConstraintValidator
does is basically the same thing asSmartDefaultSettings
: the "needed" elements are the ones configured by the user as "manually editable tags"; the goal is to find enabled or disabled plugins that meet those needs, because that would mean that a better solution exists, and hence that should be the validation error.While we could do that, perhaps that's best left as a follow-up? I think that'd be too much of a scope increase. Especially because it would require refactoring
SmartDefaultSettings
, to intentionally open up someprivate
methods.Comment #38
lauriii#36 seems like something that could be handled by a follow-up.
Should revert changes to this file 😇
Should we explicitly document what this means for plugins that support a superset?
Do we have test coverage for this? 🤓
The reason I'm wondering that is because it's unclear what's the expected behavior here.
Probably should be reverted
Comment #39
Wim Leers#38
\Drupal\ckeditor5\SmartDefaultSettings::computeSurplusScore()
— in other words: all the more reason to do what I proposed in #36 … 🤓INVALID Source Editable tag already provided by plugin and another available in a not enabled plugin
test case inValidatorsTest::testPair()
. Attached a patch here to prove that without this, tests fail.Comment #40
Wim Leersphpcs
getting in the way just when proving something … 😬Comment #42
lauriiiThis is what I was wondering, what if the user doesn't want to enable the plugin because it provides a superset?
Comment #43
Wim LeersFollow-up created: #3271179: Update SourceEditingRedundantTagsConstraintValidator to reuse SmartDefaultSettings. Already posted PoCs there that are largely passing tests.
Comment #44
Wim LeersSmartDefaultSettings
already contains this kind of logic! I'm happy to include that in that scope too.Comment #45
Wim LeersHuh, apparently the patch does not apply to 9.3 due to a slight difference in 9.3 caused by #3106216: Remove unused variables from core 😬
git apply -3
applies the patch in #44 just fine … but here's a 9.3-specific one anyway.Comment #47
Wim LeersThe 9.3 patch only fails because #3263384: Add ckeditor5-code-block package and CodeBlock plugin has not yet been committed to 9.3, which will happen in #3269651: Update Drupal 9.3.x to CKEditor 5 v34.0.0 along with other un-backported issues. IMHO we should apply the same strategy here: commit to 10+9.4, and cherry-pick the commit in #3269651, along with #3263384.
Comment #48
Wim LeersComment #49
lauriii#44.2 Makes sense, let's work on that in the follow-up then.
The 9.4.x and 10.0.x patch in #44 is RTBC.
Comment #50
bnjmnmI looked at everything other than
ValidatorsTest.php
- I don't expect much (if any) feedback on that, so here's what I have before I sign off for the day:And we don't have to worry about unsetting a disabled ckeditor5_sourcediting (that may have config from prior use) because this validation only runs if it is enabled, yea?
This phrasing is unclear due to the flexible nature of the word 'just'. Two valid readings could be does "plugins that were very recently enabled" and "only plugins that are enabled".
There's also "A plugin with high moral integrity", but that one is pretty easy to rule out via context 🙂.
I'd like to position the comments closer to the code they reference, here's a suggestion:
The 'correctly' reads oddly, as if we'd intentionally done it wrong earlier in the method.
Is there a risk here of unwanted filtering if the plugin includes a combination of wildcards and concrete tags?
This comment doesn't quite line up with the unset of something keyed with an empty string (and is it necessary to isset that?).
Based on context, I assume any remaining fundamental errors are in
''
, but that's just a guess.None of these strike me as significant enough to require a 2nd reviewer to RTBC. Whoever makes the changes is welcome to re-RTBC if they're inclined.
Comment #51
Wim Leers$plugin_capabilities
). If it has wildcards, we first merge the elements already allowed by enabled plugins ($enabled_plugin_restrictions
). This allows the wildcards of$plugin_capabilities
to resolve into concrete tags. Then when we omit the$enabled_plugin_restrictions
again, the resolved tags remain. These are the tags that would actually be added.I first thoguht you meant "what if there is a combination of wildcard and concrete tags" in
$enabled_plugin_restrictions
. This shows that that is not the case:Then I realized you might've meant
$plugin_capabilities
instead. Well, this shows that that is also not the case:As you can see, in both cases, the result in
$test
contains the net new HTML elements supported by adding the new plugin whose capabilities are shown in$plugin_capabilities
.I tried to be thorough 🤓
See
\Drupal\ckeditor5\Plugin\Editor\CKEditor5::validatePair()
, which contains:That's right! The difference is that
\Drupal\Tests\ckeditor5\Kernel\CKEditor5ValidationTestTrait::validatePairToViolationsArray()
doesn't omit anything (because in tests we want to be as strict and complete as possible), whereas\Drupal\ckeditor5\Plugin\Editor\CKEditor5::validatePair()
allows you to omit those :)Comment #55
bnjmnmCommitted to 10.0.x and cherry-picked to 9.4.x. There is a failing test on 9.3.x, which appears to be expecting Code Block, a recent update that is postponed on being added to 9.3 #3263384: Add ckeditor5-code-block package and CodeBlock plugin.
I added this as a proposed backport in the 9.3 + CK 33 issue #3269651: Update Drupal 9.3.x to CKEditor 5 v34.0.0 along with other un-backported issues, and I'll label this as fixed.
Comment #57
catchRe-opening for 9.3.x backport.
Comment #58
Wim Leers#51's 9.3.x patch failed only due to #3263384: Add ckeditor5-code-block package and CodeBlock plugin not yet having been cherry-picked. Let's verify that that is true.
Comment #60
lauriiiCommitted e678d0c and pushed to 9.3.x. Thanks!
Comment #62
Wim LeersFollow-up: #3396628: Fix <ol start> → native CKEditor 5 functionality and fix bug in SourceEditingRedundantTagsConstraintValidator that allowed it to slip by.