Problem/Motivation

During a large refactor/improvements about JS ImageWidgetCrop integration we have introduce a small bug during the initialization of Cropper. When you define crop area in "ADD" context AND Image Widget Crop widget configuration "Always expand crop area" set to "YES" If "NO" all works well.

Step to reproduce :

  • Install fresh Drupal instance
  • Enable image_widget_crop_examples
  • Create a node of type "Crop simple example".
  • Add a file in the image field
  • Crop your picture
  • Save the node
  • You are redirected to the node view and the cropped zone isn't correct
  • Edit the node
  • The crop's default position is wrong and always positionned at the Top Left corner of the image with always the same dimensions but always in good aspect ratio.
  • Change your crop area in editing mode
  • Save the node
  • You are redirected to the node view page again but your cropped image is good
  • Click to "edit" to see that the default crop area position and dimensions are good too

This VIDEO can help to seen the problem.

I suppose the problem is in the initializeCropper function

    // If "Show default crop" is checked apply default crop.
    if (this.showDefaultCrop) {
      // All data returned by cropper plugin multiple with delta in order to get
      // proper crop sizes for original image.
      this.setValue(this.$image.cropper('getData'), this.naturalDelta);
      this.$wrapper.trigger('summaryUpdated');
    }

EDIT : I admit my bad of that analize *_* This part aren't lie to show_crop_area option but to show_default_crop option to display a crop area automatically when the element is visible ...

I purpose you a more complete Feedback in this other VIDEO (This describe this bug + another bug but good to view where are based my tests).

Proposed resolution

Fix the bug with initialization with "show_default_crop" activated.

Comments

woprrr created an issue. See original summary.

markhalliwell’s picture

Assigned: Unassigned » markhalliwell

The delta modification needs work. I'll try to take a look at this in more depth when I have time (likely this weekend again).

woprrr’s picture

After more improvements/Tests, I finally found the real problem ahead this bug :D !! Infact this problem appear when user enable the option "show_crop_area" (Always expand crop area)... When this option we have an error on InitializeCropper. This reduce drasticaly the futur fix :D

woprrr’s picture

Version: 8.x-1.x-dev » 8.x-2.0-rc1
woprrr’s picture

Title: Cropper position at first save are wrong » Crop first area are wrong when "Always expand crop area" is set to "YES"
Issue summary: View changes
StatusFileSize
new37.88 KB
woprrr’s picture

Hi @markcarver,

I need your specialist opinion about my analysis of that bug... I suppose that is not due to refactor because with the new approach we seems to be verry linked with Drupal events to initialize/destroy objects. But with these option we "enforce" the detail element to "open" with element attribute like :

      $element['crop_wrapper'] = [
        '#type' => 'details',
        '#title' => t('Crop image'),
        '#attributes' => [
          'class' => ['image-data__crop-wrapper'],
          'data-drupal-iwc' => 'wrapper',
        ],
        '#open' => $element['#show_crop_area'],
        '#weight' => 100,
      ];

It's possible to that method aren't compatible with our more precise approach and our js for wathever reason not are corretly initialized because the element are suppose to be hidden ? I think we can try to send data-attributes like others configuration to Js ImageWidgetCrop object and open details element with even appropried (I'm not sure with that...).

Edit : I can confirm if we comment "'#open' => $element['#show_crop_area']," All works good ... We will try to found another solution to open this details element.

woprrr’s picture

Issue summary: View changes

After more effort to understand, I think this is it

  /**
   * Creates a poll that checks visibility of an item.
   *
   * @param {HTMLElement|jQuery} element
   *   The element to poll.
   *
   * @todo Perhaps replace once vertical tabs have proper events?
   *
   * @see https://www.drupal.org/node/2653570
   */
  Drupal.ImageWidgetCropType.prototype.pollVisibility = function (element) {
    var $element = $(element);
    var value = null;
    var interval = setInterval(function () {
      var visible = $element.is(':visible');
      if (value !== visible) {
        $element.trigger((value = visible) ? 'visible.iwc' : 'hidden.iwc');
      }
    }, 250);
    this.intervals[interval] = $element;
  };

When we are on Add context and details element set to open, We never match with "value = visible" case. That can be usefull to understand it ?

Edit : To help more I past another screenshot with that :

  /**
   * Creates a poll that checks visibility of an item.
   *
   * @param {HTMLElement|jQuery} element
   *   The element to poll.
   *
   * @todo Perhaps replace once vertical tabs have proper events?
   *
   * @see https://www.drupal.org/node/2653570
   */
  Drupal.ImageWidgetCropType.prototype.pollVisibility = function (element) {
    var $element = $(element);
    var value = null;
    var interval = setInterval(function () {
      var visible = $element.is(':visible');
      if (value !== visible) {
        console.log((value = visible));
        $element.trigger((value = visible) ? 'visible.iwc' : 'hidden.iwc');
      }
    }, 250);
    this.intervals[interval] = $element;
  };

To try compare add context and edit context but nothing seems different *_* I don't understand why my last track are wrong again ;'(

woprrr’s picture

woprrr’s picture

@markcarver Do youi have an idea of this problem ? (I admit I didn't found solutions to avoid this problem) The better I can do is add more describe of problems and analize to help you :( sorry.

markhalliwell’s picture

@woprrr, TBH, I really haven't looked at this issue yet.

I've been bogged down with work, sorry. I'll try to take a look soon-ish.

Scott Robertson’s picture

@woprrr I think you're on the right track with the pollVisibility function. Having value be set to null will cause an event to be triggered the first time that function is invoked, although I'm not sure that it's actually causing this issue. However, I also noticed that the jQuery .is(':visible') check seemed quite unreliable for me. As in, visible would be true, even though the image wasn't actually visible yet.

Can you try replacing the pollVisibility function with the following and see if this issue goes away for you?

Drupal.ImageWidgetCropType.prototype.pollVisibility = function (element) {
  var $element = $(element);
  var value = false;

  var interval = setInterval(function () {
    var visible = element[0].offsetHeight > 0;

    if (value !== visible) {
      $element.trigger((value = visible) ? 'visible.iwc' : 'hidden.iwc');
    }
  }, 250);
  this.intervals[interval] = $element;
};

After I made the above changes, I could no longer reproduce this issue. If it works for you too then I can submit a PR.

markhalliwell’s picture

Yes, I keep forgetting that :visible has its limitations.

The solution in #11 is partially correct, but on the right track.

I'd rather we implement http://stackoverflow.com/a/15203639/1226717 as it's a little more comprehensive.

Scott Robertson’s picture

@markcarver Good idea. I came across that exact question, but missed the answer you linked to and only tried to implement the answer that tested if the element was simply in the viewport, not actually visible on the screen, which of course didn't work very well. I'll try implementing that solution instead and test it out.

markhalliwell’s picture

Version: 8.x-2.0-rc1 » 8.x-2.x-dev
Assigned: markhalliwell » Unassigned
Priority: Major » Critical
Status: Active » Needs review
StatusFileSize
new1.9 KB

Here's a patch.

markhalliwell’s picture

StatusFileSize
new1.9 KB
new1.3 KB

Typo and a minor optimization.

woprrr’s picture

Hi guys,

I'm glad to see you in that issue :) !! I was read all comments and learn a lot thank you ! :) Now I understand more the problem and the limitation of is_visible :)

@markcarver I have tested all cases possible and WORKS !!!! GOD :) all work like a charm :) THANKS to you guys !

duaelfr’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

I did manual testing on simplytest.

Without the patch : https://dcfd7.ply.st/node/1
With the patch : https://dcfdb.ply.st/node/3

Congrats!
(I updated the IS to make the steps more understandable)

duaelfr’s picture

StatusFileSize
new37.69 KB
new268.24 KB
new71.81 KB
new275.72 KB

You might enjoy some screenshots soo ;)

  • woprrr committed b7cd630 on 8.x-2.x authored by markcarver
    Issue #2862709 by markcarver, DuaelFr, woprrr, Scott Robertson: Crop...
woprrr’s picture

Status: Reviewed & tested by the community » Fixed

Merged in 8.x.2-x :) We are ready to stable release now.

Status: Fixed » Closed (fixed)

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