autosize.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*!
  2. Autosize 3.0.15
  3. license: MIT
  4. http://www.jacklmoore.com/autosize
  5. */
  6. (function (global, factory) {
  7. if (typeof define === 'function' && define.amd) {
  8. define(['exports', 'module'], factory);
  9. } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
  10. factory(exports, module);
  11. } else {
  12. var mod = {
  13. exports: {}
  14. };
  15. factory(mod.exports, mod);
  16. global.autosize = mod.exports;
  17. }
  18. })(this, function (exports, module) {
  19. 'use strict';
  20. var set = typeof Set === 'function' ? new Set() : (function () {
  21. var list = [];
  22. return {
  23. has: function has(key) {
  24. return Boolean(list.indexOf(key) > -1);
  25. },
  26. add: function add(key) {
  27. list.push(key);
  28. },
  29. 'delete': function _delete(key) {
  30. list.splice(list.indexOf(key), 1);
  31. } };
  32. })();
  33. var createEvent = function createEvent(name) {
  34. return new Event(name);
  35. };
  36. try {
  37. new Event('test');
  38. } catch (e) {
  39. // IE does not support `new Event()`
  40. createEvent = function (name) {
  41. var evt = document.createEvent('Event');
  42. evt.initEvent(name, true, false);
  43. return evt;
  44. };
  45. }
  46. function assign(ta) {
  47. var _ref = arguments[1] === undefined ? {} : arguments[1];
  48. var _ref$setOverflowX = _ref.setOverflowX;
  49. var setOverflowX = _ref$setOverflowX === undefined ? true : _ref$setOverflowX;
  50. var _ref$setOverflowY = _ref.setOverflowY;
  51. var setOverflowY = _ref$setOverflowY === undefined ? true : _ref$setOverflowY;
  52. if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return;
  53. var heightOffset = null;
  54. var overflowY = null;
  55. var clientWidth = ta.clientWidth;
  56. function init() {
  57. var style = window.getComputedStyle(ta, null);
  58. overflowY = style.overflowY;
  59. if (style.resize === 'vertical') {
  60. ta.style.resize = 'none';
  61. } else if (style.resize === 'both') {
  62. ta.style.resize = 'horizontal';
  63. }
  64. if (style.boxSizing === 'content-box') {
  65. heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom));
  66. } else {
  67. heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
  68. }
  69. // Fix when a textarea is not on document body and heightOffset is Not a Number
  70. if (isNaN(heightOffset)) {
  71. heightOffset = 0;
  72. }
  73. update();
  74. }
  75. function changeOverflow(value) {
  76. {
  77. // Chrome/Safari-specific fix:
  78. // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space
  79. // made available by removing the scrollbar. The following forces the necessary text reflow.
  80. var width = ta.style.width;
  81. ta.style.width = '0px';
  82. // Force reflow:
  83. /* jshint ignore:start */
  84. ta.offsetWidth;
  85. /* jshint ignore:end */
  86. ta.style.width = width;
  87. }
  88. overflowY = value;
  89. if (setOverflowY) {
  90. ta.style.overflowY = value;
  91. }
  92. resize();
  93. }
  94. function resize() {
  95. var htmlTop = window.pageYOffset;
  96. var bodyTop = document.body.scrollTop;
  97. var originalHeight = ta.style.height;
  98. ta.style.height = 'auto';
  99. var endHeight = ta.scrollHeight + heightOffset;
  100. if (ta.scrollHeight === 0) {
  101. // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
  102. ta.style.height = originalHeight;
  103. return;
  104. }
  105. ta.style.height = endHeight + 'px';
  106. // used to check if an update is actually necessary on window.resize
  107. clientWidth = ta.clientWidth;
  108. // prevents scroll-position jumping
  109. document.documentElement.scrollTop = htmlTop;
  110. document.body.scrollTop = bodyTop;
  111. }
  112. function update() {
  113. var startHeight = ta.style.height;
  114. resize();
  115. var style = window.getComputedStyle(ta, null);
  116. if (style.height !== ta.style.height) {
  117. if (overflowY !== 'visible') {
  118. changeOverflow('visible');
  119. }
  120. } else {
  121. if (overflowY !== 'hidden') {
  122. changeOverflow('hidden');
  123. }
  124. }
  125. if (startHeight !== ta.style.height) {
  126. var evt = createEvent('autosize:resized');
  127. ta.dispatchEvent(evt);
  128. }
  129. }
  130. var pageResize = function pageResize() {
  131. if (ta.clientWidth !== clientWidth) {
  132. update();
  133. }
  134. };
  135. var destroy = (function (style) {
  136. window.removeEventListener('resize', pageResize, false);
  137. ta.removeEventListener('input', update, false);
  138. ta.removeEventListener('keyup', update, false);
  139. ta.removeEventListener('autosize:destroy', destroy, false);
  140. ta.removeEventListener('autosize:update', update, false);
  141. set['delete'](ta);
  142. Object.keys(style).forEach(function (key) {
  143. ta.style[key] = style[key];
  144. });
  145. }).bind(ta, {
  146. height: ta.style.height,
  147. resize: ta.style.resize,
  148. overflowY: ta.style.overflowY,
  149. overflowX: ta.style.overflowX,
  150. wordWrap: ta.style.wordWrap });
  151. ta.addEventListener('autosize:destroy', destroy, false);
  152. // IE9 does not fire onpropertychange or oninput for deletions,
  153. // so binding to onkeyup to catch most of those events.
  154. // There is no way that I know of to detect something like 'cut' in IE9.
  155. if ('onpropertychange' in ta && 'oninput' in ta) {
  156. ta.addEventListener('keyup', update, false);
  157. }
  158. window.addEventListener('resize', pageResize, false);
  159. ta.addEventListener('input', update, false);
  160. ta.addEventListener('autosize:update', update, false);
  161. set.add(ta);
  162. if (setOverflowX) {
  163. ta.style.overflowX = 'hidden';
  164. ta.style.wordWrap = 'break-word';
  165. }
  166. init();
  167. }
  168. function destroy(ta) {
  169. if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
  170. var evt = createEvent('autosize:destroy');
  171. ta.dispatchEvent(evt);
  172. }
  173. function update(ta) {
  174. if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
  175. var evt = createEvent('autosize:update');
  176. ta.dispatchEvent(evt);
  177. }
  178. var autosize = null;
  179. // Do nothing in Node.js environment and IE8 (or lower)
  180. if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') {
  181. autosize = function (el) {
  182. return el;
  183. };
  184. autosize.destroy = function (el) {
  185. return el;
  186. };
  187. autosize.update = function (el) {
  188. return el;
  189. };
  190. } else {
  191. autosize = function (el, options) {
  192. if (el) {
  193. Array.prototype.forEach.call(el.length ? el : [el], function (x) {
  194. return assign(x, options);
  195. });
  196. }
  197. return el;
  198. };
  199. autosize.destroy = function (el) {
  200. if (el) {
  201. Array.prototype.forEach.call(el.length ? el : [el], destroy);
  202. }
  203. return el;
  204. };
  205. autosize.update = function (el) {
  206. if (el) {
  207. Array.prototype.forEach.call(el.length ? el : [el], update);
  208. }
  209. return el;
  210. };
  211. }
  212. module.exports = autosize;
  213. });