Problem/Motivation
Webform is currently using customized CKEditor 4, included with Drupal 8 and 9. Drupal 10 ships with CKEditor 5.
Proposed resolution
Replace Webform's custom CKEditor with hidden default 'webform' only text format/editor.
The Webform module provided a custom instance of the CKEditor, which added additional dependencies and maintenance challenges. The Webform module now provides a default hidden 'webform_default' text format that leverages Drupal core's editor and CKEditor modules.
The new default 'webform_default' text format is completely hidden from all instances of the text format element and the admin UI. The approach allows the new default 'webform_default' text format to be backward compatible and fully maintained by the Webform module.
Steps to review
- Install webform 6.2.x
- Confirm that old default ckeditor is working as expected. /admin/structure/webform/config
- Apply patch
- Run database updates
- Confirm that the webform text format and editor is installed via config export
- Confirm that new ckeditor is working as expected. /admin/structure/webform/config
- Confirm that the element and mail format are set to webform. /admin/structure/webform/config/elements
- Confirm that existing HTML with BR tags is converted to P tags and wrapped P tags
- Confirm that custom HTML attributes are supported
- Reinstall with a patch applied and confirm webform text format is installed
- Confirm that the default webform text format is hidden and not configurable.
Version installation and upgrade manual tests
Install Webform 6.2.x and Drupal 9.4 with CKEditor patch.
- Confirm CKEditor4 is used
Install Webform 6.2.x and Drupal 9.5 with CKEditor patch. CKEditor5 is part of the standard.profile in Drupal 9.5+
- Confirm CKEditor5 is used
Install Webform 6.2.x and Drupal 10.0 with patch
- Confirm CKEditor5 is used
Install Webform 6.2.x and Drupal 9.4 without CKEditor patch.
- Confirm Custom CKEditor is used
Upgrade Webform 6.2.x and Drupal 9.4 with CKEditor patch.
- Confirm Text format CKEditor4 is used
Upgrade from Drupal 9.4 to Drupal 10.0 with CKEditor and D10
- Note: Missing rdf and ckeditor modules will display errors.
- Confirm no editor is used because ckeditor module is missing and ckeditor5 module is not installed.
Install CKEditor5 module.
- If the rdf and ckeditor modules are missing, go to /admin/structure/webform/config/elements and 'Save configuration', and confirm Text format CKEditor5 is used
- If the rdf and ckeditor modules are NOT missing, confirm Text format CKEditor5 is used
Remaining tasks
- Write patch
- Review patch
- Commit patch
User interface changes
New default webform text format/editor has the same buttons but does not support the codemirror source mode. Some other feature might be missing.
General/API changes
- Adds editor.editor.webform_default.yml
- Adds filter.format.webform_default.yml
- Removes all ckeditor libraries
- Removes custom ckeditor JS
Data model changes
TBD
| Comment | File | Size | Author |
|---|---|---|---|
| #54 | 3322552-54.patch | 86.23 KB | jrockowitz |
| #51 | 3322552-51.patch | 82.23 KB | jrockowitz |
| #48 | 3322552-49.patch | 79.97 KB | jrockowitz |
| #47 | 3322552-46.patch | 80.29 KB | jrockowitz |
| #44 | 3322552-44.patch | 73.47 KB | jrockowitz |
Issue fork webform-3322552
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
jrockowitz commentedI am having a very difficult time reusing Drupal core's version of CKEditor. As far as I can tell core is generating the editor based on YAML configuration files. I am not able to determine which libraries are required to build a simple isolated CKEditor. I am going to ask for help via Drupal Slack.
Comment #3
wim leersTo paraphrase @acbramley from Slack:
In Slack you wrote:
😱 This was never supported by the CKEditor (4) module in Drupal core! This is not using the API provided by Drupal.
You chose to use the CKEditor 4 API directly (i.e. https://ckeditor.com/docs/ckeditor4/latest/guide/index.html).
… that's not just any example, that is a really crucial atypical behavior 😱 You used https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html... to achieve this.
And per https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/... … I'm afraid CKEditor 5 won't support this anymore:
.
… so the only potential solution I see for you is to create a custom
htmlWriterplugin that still allows<p>in the editor but converts them to<br>when converting ("downcasting") to actual HTML. Fortunately we have somewhat of an example for you in Drupal core:core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/*.Comment #4
wim leersComment #5
jrockowitz commentedIf we want to roll a custom editor for webform... is it still possible to include the ckeditor5 libraries from Drupal core and create a custom editor?
Here is an example of my attempt to load the required libraries and initialize a basic editor. No errors are logged, but the editor is disabled. When I start adding plugins to the editor, I get a whole bunch of different errors.
I need a tiny push in the right direction or someone to say it is not feasible to reuse core ckeditor5 libraries.
Comment #6
nigelcunningham commentedPerhaps it's asking if it's worth the pain? Perhaps doing things the Drupally way is the go?
Comment #7
joseph.olstad***EDIT***
the issue I'm describing here occurs whether or not a wysiwyg editor is used, even on non-wysiwyg fields for labels edited with input boxes in the webform translation ui. So I thought some more and questioned the assumption below as probably incorrect which is why I'm editting my own comment here.
*** END EDIT ***
This above issue discussed by @Wimleer might explain why we're still observing this issue with +64kb long webform translations
#2836206: [Translations] Translation of big webforms broken
for some reason webforms is processing translations as a single line when saving translations with the web gui interface, however if importing with drush the correct multiline translation import is working (provided the
\r\nare replaced first).#2844452: Export configuration YAML strings as multiline
Comment #8
jrockowitz commentedCKEditor support for Webform the Drupally way
Comment #9
joseph.olstadI'd like to trigger tests, I'm also going to try to test this with 9.4.8 and ckeditor5 (enable this core module)
Comment #10
joseph.olstad@jrockowitz,
line 731 of your merge request
js/webform.element.html_editor.ckeditor..js: {}this line was probably instead intended to be like this:
js/webform.element.html_editor.ckeditor.js: {}Could this explain your trouble?
Comment #12
joseph.olstadTriggered a Drupal 10 test (manually)
Triggered a Drupal 9.4 test (was automatic)
Comment #13
joseph.olstadok I ran 6.2.x-dev with this MR branch on a site with: Drupal 9.4.8,
I enabled the ckeditor5 module however the text format default remained the same when I was editing webform configurations (advanced html form items using the GUI).
I tested also the translation of webforms, didn't notice any change in behavior here.
the ckeditor 1.0.1 module (ckeditor v4) was still trying to find library files:
Not Found
The requested URL "http://f7fb44f3-5fdf-4283-ac13-7b0b4f153111.web.ahdev.cloud/modules/cont..." was not found on this server.
Not Found
The requested URL "http://f7fb44f3-5fdf-4283-ac13-7b0b4f153111.web.ahdev.cloud/modules/cont..." was not found on this server.
In Drupal 9.4.8, ckeditor version 5 is included with Drupal 9.4.8 core however ckeditor 4 is now a contrib module.
the new html_editor.element_format I couldn't confirm if this was actually working or not, I didn't notice a difference before or after using the 6.2.x-dev with the above branch.
one thing I did test is I did uninstall the ckeditor module, once I did this, gutenberg kicked in but ckeditor 5 was not visible.
I also tested a super long translation of a super long webform > 64 kilobytes in the configuration file, no change in behavior, could not save a change in any version of webform with any branch or release, the
\r\nsingle line locales_source blob limit problem issue is caused somewhere else inside drupal (the webform module?) because I could not save a change through the GUI interface of the translated webform, only could do that using drush cim after having a clean yml file (drush webform-tidy) (drush webform-tidy very useful btw). So unfortunately I'm still looking for a solution to :#2836206: [Translations] Translation of big webforms broken
Comment #14
joseph.olstadconclusion:
More testing is needed, suggest testing these changes with Drupal 10
As for these changes on Drupal 9.4.8, I didn't notice much change at all, with that said, it didn't seem to bring up the ckeditor5 even when the ckeditor5 module was enabled. Perhaps there's a webform settings change needed for the new text format.
seems to still need work but good start so far.
Comment #15
jrockowitz commented@joseph.olstad I think the current branch is worthless, and the new branch will need to be cut. By the way, I think for 6.2.x, we will probably take the approach in #8 for D9 and D10.
Comment #16
joseph.olstad@jrockowitz, may the force be with you, I'll test your new branch out whenever it comes.
Comment #21
jrockowitz commentedTesting new patch, which needs work and documentation.
The attached patch replaces the custom CKEditor for Webform 6.2.x and Drupal 9 with a 'webform' text format.
Below is the before and after.
Comment #24
jrockowitz commentedComment #30
jrockowitz commentedComment #33
jrockowitz commentedComment #34
jrockowitz commentedComment #37
jrockowitz commentedComment #38
jrockowitz commentedComment #41
jrockowitz commentedComment #42
jrockowitz commentedComment #44
jrockowitz commentedComment #46
joseph.olstad@jrockowitz, I quickly tested your new branch with D9.4.8
installed the ckeditor5 core module however when I uninstalled ckeditor4 it uninstalled two text formats (kinda expected)
next time I'll try with both ckeditor5 and ckeditor4 installed.
Comment #47
jrockowitz commentedI had to move the ckeditor switching to hook_requirements. If you have the ckeditor and ckeditor5 module enabled it should figure out the right version,
Comment #48
jrockowitz commentedThis patch is ready for a full review.
Comment #49
jrockowitz commented@Wim Leers @Nigel Cunningham Thanks for the nudge to avoid using a custom CKEditor. The new approach still has some custom code to hide the webform's text format, but it should be much easier to maintain and compatible with future versions of Drupal and CKEditor.
Comment #50
jrockowitz commentedThe MR should now also be up-to-date.
@see https://git.drupalcode.org/issue/webform-3322552/-/tree/3322552-ckeditor...
Comment #51
jrockowitz commentedComment #53
joseph.olstad@jrockowitz
Great work!
I saw the dependency error, I added an upstream ticket for Drupal 10 support of that dependency.
#3326466: Offering to maintain jQuery UI Checkboxradio
the related dependency found in the 1 failure needs a D10 release.
I haven't yet looked at the test code closely to see about a fix
Comment #54
jrockowitz commentedWe need to ignore the failing test which is NOT related to CKEditor support.
@see https://www.drupal.org/pift-ci-job/2542827
Comment #55
wim leersSorry for my silence here! 😬 But excellent progress! 🤩
#5: that is an excellent question! Sadly, the links you posted no longer work … probably because you rebased in the mean time (GitLab strikes again 😬).
#49: oh, NICE! Even better :)
If I understand #54 correctly, then it's still keeping CKEditor 4 support around, just switching it to the same "hidden text format/editor" approach.
😳🤔 Route-based runtime config entity altering … I am not quite sure if this is actually free of side effects …
AFAIK the correct/supported way to do this is through
\Drupal\Core\Config\ConfigFactoryOverrideInterface.Or … maybe better yet, I'm wondering if we can work around this at the
\Drupal\filter\FilterFormatListBuilderlevel by using access control logic 🤔That class determines which
FilterFormatconfig entities to list using\Drupal\Core\Entity\EntityListBuilder::getEntityIds().I checked to see if one could use
hook_query_alter()to apply this restriction, but that is not possible, because\Drupal\Core\Config\Entity\Query\Query::execute()does not use the DB query API 😬So I suggest subclassing
FilterFormatListBuilder, overridinggetEntityIds()and then overriding the"list_builder" = "Drupal\filter\FilterFormatListBuilder"entity type annotation.(I doubt anybody else has the same need … http://grep.xnddx.ru/search?text=FilterFormatListBuilder&filename= finds 2 matches, but they're just copy/paste leftovers 👍)
🤔 Why not do this instead?
P.S.: seems like this is the contrib use case that would justify adding
FilterFormat::isLocked(), which 5 config entity types in Drupal core already have!Comment #56
jrockowitz commentedThanks for the review.
The main issue with webform_entity_filter_format_access() is that for administrators, a.k.a USER1, entity access checks are disabled.
Still, you are right that webform_entity_filter_format_access() should be added to prevent non-admins from accessing the webform default filter at an API level.
Overriding Drupal\filter\FilterFormatListBuilder only accounts for the filter format list page, I also want to ensure no one can alter the webform default filter by calling the filter format edit form.
Besides adding webform_entity_filter_format_access(), I'm going to also add a dedicated WebformFilterFormatDefaultAccesssTest to ensure we test all edge cases and track side effects.
Comment #57
jrockowitz commentedOnly allowing access to 'use' the format prevents an admin from updating the hidden webform default format.
@see https://git.drupalcode.org/project/webform/-/merge_requests/254/diffs#97...
Removing the hidden webform default format from /admin/config/content/formats can't be done via access checks. I feel the current approach via route detection in webform_filter_format_load() is the simplest solution without conflicting with other modules.
@see https://git.drupalcode.org/project/webform/-/merge_requests/254/diffs#97...
I added dedicated test coverage to check access and track edge cases.
https://git.drupalcode.org/project/webform/-/merge_requests/254/diffs#5d...
I am open to overriding \Drupal\filter\FilterFormatListBuilder.
Comment #58
wim leersIIRC,
AccessResult::forbidden()applies always, including to user 1.IIRC, the only thing that is special cased is that user 1 automatically gets all permissions, but that doesn't mean everything is necessarily accessible. See
\Drupal\user\Entity\User::hasPermission().A quick check of
\Drupal\Core\Entity\EntityAccessControlHandler::access()appears to confirm this. But I can definitely be wrong.Comment #59
jrockowitz commented#58 @Wim Leers Thanks for confirming what I saw in my testing.
Comment #60
jrockowitz commentedThere is enough test coverage to ensure the hidden webform default format is not accessible; even if it appears on the text format list page.
I will merge this MR to push people to test and review the change/improvement in the last dev and beta releases. I will hold off tagging a stable release of 6.2.x until next year.
Comment #62
jrockowitz commented