'height',
'overflowX',
'overflowY', // copy the scrollbar for IE

'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth',
'borderStyle',

'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft',

// https://developer.mozilla.org/en-US/docs/Web/CSS/font
'fontStyle',
'fontVariant',
'fontWeight',
'fontStretch',
'fontSize',
'fontSizeAdjust',
'lineHeight',
'fontFamily',

'textAlign',
'textTransform',
'textIndent',
'textDecoration', // might not make a difference, but better be safe

'letterSpacing',
'wordSpacing',

'tabSize',
'MozTabSize'

];

var isFirefox = window.mozInnerScreenX != null;

function getCaretCoordinates(element, position, options) {

var debug = options && options.debug || false;
if (debug) {
var el = document.querySelector('#input-textarea-caret-position-mirror-div');
if ( el ) { el.parentNode.removeChild(el); }
}

// mirrored div
var div = document.createElement('div');
div.id = 'input-textarea-caret-position-mirror-div';
document.body.appendChild(div);

var style = div.style;
var computed = window.getComputedStyle? getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9

// default textarea styles
style.whiteSpace = 'pre-wrap';
if (element.nodeName !== 'INPUT')
style.wordWrap = 'break-word'; // only for textarea-s

// position off-screen
style.position = 'absolute'; // required to return coordinates properly
if (!debug)
style.visibility = 'hidden'; // not 'display: none' because we want rendering

// transfer the element's properties to the div
properties.forEach(function (prop) {
style[prop] = computed[prop];
});

if (isFirefox) {
// Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
if (element.scrollHeight > parseInt(computed.height))
style.overflowY = 'scroll';
} else {
style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
}

div.textContent = element.value.substring(0, position);
// the second special handling for input type="text" vs textarea: spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
if (element.nodeName === 'INPUT')
div.textContent = div.textContent.replace(/\s/g, "\u00a0");

var span = document.createElement('span');
// Wrapping must be replicated *exactly*, including when a long word gets
// onto the next line, with whitespace at the end of the line before (#7).
// The *only* reliable way to do that is to copy the *entire* rest of the
// textarea's content into the <span> created at the caret position.
// for inputs, just '.' would be enough, but why bother?
span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
div.appendChild(span);

var coordinates = {
top: span.offsetTop + parseInt(computed['borderTopWidth']),
left: span.offsetLeft + parseInt(computed['borderLeftWidth'])
};

if (debug) {
span.style.backgroundColor = '#aaa';
} else {
document.body.removeChild(div);
}

return coordinates;
}

if (typeof module != "undefined" && typeof module.exports != "undefined") {
module.exports = getCaretCoordinates;
} else {
window.getCaretCoordinates = getCaretCoordinates;
}

}());

/***/ })
/******/ ])
});

Prev | Next
Pg.: 1 2 3


Back to home | File page

Subscribe | Register | Login | N