UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

427 lines (344 loc) 13.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; Object.defineProperty(exports, "__esModule", { value: true }); exports.alignPoint = alignPoint; exports["default"] = alignElement; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _DocumentUtils = require("../../pro/lib/_util/DocumentUtils"); var _isString = _interopRequireDefault(require("lodash/isString")); var _UnitConvertor = require("../_util/UnitConvertor"); function isFailX(elFuturePos, elRegion, visibleRect) { return elFuturePos.left < visibleRect.left || elFuturePos.left + elRegion.width > visibleRect.right; } function isFailY(elFuturePos, elRegion, visibleRect) { return elFuturePos.top < visibleRect.top || elFuturePos.top + elRegion.height > visibleRect.bottom; } function isCompleteFailX(elFuturePos, elRegion, visibleRect) { return elFuturePos.left > visibleRect.right || elFuturePos.left + elRegion.width < visibleRect.left; } function isCompleteFailY(elFuturePos, elRegion, visibleRect) { return elFuturePos.top > visibleRect.bottom || elFuturePos.top + elRegion.height < visibleRect.top; } function getParent(element) { var parent = element; do { parent = parent.parentElement; } while (parent && parent.nodeType !== 1 && parent.nodeType !== 9); return parent; } function getOffsetParentAndStyle(el, defaultView) { var _defaultView$getCompu = defaultView.getComputedStyle(el), position = _defaultView$getCompu.position; if (position !== 'absolute' && position !== 'fixed') { if (!(0, _isString["default"])(el.nodeName) || el.nodeName.toLowerCase() !== 'html') { var parent = getParent(el); if (parent) { return { parent: parent, style: null }; } } } else { var body = defaultView.document.body; for (var _parent = getParent(el); _parent && _parent !== body && _parent.nodeType !== 9; _parent = getParent(_parent)) { var style = defaultView.getComputedStyle(_parent); if (style.position !== 'static') { return { parent: _parent, style: style }; } } } return null; } function getVisibleRectForElement(element) { var ownerDocument = element.ownerDocument; if (ownerDocument) { var defaultView = ownerDocument.defaultView; if (defaultView) { var _body = ownerDocument.body, documentElement = ownerDocument.documentElement; var offsetParentAndStyle = getOffsetParentAndStyle(element, defaultView); while (offsetParentAndStyle) { var _offsetParentAndStyle = offsetParentAndStyle, parent = _offsetParentAndStyle.parent, style = _offsetParentAndStyle.style; if (!parent || parent === _body || parent === documentElement) { break; } if ((style || defaultView.getComputedStyle(parent)).overflow !== 'visible') { var rect = parent.getBoundingClientRect(); var _getMousePosition = (0, _DocumentUtils.getMousePosition)(rect.left, rect.top, defaultView, true), x = _getMousePosition.x, y = _getMousePosition.y; return { top: y, right: rect.right + x - rect.left, bottom: rect.bottom + y - rect.top, left: x }; } offsetParentAndStyle = getOffsetParentAndStyle(parent, defaultView); } } } var _getDocument = (0, _DocumentUtils.getDocument)(window), body = _getDocument.body; return { top: 0, right: body.clientWidth, bottom: body.clientHeight, left: 0 }; } function getRegion(node) { var rect = node.getBoundingClientRect(); var ownerDocument = node.ownerDocument; var defaultView = ownerDocument ? ownerDocument.defaultView : null; var position = defaultView ? (0, _DocumentUtils.getMousePosition)(rect.left, rect.top, defaultView, true) : { x: rect.left, y: rect.top }; return { top: position.y, left: position.x, width: rect.width || node.offsetWidth, height: rect.height || node.offsetHeight }; } function isOutOfVisibleRect(target) { var visibleRect = getVisibleRectForElement(target); var targetRegion = getRegion(target); return !visibleRect || targetRegion.left + targetRegion.width <= visibleRect.left || targetRegion.top + targetRegion.height <= visibleRect.top || targetRegion.left >= visibleRect.right || targetRegion.top >= visibleRect.bottom; } function flip(points, reg, map) { return points.map(function (p) { return p.replace(reg, function (m) { return map[m]; }); }); } function flipOffset(offset, index) { offset[index] = -offset[index]; return offset; } function getAlignOffset(region, align) { var V = align.charAt(0); var H = align.charAt(1); var w = region.width; var h = region.height; var x = region.left; var y = region.top; if (V === 'c') { y += h / 2; } else if (V === 'b') { y += h; } if (H === 'c') { x += w / 2; } else if (H === 'r') { x += w; } return { left: x, top: y }; } function getElFuturePos(elRegion, refNodeRegion, points, offset, targetOffset) { var p1 = getAlignOffset(refNodeRegion, points[1]); var p2 = getAlignOffset(elRegion, points[0]); var diff = [p2.left - p1.left, p2.top - p1.top]; return { left: elRegion.left - diff[0] + offset[0] - targetOffset[0], top: elRegion.top - diff[1] + offset[1] - targetOffset[1] }; } function adjustForViewport(elFuturePos, elRegion, visibleRect, overflow) { var pos = (0, _objectSpread2["default"])({}, elFuturePos); var size = { width: elRegion.width, height: elRegion.height }; if (overflow.adjustX && pos.left < visibleRect.left) { pos.left = visibleRect.left; } // Left edge inside and right edge outside viewport, try to resize it. if (overflow.resizeWidth && pos.left >= visibleRect.left && pos.left + size.width > visibleRect.right) { size.width -= pos.left + size.width - visibleRect.right; } // Right edge outside viewport, try to move it. if (overflow.adjustX && pos.left + size.width > visibleRect.right) { // 保证左边界和可视区域左边界对齐 pos.left = Math.max(visibleRect.right - size.width, visibleRect.left); } // Top edge outside viewport, try to move it. if (overflow.adjustY && pos.top < visibleRect.top) { pos.top = visibleRect.top; } // Top edge inside and bottom edge outside viewport, try to resize it. if (overflow.resizeHeight && pos.top >= visibleRect.top && pos.top + size.height > visibleRect.bottom) { size.height -= pos.top + size.height - visibleRect.bottom; } // Bottom edge outside viewport, try to move it. if (overflow.adjustY && pos.top + size.height > visibleRect.bottom) { // 保证上边界和可视区域上边界对齐 pos.top = Math.max(visibleRect.bottom - size.height, visibleRect.top); } return (0, _extends2["default"])(pos, size); } // function isFixedPosition(node: HTMLElement): boolean { // const { offsetParent, ownerDocument } = node; // if ( // ownerDocument && // offsetParent === ownerDocument.body && // ownerDocument.defaultView && // ownerDocument.defaultView.getComputedStyle(node).position !== 'fixed' // ) { // return false; // } // if (offsetParent) { // return isFixedPosition(offsetParent as HTMLElement); // } // return true; // } function doAlign(el, refNodeRegion, align, isTargetNotOutOfVisible) { var points = align.points; var offset = (align.offset || [0, 0]).slice(); var targetOffset = (align.targetOffset || [0, 0]).slice(); var overflow = align.overflow || {}; var source = align.source || el; var newOverflowCfg = {}; var fail = 0; var visibleRect = getVisibleRectForElement(el); var elRegion = getRegion(source); var elFuturePos = getElFuturePos(elRegion, refNodeRegion, points, offset, targetOffset); var newElRegion = (0, _extends2["default"])(elRegion, elFuturePos); if (visibleRect && (overflow.adjustX || overflow.adjustY) && isTargetNotOutOfVisible) { if (overflow.adjustX) { if (isFailX(elFuturePos, elRegion, visibleRect)) { var newPoints = flip(points, /[lr]/gi, { l: 'r', r: 'l' }); var newOffset = flipOffset(offset, 0); var newTargetOffset = flipOffset(targetOffset, 0); var newElFuturePos = getElFuturePos(elRegion, refNodeRegion, newPoints, newOffset, newTargetOffset); if (!isCompleteFailX(newElFuturePos, elRegion, visibleRect)) { fail = 1; points = newPoints; offset = newOffset; targetOffset = newTargetOffset; } } } if (overflow.adjustY) { if (isFailY(elFuturePos, elRegion, visibleRect)) { var _newPoints = flip(points, /[tb]/gi, { t: 'b', b: 't' }); var _newOffset = flipOffset(offset, 1); var _newTargetOffset = flipOffset(targetOffset, 1); var _newElFuturePos = getElFuturePos(elRegion, refNodeRegion, _newPoints, _newOffset, _newTargetOffset); if (!isCompleteFailY(_newElFuturePos, elRegion, visibleRect)) { fail = 1; points = _newPoints; offset = _newOffset; targetOffset = _newTargetOffset; } } } if (fail) { elFuturePos = getElFuturePos(elRegion, refNodeRegion, points, offset, targetOffset); (0, _extends2["default"])(newElRegion, elFuturePos); } newOverflowCfg.adjustX = overflow.adjustX && isFailX(elFuturePos, elRegion, visibleRect); newOverflowCfg.adjustY = overflow.adjustY && isFailY(elFuturePos, elRegion, visibleRect); if (newOverflowCfg.adjustX || newOverflowCfg.adjustY) { newElRegion = adjustForViewport(elFuturePos, elRegion, visibleRect, newOverflowCfg); } } var _newElRegion = newElRegion, width = _newElRegion.width, height = _newElRegion.height; if (width !== elRegion.width) { source.style.width = width ? (0, _UnitConvertor.pxToRem)(width, true) : '0'; } if (height !== elRegion.height) { source.style.height = height ? (0, _UnitConvertor.pxToRem)(height, true) : '0'; } // const isTargetFixed = isFixedPosition(target); var offsetParent = source.offsetParent, ownerDocument = source.ownerDocument; if (offsetParent) { var _offsetParent$getBoun = offsetParent.getBoundingClientRect(), left = _offsetParent$getBoun.left, top = _offsetParent$getBoun.top; newElRegion.left -= left; newElRegion.top -= top; } if (ownerDocument) { var _getMousePosition2 = (0, _DocumentUtils.getMousePosition)(0, 0, ownerDocument.defaultView || window, true), x = _getMousePosition2.x, y = _getMousePosition2.y; newElRegion.left -= x; newElRegion.top -= y; } (0, _extends2["default"])(source.style, { left: (0, _UnitConvertor.pxToRem)(newElRegion.left, true), top: (0, _UnitConvertor.pxToRem)(newElRegion.top, true) }); // if (isTargetFixed) { // source.style.position = 'fixed'; // } else { // source.style.position = ''; // } return { points: points, offset: offset, targetOffset: targetOffset, overflow: newOverflowCfg }; } function alignElement(el, refNode, align) { var target = align.target || refNode; var refNodeRegion = getRegion(target); var isTargetNotOutOfVisible = !isOutOfVisibleRect(target); return doAlign(el, refNodeRegion, align, isTargetNotOutOfVisible); } function alignPoint(el, tgtPoint, align) { var left = 0; var top = 0; var ownerDocument = el.ownerDocument; var defaultView = ownerDocument ? ownerDocument.defaultView : null; var documentElement = ownerDocument ? ownerDocument.documentElement : null; var scrollX = documentElement ? documentElement.scrollLeft : 0; var scrollY = documentElement ? documentElement.scrollTop : 0; if (tgtPoint.pageX !== undefined) { left = tgtPoint.pageX - scrollX; } else if (tgtPoint.clientX !== undefined) { left = scrollX + tgtPoint.clientX; } if (tgtPoint.pageY !== undefined) { top = tgtPoint.pageY - scrollY; } else if (tgtPoint.clientY !== undefined) { top = tgtPoint.clientY; } var position = defaultView ? (0, _DocumentUtils.getMousePosition)(left, top, defaultView, true) : { x: left, y: top, vw: documentElement ? documentElement.clientWidth : 0, vh: documentElement ? documentElement.clientHeight : 0 }; left = position.x; top = position.y; var tgtRegion = { left: left, top: top, width: 0, height: 0 }; var pointInView = left >= 0 && left <= position.vw && top >= 0 && top <= position.vh; // Provide default target point var points = [align.points[0], 'cc']; return doAlign(el, tgtRegion, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, align), {}, { points: points }), pointInView); } //# sourceMappingURL=domAlign.js.map