The save stopped working since XWIKI-22415 indeed, but that's not the root problem. CKEditor keeps a map of created CKEditor instances, where the key is the editor name (which normally matches the ID or the name of the form field that is enhanced by CKEditor) and the value is the CKEditor instance. This is very useful when debugging CKEditor issues because you can inspect CKEditor instances quickly from the JavaScript console: {noformat} CKEDITOR.instances.content.getData() {noformat} This is even used by some of our CKEditor plugins and test framework [ https://github.com/search?q=repo%3Axwiki%2Fxwiki-platform%20%22CKEDITOR.instances%22&type=code] . It's public API [ https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR.html#property-instances] .
Since the key is the editor name, it means there is the risk that you can have two editors with the same name of the page. If that is the case then the instance create last will be stored in {{CKEDITOR.instances}} while the first instance will not be destroyed, but you won't be able to access it through {{{}CKEDITOR.instances{}}}. This means that when you have two (or more) editors with the same name, only the last instance will be "seen" by our plugins that use this API.
The change I did in XWIKI-22415 was to use this API to access the available CKEditor instances instead of keeping track of the created instances myself. This is a generic need, so we can't expect each CKEditor plugin that needs it to maintain its own list of created CKEditor instances.
The root problem is that when the dashboard / gadget is rendered the textarea property is {*} rendered twice{*}, which creates two CKEditor instances: * the first is visible on the page, and is the one the user interacts with * the second is hidden from view, but since it was created last, it overwrites the previous {{CKEDITOR.instances}} entry
This means that all CKEditor plugins that use {{{}CKEDITOR.instances{}}}, including the save plugin since XWIKI-22415, are working with the second hidden instance of CKEditor. When you save the page the value of the second hidden instance is thus submitted.
I see 3 options: * Revert the usage of {{CKEDITOR.instances}} in the save plugin, but there are other plugins that still rely on it, so there might be other bugs not discovered yet. Plus {{CKEDITOR.instances}} is public API, so new code can use it, leading to bugs when CKEditor is used in the dashboard. * Customize the way {{CKEDITOR.instances}} is populated so that the previous entry is not overwritten and instead a new entry is added, by changing the editor name (e.g. using some counter) * Fix the dashboard / gadget rendering so that the content is not rendered twice, avoiding the double CKEditor instance
I prefer we do the third option, which seems to be the cleanest, but I'm not familiar with the dashboard / gadget rendering, so I need to understand first if the double rendering is a bug or by design, and if it can be avoided.
Marius Dumitru Florea on 06/Nov/25 16:34
The save stopped working since XWIKI-22415 indeed, but that's not the root problem. CKEditor keeps a map of created CKEditor instances, where the key is the editor name (which normally matches the ID or the name of the form field that is enhanced by CKEditor) and the value is the CKEditor instance. This is very useful when debugging CKEditor issues because you can inspect CKEditor instances quickly from the JavaScript console: {noformat} CKEDITOR.instances.content.getData() {noformat} This is even used by some of our CKEditor plugins and test framework [https://github.com/search?q=repo%3Axwiki%2Fxwiki-platform%20%22CKEDITOR.instances%22&type=code] . It's public API [https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR.html#property-instances] .
Since the key is the editor name, it means there is the risk that you can have two editors with the same name of the page. If that is the case then the instance create last will be stored in {{CKEDITOR.instances}} while the first instance will not be destroyed, but you won't be able to access it through {{{}CKEDITOR.instances{}}}. This means that when you have two (or more) editors with the same name, only the last instance will be "seen" by our plugins that use this API.
The change I did in XWIKI-22415 was to use this API to access the available CKEditor instances instead of keeping track of the created instances myself. This is a generic need, so we can't expect each CKEditor plugin that needs it to maintain its own list of created CKEditor instances.
The root problem is that when the dashboard / gadget is rendered the textarea property is {*}rendered twice{*}, which creates two CKEditor instances: * the first is visible on the page, and is the one the user interacts with * the second is hidden from view, but since it was created last, it overwrites the previous {{CKEDITOR.instances}} entry
This means that all CKEditor plugins that use {{{}CKEDITOR.instances{}}}, including the save plugin since XWIKI-22415, are working with the second hidden instance of CKEditor. When you save the page the value of the second hidden instance is thus submitted.
I see 3 options: * Revert the usage of {{CKEDITOR.instances}} in the save plugin, but there are other plugins that still rely on it, so there might be other bugs not discovered yet. Plus {{CKEDITOR.instances}} is public API, so new code can use it, leading to bugs when CKEditor is used in the dashboard. * Customize the way {{CKEDITOR.instances}} is populated so that the previous entry is not overwritten and instead a new entry is added, by changing the editor name (e.g. using some counter). We could for instance overwrite [https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR.html#method-add] . * Fix the dashboard / gadget rendering so that the content is not rendered twice, avoiding the double CKEditor instance
I prefer we do the third option, which seems to be the cleanest, but I'm not familiar with the dashboard / gadget rendering, so I need to understand first if the double rendering is a bug or by design, and if it can be avoided.
This message was sent by Atlassian Jira (v9.3.0#930000-sha1:287aeb6)
If image attachments aren't displayed, see this article.