forked from a64f7bb4-7358-4778-9fbe-3b882c34cc1d/v1
161 lines
3.8 KiB
JavaScript
161 lines
3.8 KiB
JavaScript
/**
|
|
* @file
|
|
* Provides CSS3 Native Grid treated as Masonry based on Grid Layout.
|
|
*
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
|
|
* The two-dimensional Native Grid does not use JS until treated as a Masonry.
|
|
* If you need GridStack kind, avoid inputting numeric value for Grid.
|
|
* Below is the cheap version of GridStack.
|
|
*/
|
|
|
|
(function ($, Drupal, _doc) {
|
|
|
|
'use strict';
|
|
|
|
var _context = _doc;
|
|
var _id = 'block-nativegrid';
|
|
var _idOnce = 'b-masonry';
|
|
var _isMasonry = 'is-' + _idOnce;
|
|
var _isUnload = 'is-b-unload';
|
|
var _element = '.' + _id + '.' + _isMasonry;
|
|
var _unload = false;
|
|
|
|
Drupal.blazy = Drupal.blazy || {};
|
|
|
|
var _opts = {
|
|
$el: null,
|
|
gap: 15,
|
|
height: 15,
|
|
rows: 10
|
|
};
|
|
|
|
var _heights = [];
|
|
|
|
/**
|
|
* Applies the correct span to each grid item.
|
|
*
|
|
* @param {HTMLElement|Event} el
|
|
* The item HTML element, or event object on blazy.done.
|
|
* @param {int} i
|
|
* The element index.
|
|
* @param {bool} isResized
|
|
* If the resize event is triggered.
|
|
*/
|
|
function processItem(el, i, isResized) {
|
|
var target = el.target;
|
|
var box = 'target' in el ? $.closest(target, '.grid') : el;
|
|
|
|
if (!$.isElm(box)) {
|
|
return;
|
|
}
|
|
|
|
var cn = $.find(box, '.grid__content');
|
|
|
|
if ($.isElm(cn)) {
|
|
if (_opts.gap === 0) {
|
|
_opts.gap = 0.0001;
|
|
}
|
|
|
|
// Once setup, we rely on CSS to make it responsive.
|
|
var layout = function () {
|
|
_heights.push($.outerHeight(cn, true));
|
|
var rect = $.rect(cn);
|
|
var span = Math.ceil((rect.height + _opts.gap) / (_opts.height + _opts.gap));
|
|
|
|
// Sets the grid row span based on content and gap height.
|
|
box.style.gridRowEnd = 'span ' + span;
|
|
|
|
$.addClass(box, 'is-b-grid');
|
|
setTimeout(function () {
|
|
cn.style.minHeight = '';
|
|
$.addClass(box, 'is-b-layout');
|
|
}, _unload ? 600 : 200);
|
|
};
|
|
|
|
if (isResized || _unload) {
|
|
setTimeout(layout, _unload ? 300 : 200);
|
|
}
|
|
else {
|
|
layout();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Applies grid row end to each grid item.
|
|
*
|
|
* @param {HTMLElement} elm
|
|
* The container HTML element.
|
|
*/
|
|
function process(elm) {
|
|
var selector = '.grid:not(.is-b-grid)';
|
|
// The is-b-grid is flag to not re-do with VIS, views infinite scroll/ IO.
|
|
var items = $.findAll(elm, selector);
|
|
|
|
var init = function () {
|
|
var style = $.computeStyle(elm);
|
|
var gap = style.getPropertyValue('grid-row-gap');
|
|
var rows = style.getPropertyValue('grid-auto-rows');
|
|
|
|
if (gap) {
|
|
_opts.gap = parseInt(gap, 10);
|
|
}
|
|
if (rows) {
|
|
_opts.height = parseInt(rows, 10);
|
|
}
|
|
|
|
if (items.length) {
|
|
if (_unload) {
|
|
$.each(items, function (item, i) {
|
|
var cn = $.find(item, '.grid__content');
|
|
if (cn && _heights[i]) {
|
|
cn.style.minHeight = _heights[i] + 'px';
|
|
}
|
|
});
|
|
}
|
|
|
|
// Process on page load.
|
|
$.each(items, processItem);
|
|
|
|
// Process on resize.
|
|
if (!_unload) {
|
|
Drupal.blazy.checkResize(items, processItem, elm, processItem);
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
setTimeout(init, _unload ? 110 : 0);
|
|
_opts.$el = elm;
|
|
|
|
// $.addClass(elm, _isMounted);
|
|
if (_unload) {
|
|
$.addClass(elm, _isUnload);
|
|
}
|
|
_unload = false;
|
|
}
|
|
|
|
/**
|
|
* Attaches Blazy behavior to HTML element identified by .block-nativegrid.
|
|
*
|
|
* @type {Drupal~behavior}
|
|
*/
|
|
Drupal.behaviors.blazyNativeGrid = {
|
|
attach: function (context) {
|
|
|
|
_context = $.context(context);
|
|
|
|
$.once(process, _idOnce, _element, _context);
|
|
|
|
},
|
|
detach: function (context, setting, trigger) {
|
|
_unload = trigger === 'unload';
|
|
if (_unload) {
|
|
$.once.removeSafely(_idOnce, _element, _context);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
}(dBlazy, Drupal, this.document));
|