data-ck-unsafe-element on plugin custom tag

Created on 26 January 2023, almost 2 years ago
Updated 14 March 2024, 8 months ago

Problem/Motivation

I have created a custom ckeditor5 plugin (run with Drupal 9) and that all works fine for initial editing and output. It creates a custom tag eg: <bbref ver="RSV">Ex 2:32</bbref>
A couple of days later (possibly after 9.5.2 update?) the editor now rejects my tag when it loads saved HTML (or creating new) and replaces it with <span data-ck-unsafe-element="bbref" ver="RSV">Ex 2:32</span> which is styled to be invisible in the editor.

ckeditor's domconverter.js seems to have a hand in this.

There is a method for handling a similar thing with data-ck-unsafe-attribute- (eg https://ckeditor.com/docs/ckeditor5/latest/updating/guides/update-to-31....) but not for unsafe-element and trying the unsafe-attribute method does not seem to work:

// Callback function provides access to the model attribute value
            // and the DowncastWriter
            view: (modelAttributeValue, conversionApi) => {
                const {writer} = conversionApi;
                const cae =  writer.createAttributeElement(
                        'bbref',
                        {
                            ver: modelAttributeValue
                        },
                        {
                            renderUnsafeAttributes: ['ver', 'bbref']
                        });
                console.log('cae');
                //console.dir(cae);        
                return cae;
            }

Current core: 9.5.2
Using full_html text format, 'Limit allowed HTML tags and correct faulty HTML' and 'Correct faulty and chopped off HTML' both disabled.

Steps to reproduce

Add any custom tag to ckeditor (ie using source-edit facility), switch back to normal editing. The text disappears and inspecting the element shows <span data-ck-unsafe-element="mytag" ...

Proposed resolution

Stop ckeditor 5 marking unknown tags.
Provide a method to bypass
Note: you cannot add accepted tags to 'Limit allowed HTML tags and correct faulty HTML' anymore, and notes: 'With CKEditor 5 this is a read-only field....'

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

๐Ÿ’ฌ Support request
Status

Fixed

Version

11.0 ๐Ÿ”ฅ

Component
CKEditor 5ย  โ†’

Last updated 1 day ago

Created by

๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @Jons
  • Status changed to Postponed: needs info almost 2 years ago
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Please report this upstream โ€” this is not something Drupal can fix/support, it must be reported upstream: https://github.com/ckeditor/ckeditor5.

    At this point, I'm not even sure if it's a bug report or a feature request! ๐Ÿ˜… So I'll settle for "task".

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    BTW Working through the ckeditor sample plugins, all the code is local in node_modules etc
    When transferring to running under drupal the structure is not the same.
    I worked out the import path changes.
    I can see ckeditor5-dll.js in core/assets/... and the plugins in core/modules/ckeditor5/js/ckeditor5_plugins
    Also clues in core/modules/ckeditor5/js/build/ckeditor5.types.jsdoc
    But could full structure be documented please to help with debugging?

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    I created a standalone version of the plugin with local paths (ie so runs like one of the example plugins) (uploaded to github issue). This works fine so the issue seems to be something to do with the Drupal environment? Both are running the same version of CKE (34.2.0) according to window.CKEDITOR_VERSION

    Looking at unminified ckeditor5-dll.js it seems to be evaluated in cjs.js which is passed various rules:

                    "./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./packages/ckeditor5-engine/theme/renderer.css": (e, t, o) => {
                        "use strict";
                        o.d(t, { Z: () => n });
                        var s = o("./node_modules/css-loader/dist/runtime/api.js"),
                            i = o.n(s)()(function (e) {
                                return e[1];
                            });
                        i.push([e.id, ".ck.ck-editor__editable span[data-ck-unsafe-element]{display:none}", ""]);
                        const n = i;
                    },

    This seems to be in one of the loaders as not in core ckeditor5 source on github, from what I can see (https://github.com/ckeditor)

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Looks like you're getting closer to the answer in the CKEditor 5 issue queue! ๐Ÿ˜Š๐Ÿ‘

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    Wim, yes looks like I'll need to debug the Drupal setup - could you advise easiest way to build a 'source' version of web/core/assets/vendor/ckeditor5/ckeditor5-dll/ckeditor5-dll.js with same loaders etc? package.json, webpack.config.js are obviously not in the core area.

    I guess along these lines https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/alterna...

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    IIRC that is just the yarn build:ckeditor5-dev command that core's package.json provides! ๐Ÿ˜Š

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    Hi Wim
    Tried that:

    $ yarn cache clean
    โžค YN0000: Done in 0s 1ms
    jon@nat:/var/www/ktt/web/core$ yarn build:ckeditor5-dev
    Internal Error: Drupal@workspace:.: This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile
        at Cb.getCandidates (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:435:5146)
        at zf.getCandidates (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:391:1264)
        at /home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:439:7695
        at Ff (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:390:8965)
        at ge (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:439:7675)
        at async Promise.allSettled (index 0)
        at async eo (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:390:8293)
        at async /home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:439:8205
        at async ni.startProgressPromise (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:390:45507)
        at async He.resolveEverything (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:439:6238)
    
    
    $ yarn install
    โžค YN0000: โ”Œ Resolution step
    โžค YN0013: โ”‚ farbtastic@https://github.com/mattfarina/farbtastic/archive/1.3u.tar.gz can't be found in the cache and will be fetched from the remote server
    โžค YN0013: โ”‚ joyride@https://github.com/zurb/joyride/archive/refs/heads/v2.1.tar.gz can't be found in the cache and will be fetched from the remote server
    โžค YN0061: โ”‚ picturefill@npm:3.0.3 is deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
    โžค YN0032: โ”‚ fsevents@npm:2.3.2: Implicit dependencies on node-gyp are discouraged
    โžค YN0061: โ”‚ request@npm:2.88.2 is deprecated: request has been deprecated, see https://github.com/request/request/issues/3142
    
    โžค YN0001: โ”‚Error: farbtastic@https://github.com/mattfarina/farbtastic/archive/1.3u.tar.gz: Manifest not found
        at el.find (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:390:29961)
        at async /home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:601:11496
        at async Object.Gbe (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:390:8896)
        at async yQ.resolve (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:601:11457)
        at async zf.resolve (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:391:1400)
        at async zf.resolve (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:391:1400)
        at async /home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:439:6346
        at async Ff (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:390:8959)
        at async Z (/home/jon/.cache/node/corepack/yarn/3.3.1/yarn.js:439:6328)
        at async Promise.allSettled (index 43)
    โžค YN0000: โ”” Completed in 2s 892ms
    โžค YN0000: Failed with errors in 2s 896ms
    โžค YN0061: request-promise@npm:4.2.6 is deprecated: request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
    โžค YN0061: debug@npm:3.2.6 is deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)
    โžค YN0061: mkdirp@npm:0.5.4 is deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
    โžค YN0061: har-validator@npm:5.1.5 is deprecated: this library is no longer supported
    โžค YN0061: uuid@npm:3.4.0 is deprecated: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
    โžค YN0061: @npmcli/move-file@npm:2.0.1 is deprecated: This functionality has been moved to @npmcli/fs
    

    I've tried related actions with npm and get similar problems with farbtastic, also if trying to add packages in package.json manually

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    The above build issues were related to using the latest yarn version (v3) - yarn v1 is needed! (see https://github.com/ckeditor/ckeditor5/issues/13340).
    The page https://www.drupal.org/docs/core-modules-and-themes/core-modules/ckeditor-5-module/ckeditor-5-development โ†’ has been updated to note this.
    I was able to do a debug build - which is complicated with all the yarn-linking but could not see exactly where this was happening.
    I did a CSS work-round so the data was at least visible.

    However - in 'Text formats and editors' if the filter 'Limit allowed HTML tags and correct faulty HTML' is enabled the problem goes away...
    This is in core/modules/filter/src/Plugin/Filter/FilterHtml.php
    Again it's not clear how this is affecting ckeditor5

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    Now on Drupal 9.5.4
    The custom tag (and others like abbr) are now being stripped off when viewed if in 'Text formats and editors', the filter 'Limit allowed HTML tags and correct faulty HTML' is enabled.

    This is done by Xss::filter() in process() (core/modules/filter/src/Plugin/Filter/FilterHtml.php) as the allowed tags do not include our custom tag.
    The 'restrictions' are:<br> <p> <h2> <h3> <h4> <h5> <h6> <strong> <em> <blockquote> <a href> <ul> <ol reversed start> <li> <table> <tr> <td rowspan colspan> <th rowspan colspan> <thead> <tbody> <tfoot> <caption> <img src alt height width data-entity-uuid data-entity-type data-caption data-align> <drupal-media data-entity-type data-entity-uuid alt data-caption data-align>
    as shown on the configuration page but are read-only as apparently come from ckeditor. It's not stated how to set them there.

    Note this filter operates on normal view not just when saving in ckeditor.

    If the filter 'Limit allowed HTML tags and correct faulty HTML' is switched off the custom tag is shown correctly on view and edit - no data-ck-unsafe-element

    I could not see a release note on filters or ckeditor in Drupal 9.5.4

    It would be good to confirm what should happen and how to add a custom tag if you want 'Limit allowed HTML tags and correct faulty HTML' switched on.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    #10: Thanks for updating the docs! ๐Ÿ‘

    The custom tag (and others like abbr) are now being stripped off when viewed if in 'Text formats and editors', the filter 'Limit allowed HTML tags and correct faulty HTML' is enabled.

    That must mean that the metadata you've declared for your custom CKEditor 5 plugin is incomplete. See https://api.drupal.org/api/drupal/core%21modules%21ckeditor5%21ckeditor5..., specifically this bit:

        elements:
          - <marquee>
          - <marquee behavior>
    

    Read the documentation associated with that metadata, and then it should make sense :)

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    @wim These lines were missing. I my case changing from false to

          - <bbref>
          - <bbref ver>

    as I have one attribute 'ver'

    For info: to make editor pickup change: in text format - after enabling 'Limit allowed HTML tags and correct faulty HTML' filter, remove your plugin from text format, save, edit text format again and re-add.

    BTW A related issue - not specifically to do with the above filter:
    The attribute 'ver' is logically optional but in ckeditor5 it must be present (even as 'ver=""') otherwise ckeditor5 will not recognise the tag and removes that markup. Is there a way to configure an optional attribute?

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    The presence of

          - <bbref ver>
    

    has zero effect on CKEditor 5 itself, it only has an effect on Drupal, to ensure Drupal's filter_html configuration maches.

    The attribute 'ver' is logically optional but in ckeditor5 it must be present (even as 'ver=""') otherwise ckeditor5 will not recognise the tag and removes that markup.

    That's entirely up to your custom CKEditor 5 plugin's logic I'm afraid ๐Ÿ˜… Plenty of CKEditor 5 plugins have optional attributes!

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    Hi Wim - yep thanks - but could not find a plugin example with optional attributes - suggestion please?

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia pravat231

    Hi @jons @Wim Leers

    Thank you so much for sharing your experience. It helped me to resolve my issue. All my editor issues resolved. And I am able to save these custom tags with attributes. e.g. <text-format-custom type="xss">

    But I am facing only one issue now, after saving these data. These custom tags with attribute not coming in my Drupal pages. All other tags <b> <hr> all these tags are coming even If try to save only <text-format-custom> then its showing in my saved pages but <text-format-custom type="xss"> these tags are stripped before loading into the pages.

    May I know how to solve this issue for the Drupal pages not to strip these tags with attributes?

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    Hi @pravat231
    You need to add them to the allowed tags in the text-formats you are using, eg Full HTML (admin/config/content/formats)
    Click configure
    If you have 'Limit allowed HTML tags and correct faulty HTML' filter enabled (as I suspect you have):
    Scroll down to the 'Filter settings' area and add to the 'Allowed HTML Tags' textarea as ''
    Save
    Edit your page and try again.
    Note that even clicking the Source button in the editor makes the filters operate (ie you don't have to save to test this).

    The other option is to switch off 'Limit allowed HTML tags and correct faulty HTML' - which I currently have, to deal with a different issue.
    There is a 'Correct faulty and chopped off HTML' filter as well, which can be left on.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia pravat231

    Hello @jons,

    With Drupal 9.5 and CKEditor 5 plugin creation process, automatically this <text-format-custom type> is coming under allowed tags. And even I tried disabling the Limit allowed HTML tags and Correct faulty & chopped off HTML

    Now I am able to see these custom tags with attributes in my ckeditor properly saved. But its not coming in my page. Do I need to add any ckeditor plugin JS file.

    Regards,
    Pravat

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia pravat231

    Hi @Jons / @Wim,

    Any idea how to get this feature done in CKEditor5 in my existing CKEditor4 this below code is helping in selecting the whole sentence if I choose any word from the whole sentence wrapped with <text-format-custom> tag;

    e.g. This <text-format-custom type="***">is test sentence to show the</text-format-custom> example.

    In this above sample text If I select only "show" then as it was wrapped with <text-format-custom> tag then it will select the whole sentence "is test sentence to show the"

    CKeditor4 Working Code

        const selection = editor.getSelection();
        const selectedElement = selection.getSelectedElement();
    
        if (selectedElement && selectedElement.is('text-format-custom')) {
          return selectedElement;
        }
    
        const range = selection.getRanges(true)[0];
    
        if (range) {
          range.shrink(CKEDITOR.SHRINK_TEXT);
          return editor.elementPath(range.getCommonAncestor()).contains('text-format-custom', 1);
        }
    
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom Jons

    Hi @pravat231
    I can't help with this as I've not had to implement that functionality.
    It was certainly easier to work with CKE4!
    Maybe it will get a bit better the more that is done and shared with CKE5, and the main docs updated.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia pravat231

    Thanks @jon for your reply. Fortunately I was able to solve this use case using

    data.processor.toView(newElement);
    data.toModel(newViewFragment);
    model.insertContent(modelFragment, range);
  • Status changed to Fixed 9 months ago
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Per #21. Crediting @pravat231 ๐Ÿ˜Š

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024