drupal/core/misc/displace.js

129 lines
3.1 KiB
JavaScript
Raw Normal View History

/**
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
(function ($, Drupal, debounce) {
const cache = {
right: 0,
left: 0,
bottom: 0,
top: 0
};
const cssVarPrefix = '--drupal-displace-offset';
const documentStyle = document.documentElement.style;
const offsetKeys = Object.keys(cache);
const offsetProps = {};
offsetKeys.forEach(edge => {
offsetProps[edge] = {
enumerable: true,
get() {
return cache[edge];
},
set(value) {
if (value !== cache[edge]) {
documentStyle.setProperty(`${cssVarPrefix}-${edge}`, `${value}px`);
}
cache[edge] = value;
}
};
});
const offsets = Object.seal(Object.defineProperties({}, offsetProps));
function getRawOffset(el, edge) {
const $el = $(el);
const documentElement = document.documentElement;
let displacement = 0;
const horizontal = edge === 'left' || edge === 'right';
let placement = $el.offset()[horizontal ? 'left' : 'top'];
placement -= window[`scroll${horizontal ? 'X' : 'Y'}`] || document.documentElement[`scroll${horizontal ? 'Left' : 'Top'}`] || 0;
switch (edge) {
case 'top':
displacement = placement + $el.outerHeight();
break;
case 'left':
displacement = placement + $el.outerWidth();
break;
case 'bottom':
displacement = documentElement.clientHeight - placement;
break;
case 'right':
displacement = documentElement.clientWidth - placement;
break;
default:
displacement = 0;
}
return displacement;
}
function calculateOffset(edge) {
let edgeOffset = 0;
const displacingElements = document.querySelectorAll(`[data-offset-${edge}]`);
const n = displacingElements.length;
for (let i = 0; i < n; i++) {
const el = displacingElements[i];
if (el.style.display === 'none') {
continue;
}
let displacement = parseInt(el.getAttribute(`data-offset-${edge}`), 10);
if (isNaN(displacement)) {
displacement = getRawOffset(el, edge);
}
edgeOffset = Math.max(edgeOffset, displacement);
}
return edgeOffset;
}
function displace() {
let broadcast = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
const newOffsets = {};
offsetKeys.forEach(edge => {
newOffsets[edge] = calculateOffset(edge);
});
offsetKeys.forEach(edge => {
offsets[edge] = newOffsets[edge];
});
if (broadcast) {
$(document).trigger('drupalViewportOffsetChange', offsets);
}
return offsets;
}
Drupal.behaviors.drupalDisplace = {
attach() {
if (this.displaceProcessed) {
return;
}
this.displaceProcessed = true;
$(window).on('resize.drupalDisplace', debounce(displace, 200));
}
};
Drupal.displace = displace;
Object.defineProperty(Drupal.displace, 'offsets', {
value: offsets,
writable: false
});
Drupal.displace.calculateOffset = calculateOffset;
})(jQuery, Drupal, Drupal.debounce);