choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
427 lines (344 loc) • 13.1 kB
JavaScript
"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