|
|
import getSupportedPropertyName from '../utils/getSupportedPropertyName'; |
|
|
import find from '../utils/find'; |
|
|
import getOffsetParent from '../utils/getOffsetParent'; |
|
|
import getBoundingClientRect from '../utils/getBoundingClientRect'; |
|
|
import getRoundedOffsets from '../utils/getRoundedOffsets'; |
|
|
import isBrowser from '../utils/isBrowser'; |
|
|
|
|
|
const isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default function computeStyle(data, options) { |
|
|
const { x, y } = options; |
|
|
const { popper } = data.offsets; |
|
|
|
|
|
|
|
|
const legacyGpuAccelerationOption = find( |
|
|
data.instance.modifiers, |
|
|
modifier => modifier.name === 'applyStyle' |
|
|
).gpuAcceleration; |
|
|
if (legacyGpuAccelerationOption !== undefined) { |
|
|
console.warn( |
|
|
'WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!' |
|
|
); |
|
|
} |
|
|
const gpuAcceleration = |
|
|
legacyGpuAccelerationOption !== undefined |
|
|
? legacyGpuAccelerationOption |
|
|
: options.gpuAcceleration; |
|
|
|
|
|
const offsetParent = getOffsetParent(data.instance.popper); |
|
|
const offsetParentRect = getBoundingClientRect(offsetParent); |
|
|
|
|
|
|
|
|
const styles = { |
|
|
position: popper.position, |
|
|
}; |
|
|
|
|
|
const offsets = getRoundedOffsets( |
|
|
data, |
|
|
window.devicePixelRatio < 2 || !isFirefox |
|
|
); |
|
|
|
|
|
const sideA = x === 'bottom' ? 'top' : 'bottom'; |
|
|
const sideB = y === 'right' ? 'left' : 'right'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const prefixedProperty = getSupportedPropertyName('transform'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let left, top; |
|
|
if (sideA === 'bottom') { |
|
|
|
|
|
|
|
|
if (offsetParent.nodeName === 'HTML') { |
|
|
top = -offsetParent.clientHeight + offsets.bottom; |
|
|
} else { |
|
|
top = -offsetParentRect.height + offsets.bottom; |
|
|
} |
|
|
} else { |
|
|
top = offsets.top; |
|
|
} |
|
|
if (sideB === 'right') { |
|
|
if (offsetParent.nodeName === 'HTML') { |
|
|
left = -offsetParent.clientWidth + offsets.right; |
|
|
} else { |
|
|
left = -offsetParentRect.width + offsets.right; |
|
|
} |
|
|
} else { |
|
|
left = offsets.left; |
|
|
} |
|
|
if (gpuAcceleration && prefixedProperty) { |
|
|
styles[prefixedProperty] = `translate3d(${left}px, ${top}px, 0)`; |
|
|
styles[sideA] = 0; |
|
|
styles[sideB] = 0; |
|
|
styles.willChange = 'transform'; |
|
|
} else { |
|
|
|
|
|
const invertTop = sideA === 'bottom' ? -1 : 1; |
|
|
const invertLeft = sideB === 'right' ? -1 : 1; |
|
|
styles[sideA] = top * invertTop; |
|
|
styles[sideB] = left * invertLeft; |
|
|
styles.willChange = `${sideA}, ${sideB}`; |
|
|
} |
|
|
|
|
|
|
|
|
const attributes = { |
|
|
'x-placement': data.placement, |
|
|
}; |
|
|
|
|
|
|
|
|
data.attributes = { ...attributes, ...data.attributes }; |
|
|
data.styles = { ...styles, ...data.styles }; |
|
|
data.arrowStyles = { ...data.offsets.arrow, ...data.arrowStyles }; |
|
|
|
|
|
return data; |
|
|
} |
|
|
|