ckeditor / ckeditor5

Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.
https://ckeditor.com/ckeditor-5
Other
9.62k stars 3.7k forks source link

Color picker might try to register duplicated custom element, which breaks the editor #15698

Closed Mgsy closed 10 months ago

Mgsy commented 10 months ago

📝 Provide detailed reproduction steps (if any)

  1. Create two CKEditor 5 builds which include the Font feature
  2. Create a single page application with two pages, each page should use different build
  3. Navigate between pages

✔️ Expected result

The editor initializes properly.

❌ Actual result

The error is thrown.

DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "hex-color-picker" has already been used with this registry

📃 Other details

It seems that the issue is caused by the color picker library, which registers a custom element - hex-color-picker (https://github.com/web-padawan/vanilla-colorful/blob/master/src/hex-color-picker.ts#L20). It's fine if we use one build, but when the second one is loaded, the error occurs, as the second build also imports the library (https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-ui/src/colorpicker/colorpickerview.ts#L20), which tries to register hex-color-picker element again, resulting in the mentioned error.


If you'd like to see this fixed sooner, add a 👍 reaction to this post.

Dumluregn commented 10 months ago

Additional findings

This issue is only reproducible in a very specific situation where:

Possible solutions

  1. Changing the import from import 'vanilla-colorful/hex-color-picker.js'; to import { HexColorPicker } from 'vanilla-colorful/hex-color-picker.js'; doesn't help because the whole file is executed during import anyway.
  2. Changing the import from import 'vanilla-colorful/hex-color-picker.js'; to import { type HexColorPicker } from 'vanilla-colorful/hex-color-picker.js'; doesn't help because we need the actual class to register it in the CustomElementRegistry.
  3. The solution could be importing HexBase class (parent of HexColorPicker) instead and defining the custom element conditionally (i.e. if it wasn't defined yet). Unfortunately it's not exported by the vanilla-colorful package and therefore can't be used. We could ask the package author if they could add an export for us.
  4. We could also ask the vanilla-colorful author to make the custom elements definitions conditional on his end.

Still, using a single CKEditor bundle instead of two is the recommended solution in this case as it would allow to avoid code duplication and improve the performance. The details regarding how to do this are in this guide.

Edit: Changing the import from import 'vanilla-colorful/hex-color-picker.js'; to import { HexBase } from 'vanilla-colorful/lib/entrypoints/hex'; (notice no .js at the end) looks to be working.