diff --git a/datamodels/2.x/itop-attachments/renderers.itop-attachments.php b/datamodels/2.x/itop-attachments/renderers.itop-attachments.php index 9a475a3a9..bc3373534 100644 --- a/datamodels/2.x/itop-attachments/renderers.itop-attachments.php +++ b/datamodels/2.x/itop-attachments/renderers.itop-attachments.php @@ -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'); diff --git a/js/layouts/tab-container/tab-container.js b/js/layouts/tab-container/tab-container.js index 9a054a869..e4440d72c 100644 --- a/js/layouts/tab-container/tab-container.js +++ b/js/layouts/tab-container/tab-container.js @@ -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() diff --git a/js/utils.js b/js/utils.js index c7ec3fa77..790e6b7a5 100644 --- a/js/utils.js +++ b/js/utils.js @@ -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)