grapesjs icon indicating copy to clipboard operation
grapesjs copied to clipboard

Drag placeholder does not calculate the correct width.

Open jcamejo opened this issue 4 years ago • 3 comments

HI @artf, I hope you are having a nice day.

There's a small issue with the drag placeholder when a block is being dragged into a possible container with lateral margins, It could happen also with top/bottom margins or padding but I'm not 100% sure.

image

The reason for this being the function getBoundingClientRect that calculates the dimensions of a container, behaves irregularly in some cases, returning the width of the element without taking into account some properties that affects that calculation.

Someone had a similar problem before. https://stackoverflow.com/questions/28966678/getboundingclientrect-returning-wrong-results

In this case we will have to tweak a little the getElRect function located in the mixins file. I think something like this will help, although i still have to work a little bit more on it to make it right.

const getElRect = el => {
  const def = {
    top: 0,
    left: 0,
    width: 0,
    height: 0
  };

  if (!el) return def;
  let rectText;
  let rect;

  if (isTextNode(el)) {
    const range = document.createRange();
    range.selectNode(el);
    rectText = range.getBoundingClientRect();
    range.detach();
  }

  if (rectText) {
    rect = rectText;
  } else if (el.getBoundingClientRect) {
    let style = window.getComputedStyle(el);
    let boundingRect = el.getBoundingClientRect();
    let margin = {
      left: parseInt(style['margin-left']),
      right: parseInt(style['margin-right']),
      top: parseInt(style['margin-top']),
      bottom: parseInt(style['margin-bottom'])
    };
    let padding = {
      left: parseInt(style['padding-left']),
      right: parseInt(style['padding-right']),
      top: parseInt(style['padding-top']),
      bottom: parseInt(style['padding-bottom'])
    };

    boundingRect.width = boundingRect.width - margin.left - margin.right;
    boundingRect.left = 0 + bounding.left;

    rect.width = boundingRect;
  } else {
    rect = def;
  }

  return rect;
};

At the moment i do not have the time to do a pull request, I'm writing as an issue to keep a record of it, i will dig on this soon.

If you want to replicate this issue you can create a container component with these properties

.container {

width: 100%;
 padding-right: 15px;
 padding-left: 15px;
 margin-right: auto;
 margin-left: auto;
}

And another one the could go as a child component of the container

.row {
   display: block;
   margin: 0;
}

I'm using the latest version (v0.16.2), maybe there's something that I'm missing and this could be easily solved.

Best Regards, Juan

jcamejo avatar Mar 13 '20 13:03 jcamejo

To be honest, I'd leave getElRect as it is, using getComputedStyle in this context would be too much expensive and the function itself is a generic one (so it doesn't make sense having there stuff like boundingRect.width = boundingRect.width - margin.left - margin.right).

I'm quite sure the issue is in the Sorter and the function which calculates element dimensions is getDim (quite an old one, so I wouldn't expect any good logic there) so you should try to start the investigation there

artf avatar Mar 18 '20 22:03 artf

I got to getElRect by reading through the getDim function but i will do the research there again to look for another solution.

Thanks!

jcamejo avatar Mar 24 '20 10:03 jcamejo

Hello,

For future questions or technical issues, which aren't bugs, GitHub's Discussions tab is the place to be.

Don't forget to close this issue if it is resolved or write a new detailed message in Discussions -> Q&A category (and close this issue).

Thank you for your understanding.

bgrand-ch avatar May 11 '21 19:05 bgrand-ch

Closing this one as it seems to be fixed.

artf avatar Jul 26 '23 13:07 artf