The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/packages/rocketchat-ui/client/lib/textarea-autogrow.js

129 lines
3.0 KiB

import _ from 'underscore';
(function($) {
/**
* Auto-growing textareas; technique ripped from Facebook
*
*
* http://github.com/jaz303/jquery-grab-bag/tree/master/javascripts/jquery.autogrow-textarea.js
*/
$.fn.autogrow = function(options) {
let shadow = $('body > #autogrow-shadow');
if (!shadow.length) {
shadow = $('<div id="autogrow-shadow"></div>').addClass('autogrow-shadow').appendTo(document.body);
}
return this.filter('textarea').each(function() {
const self = this;
const $self = $(self);
const minHeight = $self.height();
const settings = {
postGrowCallback: null,
...options,
};
const maxHeight = window.getComputedStyle(self)['max-height'].replace('px', '');
let width = $self.width();
shadow.css({
position: 'absolute',
top: -10000,
left: -10000,
width,
fontSize: $self.css('fontSize'),
fontFamily: $self.css('fontFamily'),
fontWeight: $self.css('fontWeight'),
lineHeight: $self.css('lineHeight'),
resize: 'none',
wordWrap: 'break-word',
});
const trigger = _.debounce(() => $self.trigger('autogrow', []), 500);
const times = function(string, number) {
let r = '';
for (let i = 0; i < number; i++) { r += string; }
return r;
};
const runTimes = (space) => `${ times('&nbsp;', space.length - 1) } `;
let lastWidth = width;
let lastHeight = minHeight;
let length = 0;
const update = function update(event) {
if (lastHeight >= maxHeight && length && length < self.value.length) {
return true;
}
let val = self.value.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/&/g, '&amp;')
.replace(/\n$/, '<br/>&nbsp;')
.replace(/\n/g, '<br/>')
.replace(/ {2,}/g, runTimes);
// Did enter get pressed? Resize in this keydown event so that the flicker doesn't occur.
if (event && event.data && event.data.event === 'keydown' && event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) {
val += '<br/>';
}
if (width < 10) {
width = $self.width();
}
if (width !== lastWidth) {
shadow.css('width', width);
lastWidth = width;
}
shadow[0].innerHTML = val;
let newHeight = Math.max(shadow[0].clientHeight + 1, minHeight) + 1;
let overflow = 'hidden';
if (newHeight >= maxHeight) {
newHeight = maxHeight;
overflow = '';
} else {
length = self.value.length;
}
if (newHeight === lastHeight) {
return true;
}
lastHeight = newHeight;
$self.css({ overflow, height: newHeight });
trigger();
if (settings.postGrowCallback !== null) {
settings.postGrowCallback($self);
}
};
const updateWidth = () => {
length = 0;
width = $self.width();
update();
};
const updateWidthDebounce = _.debounce(updateWidth, 300);
const updateThrottle = _.throttle(update, 300);
$self.on('focus change input', updateThrottle);
$(window).resize(updateWidthDebounce);
update();
self.updateAutogrow = updateThrottle;
});
};
}(jQuery));