docbrown/app/assets/javascripts/initializers/initEditorResize.js
Mike Chen 7ce311834f Fix errant scroll behavior on /new when using keyboard scrolling (#1203)
Disable textarea resize and window scroll method when doing anything
that does not actually modify the textarea contents (e.g. arrow keys,
pgup/pgdn).

Fixes #1109
2018-11-28 14:57:21 -05:00

92 lines
2.5 KiB
JavaScript

/**
* This auto-resize function is made for textarea in /new.
* It is a slightly modified version of the solution found here.
* stackoverflow.com/questions/18262729/ how-to-stop-window-jumping-when-typing-in-autoresizing-textarea
*/
// eslint-disable-next-line no-unused-vars
function initEditorResize() {
var observe;
var scrollLeft;
var scrollTop;
var lastText;
var textarea = document.getElementById('article_body_markdown');
var oldEditor = document.getElementById('markdown-editor-main');
if (!textarea) {
return;
}
if (window.attachEvent) {
observe = function(element, event, handler) {
element.attachEvent('on' + event, handler);
};
} else {
observe = function(element, event, handler) {
element.addEventListener(event, handler, false);
};
}
function getScrollLeft() {
return (
window.pageXOffset ||
(document.documentElement || document.body.parentNode || document.body)
.scrollLeft
);
}
function getScrollTop() {
return (
window.pageYOffset ||
(document.documentElement || document.body.parentNode || document.body)
.scrollTop
);
}
function resize() {
var len;
var newText = textarea.value;
// Don't resize or scroll if not modifying the text
if (newText === lastText) {
return;
}
lastText = newText;
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight - 29 + 'px';
window.scrollTo(scrollLeft, scrollTop);
if (oldEditor) {
return;
}
len = textarea.value.length;
// If character entered is at the end of the textarea (therefore cursor)
if (
textarea.selectionEnd > len - 15 &&
len > 400 &&
document.activeElement === textarea
) {
window.scrollTo(scrollLeft, 10000);
} else {
window.scrollTo(scrollLeft, scrollTop);
}
}
function delayedResize() {
/**
* scrollLeft and scrollTop are kept in delayedResize because
* of a weird browser auto-focused when pressing enter in a textarea.
* This happens when the carot is either too low or too high based on
* the screen.
*/
scrollLeft = getScrollLeft();
scrollTop = getScrollTop();
/* 0-timeout to get the already changed text */
window.setTimeout(resize, 0);
}
// observe(textarea, 'change', resize);
observe(textarea, 'cut', delayedResize);
observe(textarea, 'paste', delayedResize);
observe(textarea, 'drop', delayedResize);
observe(textarea, 'keydown', delayedResize);
// textarea.focus();
resize();
}