/* 
 | 
Strike by Appiphony 
 | 
  
 | 
Version: 1.0.0 
 | 
Website: http://www.lightningstrike.io 
 | 
GitHub: https://github.com/appiphony/Strike-Components 
 | 
License: BSD 3-Clause License 
 | 
*/ 
 | 
({ 
 | 
    calculateNubbinPlacement: function(component, placement){ 
 | 
        if(!placement) { 
 | 
            placement = component.get('v.placement'); 
 | 
        } 
 | 
        placement = placement.replace('auto ', ''); 
 | 
        var nubbinPlacement; 
 | 
  
 | 
        switch (placement){ 
 | 
            case 'top' : nubbinPlacement = 'slds-nubbin--bottom'; break; 
 | 
            case 'bottom' : nubbinPlacement = 'slds-nubbin--top'; break; 
 | 
            case 'left' : nubbinPlacement = 'slds-nubbin--right'; break; 
 | 
            case 'right' : nubbinPlacement = 'slds-nubbin--left'; break; 
 | 
            default : nubbinPlacement = 'slds-nubbin--bottom'; 
 | 
        } 
 | 
  
 | 
        component.set('v.nubbinPlacement', nubbinPlacement); 
 | 
    }, 
 | 
    calculateTooltipPosition: function(component) { 
 | 
        var tooltipEl = component.find('tooltip').getElement(); 
 | 
        var tooltipBoundingBox = tooltipEl.getBoundingClientRect(); 
 | 
        var tooltipWidth = Math.ceil(tooltipBoundingBox.width); 
 | 
        var tooltipHeight = tooltipBoundingBox.height; 
 | 
  
 | 
        var containerEl = component.find('tooltipContainer').getElement(); 
 | 
        var containerBoundingBox = containerEl.getBoundingClientRect(); 
 | 
        var containerWidth = containerBoundingBox.width; 
 | 
        var containerHeight = containerBoundingBox.height; 
 | 
        var containerLeft = containerBoundingBox.left; 
 | 
        var containerRight = containerBoundingBox.right; 
 | 
  
 | 
        var placement = component.get('v.placement'); 
 | 
        var adjustment; 
 | 
        // Check for auto placement 
 | 
        if(placement.startsWith('auto ')) { 
 | 
  
 | 
            // Remove auto placement to perform bounding checks on preferred placement 
 | 
            placement = placement.replace('auto ', ''); 
 | 
  
 | 
            // Construct the window bounding box. 
 | 
  
 | 
            // The height of the sticky global header is not accessible in any way 
 | 
            // so it must be hardcoded. This may change during releases. 
 | 
            // var globalHeaderHeight = 90; 
 | 
  
 | 
            // In LEX, document.body.getBoundingClientRect() does not return the 
 | 
            // correct values so we will construct a box ourselves using the 
 | 
            // inner width and height of the window (viewport) 
 | 
            var windowBoundingBox = { 
 | 
                top: 0, 
 | 
                right: window.innerWidth, 
 | 
                bottom: window.innerHeight, 
 | 
                left: 0 
 | 
            }; 
 | 
  
 | 
            // Validate that there is space for the preferred placements. If there is 
 | 
            // not, invert the placement 
 | 
            if(placement === 'top' && (containerBoundingBox.top - tooltipBoundingBox.height) < windowBoundingBox.top) { 
 | 
                placement = 'bottom'; 
 | 
            } else if(placement === 'right' && (containerBoundingBox.right + tooltipBoundingBox.width) > windowBoundingBox.right) { 
 | 
                placement = 'left'; 
 | 
            } else if(placement === 'bottom' && (containerBoundingBox.bottom + tooltipBoundingBox.height) > windowBoundingBox.bottom) { 
 | 
                placement = 'top'; 
 | 
            } else if(placement === 'left' && (containerBoundingBox.left - tooltipBoundingBox.width) < windowBoundingBox.left) { 
 | 
                placement = 'right'; 
 | 
            } 
 | 
  
 | 
            // update nubbin since placement may have changed from the last 
 | 
            // display 
 | 
            this.calculateNubbinPlacement(component, placement); 
 | 
        } 
 | 
  
 | 
        var tooltipYPos, tooltipXPos; 
 | 
        var nubbinPadding = 14; 
 | 
  
 | 
        var tooltipStyle = component.find('tooltipStyle').getElement(); 
 | 
  
 | 
        if (placement === 'right') { 
 | 
            tooltipXPos = containerWidth + nubbinPadding; 
 | 
            tooltipYPos = (containerHeight - tooltipHeight) / 2; 
 | 
        } else if (placement === 'bottom') { 
 | 
            tooltipXPos = (containerWidth - tooltipWidth) / 2; 
 | 
            tooltipYPos = containerHeight + nubbinPadding; 
 | 
  
 | 
            if ((containerLeft + tooltipXPos) < 4) { 
 | 
                adjustment = Math.abs(containerLeft + tooltipXPos) + 4; 
 | 
  
 | 
                tooltipXPos += adjustment; 
 | 
                tooltipStyle.innerHTML = '.st-popover_container .slds-nubbin--top:before { transform: translateX(' + -adjustment + 'px) rotate(45deg); } .st-popover_container .slds-nubbin--top:after { transform: translateX(' + -adjustment + 'px) rotate(45deg); }'; 
 | 
            } else if ((containerRight + Math.abs(tooltipXPos)) > (window.innerWidth - 4)) { 
 | 
                adjustment = (containerRight + Math.abs(tooltipXPos)) - (window.innerWidth - 4); 
 | 
  
 | 
                tooltipXPos -= adjustment; 
 | 
                tooltipStyle.innerHTML = '.st-popover_container .slds-nubbin--top:before { transform: translateX(' + adjustment + 'px) rotate(45deg); } .st-popover_container .slds-nubbin--top:after { transform: translateX(' + adjustment + 'px) rotate(45deg); }'; 
 | 
            } 
 | 
        } else if (placement === 'left') { 
 | 
            tooltipXPos = -tooltipWidth - nubbinPadding; 
 | 
            tooltipYPos = (containerHeight - tooltipHeight) / 2; 
 | 
        } else { // Top 
 | 
            tooltipXPos = (containerWidth - tooltipWidth) / 2; 
 | 
            tooltipYPos = -tooltipHeight - nubbinPadding; 
 | 
  
 | 
            if ((containerLeft + tooltipXPos) < 4) { 
 | 
                adjustment = Math.abs(containerLeft + tooltipXPos) + 4; 
 | 
  
 | 
                tooltipXPos += adjustment; 
 | 
                tooltipStyle.innerHTML = '.st-popover_container .slds-nubbin--bottom:before { transform: translateX(' + -adjustment + 'px) rotate(45deg); } .st-popover_container .slds-nubbin--bottom:after { transform: translateX(' + -adjustment + 'px) rotate(45deg); }'; 
 | 
            } else if ((containerRight + Math.abs(tooltipXPos)) > (window.innerWidth - 4)) { 
 | 
                adjustment = (containerRight + Math.abs(tooltipXPos)) - (window.innerWidth - 4); 
 | 
  
 | 
                tooltipXPos -= adjustment; 
 | 
                tooltipStyle.innerHTML = '.st-popover_container .slds-nubbin--bottom:before { transform: translateX(' + adjustment + 'px) rotate(45deg); } .st-popover_container .slds-nubbin--bottom:after { transform: translateX(' + adjustment + 'px) rotate(45deg); }'; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return { 
 | 
            tooltipXPos : tooltipXPos, 
 | 
            tooltipYPos : tooltipYPos, 
 | 
            width : tooltipWidth 
 | 
        } 
 | 
    } 
 | 
}) 
 | 
/* 
 | 
Copyright 2017 Appiphony, LLC 
 | 
  
 | 
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the  
 | 
following conditions are met: 
 | 
  
 | 
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following  
 | 
disclaimer. 
 | 
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following  
 | 
disclaimer in the documentation and/or other materials provided with the distribution. 
 | 
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote  
 | 
products derived from this software without specific prior written permission. 
 | 
  
 | 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,  
 | 
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
 | 
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  
 | 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR  
 | 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
 | 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  
 | 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 | 
*/ 
 |