/*! autosize 4.0.2 license: MIT http://www.jacklmoore.com/autosize */ ( function ( global, factory ) { if ( typeof define === 'function' && define.amd ) { define( [ 'module', 'exports' ], factory ); } else if ( typeof exports !== 'undefined' ) { factory( module, exports ); } else { var mod = { exports: {} }; factory( mod, mod.exports ); global.autosize = mod.exports; } }( this, function ( module, exports ) { 'use strict'; var map = typeof Map === 'function' ? new Map() : ( function () { var keys = [], values = []; return { has: function has( key ) { return keys.indexOf( key ) > -1; }, get: function get( key ) { return values[ keys.indexOf( key ) ]; }, set: function set( key, value ) { if ( keys.indexOf( key ) === -1 ) { keys.push( key ); values.push( value ); } }, delete: function _delete( key ) { var index = keys.indexOf( key ); if ( index > -1 ) { keys.splice( index, 1 ); values.splice( index, 1 ); } } }; }() ), createEvent = function createEvent( name ) { return new Event( name, { bubbles: true } ); }; try { new Event( 'test' ); } catch ( e ) { // IE does not support `new Event()` createEvent = function createEvent( name ) { var evt = document.createEvent( 'Event' ); evt.initEvent( name, true, false ); return evt; }; } function assign( ta ) { if ( !ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has( ta ) ) { return; } var heightOffset = null, clientWidth = null, cachedHeight = null; function init() { var style = window.getComputedStyle( ta, null ); if ( style.resize === 'vertical' ) { ta.style.resize = 'none'; } else if ( style.resize === 'both' ) { ta.style.resize = 'horizontal'; } if ( style.boxSizing === 'content-box' ) { heightOffset = -( parseFloat( style.paddingTop ) + parseFloat( style.paddingBottom ) ); } else { heightOffset = parseFloat( style.borderTopWidth ) + parseFloat( style.borderBottomWidth ); } // Fix when a textarea is not on document body and heightOffset is Not a Number if ( isNaN( heightOffset ) ) { heightOffset = 0; } update(); } function changeOverflow( value ) { { // Chrome/Safari-specific fix: // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space // made available by removing the scrollbar. The following forces the necessary text reflow. var width = ta.style.width; ta.style.width = '0px'; // Force reflow: /* jshint ignore:start */ ta.offsetWidth; /* jshint ignore:end */ ta.style.width = width; } ta.style.overflowY = value; } function getParentOverflows( el ) { var arr = []; while ( el && el.parentNode && el.parentNode instanceof Element ) { if ( el.parentNode.scrollTop ) { arr.push( { node: el.parentNode, scrollTop: el.parentNode.scrollTop } ); } el = el.parentNode; } return arr; } function resize() { if ( ta.scrollHeight === 0 ) { // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. return; } var overflows = getParentOverflows( ta ), docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240) ta.style.height = ''; ta.style.height = ta.scrollHeight + heightOffset + 'px'; // used to check if an update is actually necessary on window.resize clientWidth = ta.clientWidth; // prevents scroll-position jumping overflows.forEach( function ( el ) { el.node.scrollTop = el.scrollTop; } ); if ( docTop ) { document.documentElement.scrollTop = docTop; } } function update() { resize(); var styleHeight = Math.round( parseFloat( ta.style.height ) ), computed = window.getComputedStyle( ta, null ), // Using offsetHeight as a replacement for computed.height in IE, because IE does not account use of border-box actualHeight = computed.boxSizing === 'content-box' ? Math.round( parseFloat( computed.height ) ) : ta.offsetHeight; // The actual height not matching the style height (set via the resize method) indicates that // the max-height has been exceeded, in which case the overflow should be allowed. if ( actualHeight < styleHeight ) { if ( computed.overflowY === 'hidden' ) { changeOverflow( 'scroll' ); resize(); actualHeight = computed.boxSizing === 'content-box' ? Math.round( parseFloat( window.getComputedStyle( ta, null ).height ) ) : ta.offsetHeight; } } else { // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. if ( computed.overflowY !== 'hidden' ) { changeOverflow( 'hidden' ); resize(); actualHeight = computed.boxSizing === 'content-box' ? Math.round( parseFloat( window.getComputedStyle( ta, null ).height ) ) : ta.offsetHeight; } } if ( cachedHeight !== actualHeight ) { cachedHeight = actualHeight; var evt = createEvent( 'autosize:resized' ); try { ta.dispatchEvent( evt ); } catch ( err ) { // Firefox will throw an error on dispatchEvent for a detached element // https://bugzilla.mozilla.org/show_bug.cgi?id=889376 } } } var pageResize = function pageResize() { if ( ta.clientWidth !== clientWidth ) { update(); } }, destroy = function ( style ) { window.removeEventListener( 'resize', pageResize, false ); ta.removeEventListener( 'input', update, false ); ta.removeEventListener( 'keyup', update, false ); ta.removeEventListener( 'autosize:destroy', destroy, false ); ta.removeEventListener( 'autosize:update', update, false ); Object.keys( style ).forEach( function ( key ) { ta.style[ key ] = style[ key ]; } ); map.delete( ta ); }.bind( ta, { height: ta.style.height, resize: ta.style.resize, overflowY: ta.style.overflowY, overflowX: ta.style.overflowX, wordWrap: ta.style.wordWrap } ); ta.addEventListener( 'autosize:destroy', destroy, false ); // IE9 does not fire onpropertychange or oninput for deletions, // so binding to onkeyup to catch most of those events. // There is no way that I know of to detect something like 'cut' in IE9. if ( 'onpropertychange' in ta && 'oninput' in ta ) { ta.addEventListener( 'keyup', update, false ); } window.addEventListener( 'resize', pageResize, false ); ta.addEventListener( 'input', update, false ); ta.addEventListener( 'autosize:update', update, false ); ta.style.overflowX = 'hidden'; ta.style.wordWrap = 'break-word'; map.set( ta, { destroy: destroy, update: update } ); init(); } function destroy( ta ) { var methods = map.get( ta ); if ( methods ) { methods.destroy(); } } function update( ta ) { var methods = map.get( ta ); if ( methods ) { methods.update(); } } var autosize = null; // Do nothing in Node.js environment and IE8 (or lower) if ( typeof window === 'undefined' || typeof window.getComputedStyle !== 'function' ) { autosize = function autosize( el ) { return el; }; autosize.destroy = function ( el ) { return el; }; autosize.update = function ( el ) { return el; }; } else { autosize = function autosize( el, options ) { if ( el ) { Array.prototype.forEach.call( el.length ? el : [ el ], function ( x ) { return assign( x, options ); } ); } return el; }; autosize.destroy = function ( el ) { if ( el ) { Array.prototype.forEach.call( el.length ? el : [ el ], destroy ); } return el; }; autosize.update = function ( el ) { if ( el ) { Array.prototype.forEach.call( el.length ? el : [ el ], update ); } return el; }; } exports.default = autosize; module.exports = exports.default; } ) );