Problem/Motivation

I'd like to add some custom UI to the lightbox, but ideally I'd need to listen to some lightbox events like init as well. I'm not seeing a great place to hook into any of that, and I'm wondering if you have suggestions? Or I could come up with some sort of registration system similar to how Splide works?

I've tried a couple of things so far and I'm hitting some problems:

  1. Drupal.behaviors attaching isn't working well because of the promise used to load the PhotoSwipeLightbox library. I was hoping to attach events to the lighbox object assigned to Drupal.blazyPhotoSwipe.beforeInit (with the comment "Exposes lightbox object"), but the sequence is blazyPhotoSwipe attach is called and starts loading, then my custom JS attach is called, but nothing is ready yet until the module import promise resolves (Drupal.blazyPhotoSwipe.init.then()).
  2. The only other option I could find is piggypacking off of Drupal.blazyPhotoSwipe.ui. That happens to exist to add the custom caption, so if I add my custom item there (which I would need to do either way) I'll at least get registered, but there's no opportunity to clean up or listen to other events.

Do you have any thoughts or ideas?

Comments

KarlShea created an issue. See original summary.

gausarts’s picture

Thank you.

Registering UI appears to work, however the current implementation is not really working well to accommodate events due to empty pswp.pswp object as per this writing.

     var bps = Drupal.blazyPhotoSwipe || false;

      // DOM ready fix.
      setTimeout(function () {
        if (bps && bps.init) {
          // Merge other UI providers, if any.
          Drupal.blazyPhotoSwipe.ui = bps.ui || {};

          bps.init.finally(function () {
            // @todo this object has empty pswp object.
            var pswp = bps.beforeInit;
            console.log('pswp', pswp);

            if (pswp) {
              Drupal.blazyPhotoSwipe.ui.test = {
                name: 'test-button',
                ariaLabel: 'Toggle zoom',
                order: 9,
                isButton: true,
                html: 'Test',
                onClick: (event, el) => {
                  if (confirm('Do you want to toggle zoom?')) {
                    // @todo pswp.pswp.toggleZoom();
                  }
                }
              };
            }
          });
        }
      });

Be sure to add CSS accordingly to avoid confusion:

button.pswp__button--test-button {
  background: #136912 !important;
  font-size: 20px;
  color: #fff;
}

Conclusion, we need to inject pswp object manually, or refactor to use gallery element to support multiple instances rather than relying on global Drupal.blazyPhotoSwipe.beforeInit.

gausarts’s picture

gausarts’s picture

Category: Support request » Feature request
Status: Active » Needs review
StatusFileSize
new9.2 KB

The patch will make immutable pswp object available globally, while make it possible to work with individual elements.
The last was taken from Slick convention which stores JS instance in the individual gallery element.

This sample will go to Drupal.behaviors.attach block:

var bps = Drupal.blazyPhotoSwipe || false;

      // DOM ready fix.
      setTimeout(function () {
        var items = context.querySelectorAll('[data-photoswipe-gallery]');
        if (items.length) {
          items.forEach(function (el) {
            var pswp = el.pswp;
            console.log('pswp', pswp);

            if (bps && bps.init) {
              // Merge other UI providers, if any.
              Drupal.blazyPhotoSwipe.ui = bps.ui || {};
              var lightbox = bps.lightbox;

              console.log('lightbox', lightbox);

              if (lightbox) {
                Drupal.blazyPhotoSwipe.ui.test = {
                  name: 'test-button',
                  ariaLabel: 'Toggle zoom',
                  order: 9,
                  isButton: true,
                  html: 'Test',
                  onClick: (event, el) => {
                    if (confirm('Do you want to toggle zoom?')) {
                      console.log('event', event);
                      lightbox.pswp.toggleZoom();
                    }
                  }
                };

                pswp.on('beforeOpen', function (item) {
                  console.log('beforeOpen', item);
                });

                pswp.on('initialLayout', function (item) {
                  console.log('initialLayout', item);
                });
              }
            }
          });
        }
      });

Adjust ES6 mix above accordingly, but fine though.
Also works fine with sample from #3.

Let me know if any betterment for this?

gausarts’s picture

StatusFileSize
new9.73 KB

IIRC, previously using non-indices keys for UI objects appeared to fail, but now works.

But then indices caused duplicated elements on subsequent launches, so I changed:
Drupal.blazyPhotoSwipe.ui[0] = {}, etc.

to non-indices keys:
Drupal.blazyPhotoSwipe.ui.customCaption = {}, etc.

  • gausarts committed c26d9c46 on 8.x-1.x
    Issue #3437745 by gausarts, KarlShea: Extending/adding lightbox...
gausarts’s picture

Status: Needs review » Fixed

This would do for now.

Improvements are welcome.

Thank you.

karlshea’s picture

Awesome, thank you so much! I'll give it a shot.

Status: Fixed » Closed (fixed)

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