Refactor IsElementVisibleToTheUser() JS helper within CombodoGlobalToolbox

This commit is contained in:
Molkobain
2021-04-04 22:36:20 +02:00
parent 54b718e7cd
commit 90cc08b920
3 changed files with 52 additions and 55 deletions

View File

@@ -292,7 +292,7 @@ abstract class AbstractAttachmentsRenderer
if (!bFiles) return; // Not dragging files
window.dropZone = $('#file').closest('.ibo-tab');
if (!IsElementVisibleToTheUser(dropZone[0]))
if (!CombodoGlobalToolbox.IsElementVisibleToTheUser(dropZone[0]))
{
// Hidden, but inside an inactive tab? Highlight the tab
var sTabId = dropZone.closest('.ibo-tab-container--tab-container').attr('aria-labelledby');

View File

@@ -108,8 +108,8 @@ $(function()
if(window.ResizeObserver)
{
const oTabsListRO = new ResizeObserver(function(){
// Note: For a reason I don't understand, when called instantly the sub function IsElementVisibleToTheUser() won't be able to retrieve an element using the document.elementFromPoint() function
// As it won't return anything, the function always thinks it's invisible...
// Note: For a reason I don't understand, when called instantly the sub function CombodoGlobalToolbox.IsElementVisibleToTheUser() won't be able to retrieve an element using the document.elementFromPoint() function
// As it won't return anything, the function always thinks it's invisible...
setTimeout(function(){
me._onTabContainerResize();
}, 200);
@@ -247,14 +247,11 @@ $(function()
const sTabId = oTabHeaderElem.attr('data-tab-id');
const oMatchingExtraTabElem = this.element.find(this.js_selectors.extra_tab_toggler+'[href="#'+sTabId+'"]');
if(!IsElementVisibleToTheUser(oTabHeaderElem[0], true, 2))
{
oMatchingExtraTabElem.removeClass(this.css_classes.is_hidden);
}
else
{
oMatchingExtraTabElem.addClass(this.css_classes.is_hidden);
}
if (!CombodoGlobalToolbox.IsElementVisibleToTheUser(oTabHeaderElem[0], true, 2)) {
oMatchingExtraTabElem.removeClass(this.css_classes.is_hidden);
} else {
oMatchingExtraTabElem.addClass(this.css_classes.is_hidden);
}
},
// - Update extra tabs list
_updateExtraTabsList: function()

View File

@@ -623,49 +623,6 @@ function Format() {
return str;
}
/**
* Return true if oDOMElem is visible to the user, meaning that it is in the current viewport AND is not behind another element.
*
* @param oDOMElem DOM element to check
* @param bCompletely Should oDOMElem be completely visible for the function to return true?
* @param iThreshold Use when bCompletely = true, a threshold in pixels to consider oDOMElem as completely visible. This is useful when elements are next to others as the browser can consider 1 pixel is overlapping the next element.
* @returns {boolean}
* @url: https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
*/
function IsElementVisibleToTheUser(oDOMElem, bCompletely = false, iThreshold = 0)
{
const oRect = oDOMElem.getBoundingClientRect(),
fViewportWidth = window.innerWidth || doc.documentElement.clientWidth,
fViewportHeight = window.innerHeight || doc.documentElement.clientHeight,
efp = function (x, y) {
return document.elementFromPoint(x, y)
};
// Return false if it's not in the viewport
if (oRect.right < 0 || oRect.bottom < 0
|| oRect.left > fViewportWidth || oRect.top > fViewportHeight) {
return false;
}
if (bCompletely === true) {
// Return true if ALL of its four corners are visible
return (
oDOMElem.contains(efp(oRect.left+iThreshold, oRect.top+iThreshold))
&& oDOMElem.contains(efp(oRect.right-iThreshold, oRect.top+iThreshold))
&& oDOMElem.contains(efp(oRect.right-iThreshold, oRect.bottom-iThreshold))
&& oDOMElem.contains(efp(oRect.left+iThreshold, oRect.bottom-iThreshold))
);
} else {
// Return true if ANY of its four corners are visible
return (
oDOMElem.contains(efp(oRect.left, oRect.top))
|| oDOMElem.contains(efp(oRect.right, oRect.top))
|| oDOMElem.contains(efp(oRect.right, oRect.bottom))
|| oDOMElem.contains(efp(oRect.left, oRect.bottom))
);
}
}
/**
* Enable to access translation keys client side.
* The called keys needs to be exported using \WebPage::add_dict_entry
@@ -699,7 +656,50 @@ Dict.Format = function () {
* @api
* @since 3.0.0
*/
const CombodoGlobalToolbox = {};
const CombodoGlobalToolbox = {
/**
* Return true if oDOMElem is visible to the user, meaning that it is in the current viewport AND is not behind another element.
*
* @param oDOMElem {Object} DOM element to check
* @param bCompletely {boolean} Should oDOMElem be completely visible for the function to return true?
* @param iThreshold {integer} Use when bCompletely = true, a threshold in pixels to consider oDOMElem as completely visible. This is useful when elements are next to others as the browser can consider 1 pixel is overlapping the next element.
* @returns {boolean}
* @url: https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
* @since 3.0.0
*/
IsElementVisibleToTheUser: function (oDOMElem, bCompletely = false, iThreshold = 0) {
const oRect = oDOMElem.getBoundingClientRect(),
fViewportWidth = window.innerWidth || doc.documentElement.clientWidth,
fViewportHeight = window.innerHeight || doc.documentElement.clientHeight,
efp = function (x, y) {
return document.elementFromPoint(x, y)
};
// Return false if it's not in the viewport
if (oRect.right < 0 || oRect.bottom < 0
|| oRect.left > fViewportWidth || oRect.top > fViewportHeight) {
return false;
}
if (bCompletely === true) {
// Return true if ALL of its four corners are visible
return (
oDOMElem.contains(efp(oRect.left+iThreshold, oRect.top+iThreshold))
&& oDOMElem.contains(efp(oRect.right-iThreshold, oRect.top+iThreshold))
&& oDOMElem.contains(efp(oRect.right-iThreshold, oRect.bottom-iThreshold))
&& oDOMElem.contains(efp(oRect.left+iThreshold, oRect.bottom-iThreshold))
);
} else {
// Return true if ANY of its four corners are visible
return (
oDOMElem.contains(efp(oRect.left, oRect.top))
|| oDOMElem.contains(efp(oRect.right, oRect.top))
|| oDOMElem.contains(efp(oRect.right, oRect.bottom))
|| oDOMElem.contains(efp(oRect.left, oRect.bottom))
);
}
}
};
/**
* Helper for tooltip instantiation (abstraction layer between iTop markup and tooltip plugin to ease its replacement in the future)