From 4c5ebe49852b64eb7466c7ff9ee622940a0f3bcf Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Fri, 26 Feb 2016 15:26:24 -0500 Subject: [PATCH] fixed #4020 --- public/vendor/autosize.js | 293 +++++++++++++++++++++++++------------- 1 file changed, 196 insertions(+), 97 deletions(-) diff --git a/public/vendor/autosize.js b/public/vendor/autosize.js index b6a5c39af8..aa51c70572 100644 --- a/public/vendor/autosize.js +++ b/public/vendor/autosize.js @@ -1,155 +1,254 @@ /*! - Autosize 2.0.0 + Autosize 3.0.15 license: MIT http://www.jacklmoore.com/autosize */ -'use strict'; -/*globals define*/ -(function (root, factory) { +(function (global, factory) { if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define('autosize', factory); - } else if (typeof exports === 'object') { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); + define('autosize', ['exports', 'module'], factory); + } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { + factory(exports, module); } else { - // Browser globals (root is window) - root.autosize = factory(); - } -}(this, function () { - function main(ta) { - if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || ta.hasAttribute('data-autosize-on')) { return; } + var mod = { + exports: {} + }; + factory(mod.exports, mod); + global.autosize = mod.exports; + } +})(this, function (exports, module) { + 'use strict'; + + var set = typeof Set === 'function' ? new Set() : (function () { + var list = []; + + return { + has: function has(key) { + return Boolean(list.indexOf(key) > -1); + }, + add: function add(key) { + list.push(key); + }, + 'delete': function _delete(key) { + list.splice(list.indexOf(key), 1); + } }; + })(); + + var createEvent = function createEvent(name) { + return new Event(name); + }; + try { + new Event('test'); + } catch (e) { + // IE does not support `new Event()` + createEvent = function (name) { + var evt = document.createEvent('Event'); + evt.initEvent(name, true, false); + return evt; + }; + } - var maxHeight; - var heightOffset; - var amountOfCR; + function assign(ta) { + var _ref = arguments[1] === undefined ? {} : arguments[1]; + + var _ref$setOverflowX = _ref.setOverflowX; + var setOverflowX = _ref$setOverflowX === undefined ? true : _ref$setOverflowX; + var _ref$setOverflowY = _ref.setOverflowY; + var setOverflowY = _ref$setOverflowY === undefined ? true : _ref$setOverflowY; + + if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return; + + var heightOffset = null; + var overflowY = null; + var clientWidth = ta.clientWidth; function init() { var style = window.getComputedStyle(ta, null); + overflowY = style.overflowY; + if (style.resize === 'vertical') { ta.style.resize = 'none'; } else if (style.resize === 'both') { ta.style.resize = 'horizontal'; } - // horizontal overflow is hidden, so break-word is necessary for handling words longer than the textarea width - ta.style.wordWrap = 'break-word'; - - // Chrome/Safari-specific fix: - // When the textarea y-overflow is hidden, Chrome/Safari doesn't reflow the text to account for the space - // made available by removing the scrollbar. This workaround will cause the text to reflow. - var width = ta.style.width; - ta.style.width = '0px'; - // Force reflow: - /* jshint ignore:start */ - ta.offsetWidth; - /* jshint ignore:end */ - ta.style.width = width; - - maxHeight = style.maxHeight !== 'none' ? parseFloat(style.maxHeight) : false; - if (style.boxSizing === 'content-box') { - heightOffset = -(parseFloat(style.paddingTop)+parseFloat(style.paddingBottom)); + heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); } else { - heightOffset = parseFloat(style.borderTopWidth)+parseFloat(style.borderBottomWidth); + 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; } - amountOfCR = (ta.value.match(/\n/g) || []).length; - adjust(); + update(); } - function adjust() { - var startHeight = ta.style.height; - var htmlTop = document.documentElement.scrollTop; - var bodyTop = document.body.scrollTop; + 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; + } - var newAmountOfCR = (ta.value.match(/\n/g) || []).length; - if (newAmountOfCR === amountOfCR) { - return; + overflowY = value; + + if (setOverflowY) { + ta.style.overflowY = value; } - amountOfCR = newAmountOfCR; - + resize(); + } + + function resize() { + var htmlTop = window.pageYOffset; + var bodyTop = document.body.scrollTop; + var originalHeight = ta.style.height; + ta.style.height = 'auto'; - var endHeight = ta.scrollHeight+heightOffset; + var endHeight = ta.scrollHeight + heightOffset; - if (maxHeight !== false && maxHeight < endHeight) { - endHeight = maxHeight; - if (ta.style.overflowY !== 'scroll') { - ta.style.overflowY = 'scroll'; - } - } else if (ta.style.overflowY !== 'hidden') { - ta.style.overflowY = 'hidden'; + if (ta.scrollHeight === 0) { + // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. + ta.style.height = originalHeight; + return; } - ta.style.height = endHeight+'px'; + ta.style.height = endHeight + 'px'; + + // used to check if an update is actually necessary on window.resize + clientWidth = ta.clientWidth; // prevents scroll-position jumping document.documentElement.scrollTop = htmlTop; document.body.scrollTop = bodyTop; + } + + function update() { + var startHeight = ta.style.height; + + resize(); + + var style = window.getComputedStyle(ta, null); + + if (style.height !== ta.style.height) { + if (overflowY !== 'visible') { + changeOverflow('visible'); + } + } else { + if (overflowY !== 'hidden') { + changeOverflow('hidden'); + } + } if (startHeight !== ta.style.height) { - var evt = document.createEvent('Event'); - evt.initEvent('autosize.resized', true, false); + var evt = createEvent('autosize:resized'); ta.dispatchEvent(evt); } } + var pageResize = function pageResize() { + if (ta.clientWidth !== clientWidth) { + update(); + } + }; + + var 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); + set['delete'](ta); + + Object.keys(style).forEach(function (key) { + ta.style[key] = style[key]; + }); + }).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', adjust); + ta.addEventListener('keyup', update, false); } - window.addEventListener('resize', adjust); - ta.addEventListener('input', adjust); - - ta.addEventListener('autosize.update', adjust); + window.addEventListener('resize', pageResize, false); + ta.addEventListener('input', update, false); + ta.addEventListener('autosize:update', update, false); + set.add(ta); - ta.addEventListener('autosize.destroy', function(style){ - window.removeEventListener('resize', adjust); - ta.removeEventListener('input', adjust); - ta.removeEventListener('keyup', adjust); - ta.removeEventListener('autosize.destroy'); - - Object.keys(style).forEach(function(key){ - ta.style[key] = style[key]; - }); + if (setOverflowX) { + ta.style.overflowX = 'hidden'; + ta.style.wordWrap = 'break-word'; + } - ta.removeAttribute('data-autosize-on'); - }.bind(ta, { - height: ta.style.height, - overflow: ta.style.overflow, - overflowY: ta.style.overflowY, - wordWrap: ta.style.wordWrap, - resize: ta.style.resize - })); + init(); + } - ta.setAttribute('data-autosize-on', true); - ta.style.overflow = 'hidden'; - ta.style.overflowY = 'hidden'; + function destroy(ta) { + if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; + var evt = createEvent('autosize:destroy'); + ta.dispatchEvent(evt); + } - init(); + function update(ta) { + if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; + var evt = createEvent('autosize:update'); + ta.dispatchEvent(evt); } - // Do nothing in IE8 or lower - if (typeof window.getComputedStyle !== 'function') { - return function(elements) { - return elements; + var autosize = null; + + // Do nothing in Node.js environment and IE8 (or lower) + if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { + autosize = function (el) { + return el; + }; + autosize.destroy = function (el) { + return el; + }; + autosize.update = function (el) { + return el; }; } else { - return function(elements) { - if (elements && elements.length) { - Array.prototype.forEach.call(elements, main); - } else if (elements && elements.nodeName) { - main(elements); + autosize = function (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 elements; + return el; + }; + autosize.update = function (el) { + if (el) { + Array.prototype.forEach.call(el.length ? el : [el], update); + } + return el; }; } -})); \ No newline at end of file + + module.exports = autosize; +}); \ No newline at end of file