zent
Version:
一套前端设计语言和基于React的实现
104 lines (103 loc) • 2.86 kB
JavaScript
import createElement from './createElement';
import isBrowser from '../isBrowser';
import isFirefox from '../isFirefox';
var properties = [
'direction',
'boxSizing',
'width',
'height',
'overflowX',
'overflowY',
'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth',
'borderStyle',
'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft',
'fontStyle',
'fontVariant',
'fontWeight',
'fontStretch',
'fontSize',
'fontSizeAdjust',
'lineHeight',
'fontFamily',
'textAlign',
'textTransform',
'textIndent',
'textDecoration',
'letterSpacing',
'wordSpacing',
'tabSize',
'MozTabSize',
];
var MIRROR_DIV_ID = 'zent-input-textarea-caret-coordinates-mirror-div';
function getCaretCoordinates(element, position, _a) {
var debug = _a.debug;
if (!isBrowser) {
throw new Error('getCaretCoordinates should only be called in a browser');
}
if (debug) {
var el = document.getElementById(MIRROR_DIV_ID);
if (el)
el.parentNode.removeChild(el);
}
var div = createElement('div');
div.id = MIRROR_DIV_ID;
document.body.appendChild(div);
var style = div.style;
var computed = getComputedStyle(element);
var isInput = element.nodeName === 'INPUT';
if (!isInput) {
style.whiteSpace = 'pre-wrap';
style.wordWrap = 'break-word';
}
else {
style.whiteSpace = 'nowrap';
}
style.position = 'absolute';
if (!debug)
style.visibility = 'hidden';
properties.forEach(function (prop) {
if (isInput && prop === 'lineHeight') {
style.lineHeight = computed.height;
}
else {
style[prop] = computed[prop];
}
});
if (isFirefox) {
if (element.scrollHeight > parseInt(computed.height, 10)) {
style.overflowY = 'scroll';
}
}
else {
style.overflow = 'hidden';
}
div.textContent = element.value.substring(0, position);
if (isInput)
div.textContent = div.textContent.replace(/\s/g, '\u00a0');
var span = createElement('span');
span.textContent = element.value.substring(position) || '.';
div.appendChild(span);
var rawOffsetLeft = span.offsetLeft + parseInt(computed.borderLeftWidth, 10);
var lineHeight = parseInt(computed.lineHeight, 10);
var coordinates = {
top: span.offsetTop + parseInt(computed.borderTopWidth, 10),
left: rawOffsetLeft,
height: Number.isNaN(lineHeight)
? parseInt(computed.fontSize, 10) * 1.5
: lineHeight,
};
if (debug) {
span.style.backgroundColor = '#aaa';
}
else {
document.body.removeChild(div);
}
return coordinates;
}
export default getCaretCoordinates;