gridstack-8.x-2.5/js/gridstack.fe.js
js/gridstack.fe.js
/**
* @file
* Provides methods for both native CSS Grid and original library js-layout.
*/
(function (Drupal, drupalSettings, _, _db, window) {
'use strict';
var noop = function () {};
Drupal.gridstack = Drupal.gridstack || {};
/**
* GridStack front-end public methods.
*
* @namespace
*/
Drupal.gridstack.fe = Drupal.gridstack.fe || {
$el: null,
$instance: null,
$sizer: null,
baseSettings: {
mobileFirst: false,
itemClass: 'gridstack__box'
},
dataset: [],
config: {},
breakpoints: null,
cellHeight: 0,
column: 12,
windowWidth: 0,
options: {},
updateAttribute: noop,
preUpdateGrid: noop,
postUpdateGrid: noop,
fixAspectRatio: noop,
destroy: noop,
isEnabled: function () {
return !this.$el.classList.contains('is-gs-disabled');
},
enable: function (enabled) {
var me = this;
if (!enabled) {
var matches = me.$el.className.match(/\d+/g);
if (matches !== null && matches !== 'undefined') {
me.$el.className = me.$el.className.replace(/grid-stack-(\d+)/g, '');
}
}
me.$el.classList[enabled ? 'add' : 'remove']('is-gs-enabled');
me.$el.classList[!enabled ? 'add' : 'remove']('is-gs-disabled', 'grid-stack-1');
},
outerHeight: function (el) {
var style = window.getComputedStyle(el);
return ['top', 'bottom']
.map(function (side) {
return parseInt(style['padding-' + side], 10);
})
.reduce(function (total, side) {
return total + side;
}, 0);
},
updateClasses: function () {
var me = this;
me.enable(me.windowWidth <= me.config.minWidth ? false : true);
},
/**
* Updates the current box aspect ratio.
*
* @param {HTMLElement} box
* The gridstack item.
*/
updateRatio: function (box) {
// See https://github.com/gridstack/gridstack.js/issues/304
var width = parseInt(box.dataset.gsWidth) || 0;
var height = parseInt(box.dataset.gsHeight) || 0;
var pad = Math.round(((height / width) * 100), 2);
var media = box.querySelectorAll('.media--ratio, .b-bg');
// Supports multiple media such as an embedded Slick carousel.
if (media.length && width > 0 && height > 0) {
window.setTimeout(function () {
_.each(media, function (medium) {
medium.removeAttribute('data-ratio');
medium.style.paddingBottom = pad + '%';
});
}, 150);
}
},
breakpoint: function (which) {
var me = this;
var dataset = me.breakpoints;
var keys = Object.keys(dataset);
var ls = keys.length - 1;
var xs = keys[0];
var xl = keys[ls];
var result;
var mw = function (w) {
return me.options.mobileFirst ? w <= me.windowWidth : w >= me.windowWidth;
};
var data = keys.filter(mw).map(function (v) {
return which === 'width' ? v : dataset[v];
})[me.options.mobileFirst ? 'pop' : 'shift']();
if (which === 'column') {
result = typeof data === 'undefined' ? dataset[me.windowWidth >= xl ? xl : xs] : data;
}
else if (which === 'width') {
result = typeof data === 'undefined' ? keys[me.windowWidth >= xl ? ls : 0] : data;
}
return result;
},
updateGrid: function () {
var me = this;
var grid;
var width = me.breakpoint('width');
var column = me.breakpoint('column');
if (!_.isNull(column) && !_.isUndefined(column)) {
me.column = column;
me.$el.setAttribute('data-gs-column', me.column);
me.preUpdateGrid();
// {"480":1,"767":2,"1024":3,"1400":12}.
grid = me.dataset[width];
if (!_.isNull(grid) && !_.isUndefined(grid)) {
var nodes = me.$el.querySelectorAll('.gridstack__box:not(.is-nixbox)');
_.each(grid, function (item, i) {
var box = nodes[i];
if (!_.isNull(box) && !_.isUndefined(box)) {
me.updateAttribute(box, item);
// Runs after attributes updated since no longer relied on nodes.
me.updateRatio(box);
}
});
}
me.postUpdateGrid();
}
},
update: function () {
var me = this;
me.updateClasses();
if (!_.isNull(me.breakpoints)) {
me.updateGrid();
}
},
buildOut: function () {
var me = this;
var doResize = function () {
me.windowWidth = _db.windowWidth();
me.update();
me.$el.classList.remove('gridstack--packing');
};
// Two tasks: load the active grid per breakpoint, and update on resizing.
doResize();
window.addEventListener('resize', _db.throttle(doResize, 150, me), false);
},
cleanUp: function () {
var me = this;
me.$el.classList.remove('grid-stack-12', 'gridstack--destroyed');
_.each(['breakpoints', 'config', 'data'], function (key) {
me.$el.removeAttribute('data-gs-' + key);
});
},
/**
* Initializes the GridStack.
*
* @param {HTMLElement} elm
* The .gridstack--js HTML element.
*/
init: function (elm) {
var me = this;
var defaults = drupalSettings.gridstack || {};
me.config = _db.parse(elm.dataset.gsConfig) || {};
me.options = _db.extend({}, defaults, me.baseSettings, me.config);
me.breakpoints = _db.parse(elm.dataset.gsBreakpoints) || null;
me.dataset = _db.parse(elm.dataset.gsData) || null;
me.$el = elm;
me.$sizer = elm.querySelector('.gridstack__sizer');
// @todo remove after Outlayer update.
if (_.isNull(me.$sizer)) {
var html = '<div class="gridstack__box box gridstack__sizer box--empty is-nixbox" data-gs-height="1" data-gs-width="1"><div class="box__content"></div></div>';
elm.insertAdjacentHTML('beforeend', html);
}
// Required to determine the correct aspect ratio.
me.$sizer = elm.querySelector('.gridstack__sizer');
if (!_.isNull(me.$sizer)) {
me.cellHeight = me.outerHeight(me.$sizer.querySelector('.box__content'));
}
// Fixed aspect ratio earlier, before building layouts.
// Runs it before init to pass the options to gridstack.
// me.updateClasses();
me.fixAspectRatio();
}
};
})(Drupal, drupalSettings, _, dBlazy, this);
