hm-react-cli
Version:
Create a Huimei React project by module
228 lines (184 loc) • 7.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _utils = require('./utils');
var _utils2 = _interopRequireDefault(_utils);
var _getOffsetParent = require('./getOffsetParent');
var _getOffsetParent2 = _interopRequireDefault(_getOffsetParent);
var _getVisibleRectForElement = require('./getVisibleRectForElement');
var _getVisibleRectForElement2 = _interopRequireDefault(_getVisibleRectForElement);
var _adjustForViewport = require('./adjustForViewport');
var _adjustForViewport2 = _interopRequireDefault(_adjustForViewport);
var _getRegion = require('./getRegion');
var _getRegion2 = _interopRequireDefault(_getRegion);
var _getElFuturePos = require('./getElFuturePos');
var _getElFuturePos2 = _interopRequireDefault(_getElFuturePos);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
// http://yiminghe.iteye.com/blog/1124720
/**
* align dom node flexibly
* @author yiminghe@gmail.com
*/
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 isOutOfVisibleRect(target) {
var visibleRect = (0, _getVisibleRectForElement2['default'])(target);
var targetRegion = (0, _getRegion2['default'])(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) {
var ret = [];
_utils2['default'].each(points, function (p) {
ret.push(p.replace(reg, function (m) {
return map[m];
}));
});
return ret;
}
function flipOffset(offset, index) {
offset[index] = -offset[index];
return offset;
}
function convertOffset(str, offsetLen) {
var n = void 0;
if (/%$/.test(str)) {
n = parseInt(str.substring(0, str.length - 1), 10) / 100 * offsetLen;
} else {
n = parseInt(str, 10);
}
return n || 0;
}
function normalizeOffset(offset, el) {
offset[0] = convertOffset(offset[0], el.width);
offset[1] = convertOffset(offset[1], el.height);
}
function domAlign(el, refNode, align) {
var points = align.points;
var offset = align.offset || [0, 0];
var targetOffset = align.targetOffset || [0, 0];
var overflow = align.overflow;
var target = align.target || refNode;
var source = align.source || el;
offset = [].concat(offset);
targetOffset = [].concat(targetOffset);
overflow = overflow || {};
var newOverflowCfg = {};
var fail = 0;
// 当前节点可以被放置的显示区域
var visibleRect = (0, _getVisibleRectForElement2['default'])(source);
// 当前节点所占的区域, left/top/width/height
var elRegion = (0, _getRegion2['default'])(source);
// 参照节点所占的区域, left/top/width/height
var refNodeRegion = (0, _getRegion2['default'])(target);
// 将 offset 转换成数值,支持百分比
normalizeOffset(offset, elRegion);
normalizeOffset(targetOffset, refNodeRegion);
// 当前节点将要被放置的位置
var elFuturePos = (0, _getElFuturePos2['default'])(elRegion, refNodeRegion, points, offset, targetOffset);
// 当前节点将要所处的区域
var newElRegion = _utils2['default'].merge(elRegion, elFuturePos);
var isTargetNotOutOfVisible = !isOutOfVisibleRect(target);
// 如果可视区域不能完全放置当前节点时允许调整
if (visibleRect && (overflow.adjustX || overflow.adjustY) && isTargetNotOutOfVisible) {
if (overflow.adjustX) {
// 如果横向不能放下
if (isFailX(elFuturePos, elRegion, visibleRect)) {
// 对齐位置反下
var newPoints = flip(points, /[lr]/ig, {
l: 'r',
r: 'l'
});
// 偏移量也反下
var newOffset = flipOffset(offset, 0);
var newTargetOffset = flipOffset(targetOffset, 0);
var newElFuturePos = (0, _getElFuturePos2['default'])(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]/ig, {
t: 'b',
b: 't'
});
// 偏移量也反下
var _newOffset = flipOffset(offset, 1);
var _newTargetOffset = flipOffset(targetOffset, 1);
var _newElFuturePos = (0, _getElFuturePos2['default'])(elRegion, refNodeRegion, _newPoints, _newOffset, _newTargetOffset);
if (!isCompleteFailY(_newElFuturePos, elRegion, visibleRect)) {
fail = 1;
points = _newPoints;
offset = _newOffset;
targetOffset = _newTargetOffset;
}
}
}
// 如果失败,重新计算当前节点将要被放置的位置
if (fail) {
elFuturePos = (0, _getElFuturePos2['default'])(elRegion, refNodeRegion, points, offset, targetOffset);
_utils2['default'].mix(newElRegion, elFuturePos);
}
// 检查反下后的位置是否可以放下了
// 如果仍然放不下只有指定了可以调整当前方向才调整
newOverflowCfg.adjustX = overflow.adjustX && isFailX(elFuturePos, elRegion, visibleRect);
newOverflowCfg.adjustY = overflow.adjustY && isFailY(elFuturePos, elRegion, visibleRect);
// 确实要调整,甚至可能会调整高度宽度
if (newOverflowCfg.adjustX || newOverflowCfg.adjustY) {
newElRegion = (0, _adjustForViewport2['default'])(elFuturePos, elRegion, visibleRect, newOverflowCfg);
}
}
// need judge to in case set fixed with in css on height auto element
if (newElRegion.width !== elRegion.width) {
_utils2['default'].css(source, 'width', _utils2['default'].width(source) + newElRegion.width - elRegion.width);
}
if (newElRegion.height !== elRegion.height) {
_utils2['default'].css(source, 'height', _utils2['default'].height(source) + newElRegion.height - elRegion.height);
}
// https://github.com/kissyteam/kissy/issues/190
// 相对于屏幕位置没变,而 left/top 变了
// 例如 <div 'relative'><el absolute></div>
_utils2['default'].offset(source, {
left: newElRegion.left,
top: newElRegion.top
}, {
useCssRight: align.useCssRight,
useCssBottom: align.useCssBottom,
useCssTransform: align.useCssTransform
});
return {
points: points,
offset: offset,
targetOffset: targetOffset,
overflow: newOverflowCfg
};
}
domAlign.__getOffsetParent = _getOffsetParent2['default'];
domAlign.__getVisibleRectForElement = _getVisibleRectForElement2['default'];
exports['default'] = domAlign;
/**
* 2012-04-26 yiminghe@gmail.com
* - 优化智能对齐算法
* - 慎用 resizeXX
*
* 2011-07-13 yiminghe@gmail.com note:
* - 增加智能对齐,以及大小调整选项
**/
module.exports = exports['default'];