PageSourceSearch

https://mrag.co.uk/modules/contrib/masonry/js/masonry.js?tltzhf

js mrag.co.uk collected 2026-10-02 17:37:23 UTC 5,971 bytes, 179 lines download raw bytes

1/**
2 * @file
3 * Masonry script.
4 *
5 * Sponsored by: www.freelance-drupal.com
6 */
7
8(function ($, Drupal, drupalSettings) {
9  'use strict';
10
11  Drupal.behaviors.masonry = {
12    attach: function (context) {
13
14      /**
15       * (internal) Sub-function for code factoring: actually build masonry.
16       */
17      function _buildMasonry($container, options) {
18        const masonryExists = $container.hasClass('masonry');
19
20        // If no masonry find in container: init it...
21        if (!masonryExists) {
22          $container.addClass('masonry').addClass('masonry-layout').masonry(options);
23          $(window).resize(function () {
24            $container.masonry('bindResize');
25          });
26        } else {
27          // ...otherwise, simply rebuild the layout.
28          $container.masonry('reloadItems').masonry('layout');
29        }
30
31        // Hack to support lazysizes lazy loading.
32        if (options.imagesLazyLoad) {
33          let lastClassState = false;
34          const observer = new MutationObserver(function(mutationsList) {
35            mutationsList.forEach(function(mutation) {
36              if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
37                let currentClassState = mutation.target.classList.contains(options.lazyloadedSelector);
38
39                if (lastClassState !== currentClassState) {
40                  lastClassState = currentClassState;
41
42                  if (currentClassState) {
43                    if (options.imagesFirst) {
44                      $container.imagesLoaded(function () {
45                        $container.masonry('reloadItems').masonry('layout');
46                      });
47                    } else {
48                      $container.masonry('reloadItems').masonry('layout');
49                    }
50                  }
51                }
52              }
53            });
54          });
55
56          $('img.' + options.lazyloadSelector, $container).each(function() {
57            if (!$(this).hasClass('imgloaded')) {
58              $(this).addClass('imgloaded');
59              observer.observe(this, {attributes: true});
60            }
61          });
62        }
63      }
64
65      /**
66       * Apply Masonry.
67       */
68      function applyMasonry() {
69
70        // Iterate through all Masonry instances.
71        $.each(drupalSettings.masonry, function (container, settings) {
72
73          // Set container.
74          settings.lazyload_selector = undefined;
75          const $container = $(container);
76
77          // Set options.
78          const options = {};
79
80          // Apply column width units accordingly.
81          if (settings.column_width) {
82            if (settings.column_width_units === 'px') {
83              options.columnWidth = parseInt(settings.column_width);
84            }
85            else if (settings.column_width_units === '%') {
86              const column_width = parseInt(settings.column_width);
87              options.columnWidth = ($container.width() * (column_width / 100)) - column_width;
88            }
89            else {
90              settings.force_width = false; // Can't force width on CSS selector.
91              options.columnWidth = settings.column_width;
92            }
93          }
94
95          // Apply gutter width units accordingly.
96          if (settings.gutter_width) {
97            if (settings.gutter_width_units === 'px') {
98              options.gutter = parseInt(settings.gutter_width);
99            }
100            else if (settings.gutter_width_units === '%') {
101              const gutter = parseInt(settings.gutter_width);
102              options.gutter = ($container.width() * (gutter / 100)) - gutter;
103            }
104            else {
105              options.gutter = settings.gutter_width;
106            }
107          }
108
109          // Sets the item selector and size force.
110          if (settings.item_selector) {
111            options.itemSelector = settings.item_selector;
112            // Add custom class to all items.
113            const $items = $(settings.item_selector, $container)
114              $items.addClass('masonry-item');
115            // Force the column size.
116            if (settings.force_width) {
117              $items.css('width', settings.column_width);
118            }
119          }
120
121          // Add stamped selector.
122          if (settings.stamp) {
123            options.stamp = settings.stamp;
124          }
125
126          // Add the various options.
127          options.isResizeBound = settings.resizable;
128          options.isFitWidth = settings.fit_width;
129          options.imagesFirst = settings.images_first;
130          options.imagesLazyLoad = settings.images_lazyload;
131          options.lazyloadSelector = settings.lazyload_selector;
132          options.lazyloadedSelector = settings.lazyloaded_selector;
133          if (settings.rtl) {
134            options.isOriginLeft = false;
135          }
136          if (settings.animated) {
137            options.transitionDuration = settings.animation_duration + 'ms';
138          }
139          else {
140            options.transitionDuration = 0;
141          }
142          if (settings.percent_position) {
143            options.percentPosition = true;
144          }
145
146          // Include the extra options.
147          $.each(settings.extra_options, function (option, value) {
148            options[option] = value;
149          });
150
151          /**
152           * Apply Masonry to container.
153           */
154
155          // Load images first if necessary.
156          if (settings.images_first) {
157            $container.imagesLoaded(function () {
158              _buildMasonry($container, options);
159            });
160          }
161
162          // Apply without loading images first otherwise.
163          else {
164            _buildMasonry($container, options);
165          }
166        });
167      }
168
169      // Apply Masonry on the page.
170      applyMasonry();
171
172      // Hack for tabs: when the tab is open, it takes to reload Masonry.
173      $('a[data-toggle="tab"]', context).on('shown.bs.tab', function () {
174        applyMasonry();
175      });
176
177    }
178  };
179})(jQuery, Drupal, drupalSettings);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.