Weird issue with internal drag&drop - Dropped contents === "null"
Question
Hi @artf ,
I'm facing a very strange issue related to HTML5 drag & drop.
When I select some mixed contents within grapesjs, including editable text contents and the surrounding components as a whole selection with the mouse, the dropped (copied) contents is sometimes "null" (a string carrying the "null" text value, not a JavaScript null).
I've managed to reproduce the issue with the Newsletter demo, with Chrome 71.0.3578.98. I don't know whether it happens with other browsers, or not...

When the issue arises, I've noticed that, when catching the canvas:dragdata event, the result.content variable is "null" (string). I looked into the call stack and found that this value comes from the dataTransfer.getData("text/html") call in grapesjs' core Droppable.getContentByData() function:
} else if ((0, _underscore.indexOf)(types, 'text/html') >= 0) { content = dataTransfer.getData('text/html').replace(/<\/?meta[^>]*>/g, '');
I don't know why, and in which circumstances the browser sends "null" while fetching data in text/html format. All other formats seem to carry a correct value. You'll note that I use the CKEditor plugin, hence I have some additional "formats" related to CKEditor in dataTransfer:

Could you check whether you can reproduce this on your own side, and if you can do anything to handle this case within grapesjs? (assuming that it may be a browser-related bug).
In the meantime, I handled this on my own side by picking the value from dataTransfer.getData("text/plain") when possible, and returning empty stuff otherwise:
myGrapesJsObject.on('canvas:dragdata', function (dataTransfer, result) {
if (result && result.content) {
if (typeof (result.content) == "string" && result.content === "null" && dataTransfer.getData("text/html") === result.content) {
result.content = "";
if (dataTransfer.types && dataTransfer.types.length > 0) {
for (var i = 0; i < dataTransfer.types.length; i++) {
if (dataTransfer.types[i] == "text/plain") {
var altValue = dataTransfer.getData(dataTransfer.types[i]);
if (altValue && altValue != "") {
result.content = altValue;
break;
}
}
}
}
}
}
}
As a side note, I sometimes found that the dataTransfer object carries some "old" dropped contents from previous drags, and not the latest stuff. But I've been unable to find when and why so far, so I'll not bother you with this for now (unless it's a known issue, and if you need additional information on this particular issue.)
Thanks for your thoughts!
Answers (3)
Thanks for the report @arachnosoft BTW I'm able to reproduce it, but only once the first CKEditor instance is activated, can you confirm?
Yeah @artf , seems to be the exact test case...
If I refresh the page to get a clean context, empty the canvas, drop a Grid component (quite complex one), select some of its text and surrounding cells WITHOUT activating CKEditor, and drag/drop it from the text, it's working correctly.
But as soon as I double-click on a cell to activate CKEditor, click elsewhere to disable editing, and follow the exact same steps as above (making the exact same selection and drag/drop), the dropped contents is "null".

And, unless I refresh the page to get rid of all CKEditor instances in the DOM, the issue remains, even if I empty the canvas first:

Glad you reproduced it as well, because it was quite a pain to find what was going wrong!
I noticed that a new CKEditor instance was being created into the DOM each time a new component is edited, even though the CKEditor plugin uses CKEditor's inline() method. I don't know if this is "by-design", or if it could explain that kind of issue.
I noticed that a new CKEditor instance was being created into the DOM each time a new component is edited, even though the CKEditor plugin uses CKEditor's inline() method. I don't know if this is "by-design", or if it could explain that kind of issue.
Yeah this is how their inline plugins works but I don't think this somehow related
BTW definitely CKEditor adds its type to dataTransfer object and edits, for some reason (probably to handle some their edge cases), the 'text/plain' (GrapesJS relies completely on native objects without touching them).
Related Questions and Answers
Continue research with similar issue discussions.
Issue #3128
FEAT: Drop a component at the position of the mouse is clicked
What are you trying to add to GrapesJS? When a component is dropped, stay at the position of the mouse is clicked. Describe your feature re...
Issue #1605
Can we implement Paste as Rich text editor options in Rte?
hi @artf I've gone through this Drag and Drop Editor and what an amazing work. I also read your docs and I tried to extend rich text editor...
Issue #1247
Text disappear after creating a new type
Hello! I am creating a new block that will open a modal during the creation (drag and drop https://github.com/artf/grapesjs/issues/174 real...
Issue #2260
Drag and drop of selected text displays null
Hello, I have a problem with GrapesJS editor because when some text is selected in a component and when you drop it outside component it sh...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.