diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..10728c0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+node_modules/*
+test/*
+publish.js
\ No newline at end of file
diff --git a/bower.json b/bower.json
index e6dfa05..00b4742 100644
--- a/bower.json
+++ b/bower.json
@@ -1,16 +1,12 @@
{
- "name": "jquery-autosize",
- "description": "Automatically adjust textarea height based on user input.",
- "version": "1.18.18",
- "dependencies": {
- "jquery": ">=1.7"
- },
+ "name": "autosize",
+ "description": "Autosize is a small, stand-alone script to automatically adjust textarea height to fit text.",
+ "version": "2.0.0",
+ "dependencies": {},
"keywords": [
- "form",
"textarea",
- "ui",
- "jQuery",
- "jquery-plugin"
+ "form",
+ "ui"
],
"authors": [
{
@@ -19,12 +15,12 @@
"email": "hello@jacklmoore.com"
}
],
- "licenses": [
- {
- "type": "MIT",
- "url": "http://www.opensource.org/licenses/mit-license.php"
- }
- ],
+ "license": "MIT",
"homepage": "http://www.jacklmoore.com/autosize",
- "main": "jquery.autosize.js"
+ "ignore": [],
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/jackmoore/autosize.git"
+ },
+ "main": "dest/autosize.js"
}
\ No newline at end of file
diff --git a/build.js b/build.js
new file mode 100644
index 0000000..1bf40d5
--- /dev/null
+++ b/build.js
@@ -0,0 +1,68 @@
+var pkg = require('./package.json');
+var fs = require('fs');
+var ugly = require("uglify-js");
+var jshint = require("jshint").JSHINT;
+
+function writeBower() {
+ var bower = {
+ name: pkg.config.bower.name,
+ description: pkg.description,
+ version: pkg.version,
+ dependencies: pkg.dependencies,
+ keywords: pkg.keywords,
+ authors: [pkg.author],
+ license: pkg.license,
+ homepage: pkg.homepage,
+ ignore: pkg.config.bower.ignore,
+ repository: pkg.repository,
+ main: pkg.config.bower.main,
+ };
+ fs.writeFile('bower.json', JSON.stringify(bower, null, '\t'));
+ return true;
+}
+
+function build(full) {
+ var mini = ugly.minify(full, {fromString: true}).code;
+ var header = [
+ "/*!",
+ " "+pkg.config.title+" "+pkg.version,
+ " license: MIT",
+ " "+pkg.homepage,
+ "*/",
+ ""
+ ].join("\n");
+
+ fs.writeFile('dest/'+pkg.config.fileName+'.js', header+full);
+ fs.writeFile('dest/'+pkg.config.fileName+'.min.js', header+mini);
+
+ return true;
+}
+
+function lint(full) {
+ jshint(full.toString(), {
+ browser: true,
+ undef: true,
+ unused: true,
+ immed: true,
+ eqeqeq: true,
+ eqnull: true,
+ noarg: true,
+ predef: ['define', 'module']
+ });
+
+ if (jshint.errors.length) {
+ jshint.errors.forEach(function (err) {
+ console.log(err.line+':'+err.character+' '+err.reason);
+ });
+ } else {
+ return true;
+ }
+}
+
+fs.readFile('src/'+pkg.config.fileName+'.js', 'utf8', function (err,data) {
+ if (err) {
+ return console.log(err);
+ } else {
+ lint(data) && build(data) && writeBower();
+ }
+});
\ No newline at end of file
diff --git a/changelog.md b/changelog.md
new file mode 100644
index 0000000..f16c67f
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,13 @@
+## Changelog
+
+##### v.2.0.0 - 2015-02-25
+
+* smaller, simplier code-base
+* new API. Example usage:
+
+ autosize(document.querySelectorAll(textarea));
+
+* dropped jQuery dependency
+* dropped IE7-IE8 support
+* dropped optional parameters
+* closes #98, closes #106, closes #123, fixes #129, fixes #132, fixes #139, closes #140, closes #166, closes #168, closes #192, closes #193, closes #197
\ No newline at end of file
diff --git a/demo.html b/demo.html
deleted file mode 100644
index c2751b6..0000000
--- a/demo.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
- Textarea Autosize Demo
-
-
-
-
-
-
-
-
-
-
-
diff --git a/dest/autosize.js b/dest/autosize.js
new file mode 100644
index 0000000..54fe82b
--- /dev/null
+++ b/dest/autosize.js
@@ -0,0 +1,146 @@
+/*!
+ Autosize 2.0.0
+ license: MIT
+ http://www.jacklmoore.com/autosize
+*/
+(function (root, factory) {
+ 'use strict';
+
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([], 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();
+ } 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 maxHeight;
+ var heightOffset;
+
+ 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';
+ }
+
+ // 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));
+ } else {
+ heightOffset = parseFloat(style.borderTopWidth)+parseFloat(style.borderBottomWidth);
+ }
+
+ adjust();
+ }
+
+ function adjust() {
+ var startHeight = ta.style.height;
+ var htmlTop = document.documentElement.scrollTop;
+ var bodyTop = document.body.scrollTop;
+
+ ta.style.height = 'auto';
+
+ 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';
+ }
+
+ ta.style.height = endHeight+'px';
+
+ // prevents scroll-position jumping
+ document.documentElement.scrollTop = htmlTop;
+ document.body.scrollTop = bodyTop;
+
+ if (startHeight !== ta.style.height) {
+ var evt = document.createEvent('Event');
+ evt.initEvent('autosize.resized', true, false);
+ ta.dispatchEvent(evt);
+ }
+ }
+
+ // 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);
+ }
+
+ window.addEventListener('resize', adjust);
+ ta.addEventListener('input', adjust);
+
+ ta.addEventListener('autosize.update', adjust);
+
+ 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];
+ });
+
+ 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
+ }));
+
+ ta.setAttribute('data-autosize-on', true);
+ ta.style.overflow = 'hidden';
+ ta.style.overflowY = 'hidden';
+
+ init();
+ }
+
+ // Do nothing in IE8 or lower
+ if (typeof window.getComputedStyle !== 'function') {
+ return function(elements) {
+ return elements;
+ };
+ } else {
+ return function(elements) {
+ if (elements && elements.length) {
+ Array.prototype.forEach.call(elements, main);
+ } else if (elements && elements.nodeName) {
+ main(elements);
+ }
+ return elements;
+ };
+ }
+}));
diff --git a/dest/autosize.min.js b/dest/autosize.min.js
new file mode 100644
index 0000000..c289310
--- /dev/null
+++ b/dest/autosize.min.js
@@ -0,0 +1,6 @@
+/*!
+ Autosize 2.0.0
+ license: MIT
+ http://www.jacklmoore.com/autosize
+*/
+!function(e,t){"use strict";"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?module.exports=t():e.autosize=t()}(this,function(){function e(e){function t(){var t=window.getComputedStyle(e,null);"vertical"===t.resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),e.style.wordWrap="break-word";var i=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=i,n="none"!==t.maxHeight?parseFloat(t.maxHeight):!1,r="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),o()}function o(){var t=e.style.height,o=document.documentElement.scrollTop,i=document.body.scrollTop;e.style.height="auto";var s=e.scrollHeight+r;if(n!==!1&&s>n?(s=n,"scroll"!==e.style.overflowY&&(e.style.overflowY="scroll")):"hidden"!==e.style.overflowY&&(e.style.overflowY="hidden"),e.style.height=s+"px",document.documentElement.scrollTop=o,document.body.scrollTop=i,t!==e.style.height){var d=document.createEvent("Event");d.initEvent("autosize.resized",!0,!1),e.dispatchEvent(d)}}if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!e.hasAttribute("data-autosize-on")){var n,r;"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",o),window.addEventListener("resize",o),e.addEventListener("input",o),e.addEventListener("autosize.update",o),e.addEventListener("autosize.destroy",function(t){window.removeEventListener("resize",o),e.removeEventListener("input",o),e.removeEventListener("keyup",o),e.removeEventListener("autosize.destroy"),Object.keys(t).forEach(function(o){e.style[o]=t[o]}),e.removeAttribute("data-autosize-on")}.bind(e,{height:e.style.height,overflow:e.style.overflow,overflowY:e.style.overflowY,wordWrap:e.style.wordWrap,resize:e.style.resize})),e.setAttribute("data-autosize-on",!0),e.style.overflow="hidden",e.style.overflowY="hidden",t()}}return"function"!=typeof window.getComputedStyle?function(e){return e}:function(t){return t&&t.length?Array.prototype.forEach.call(t,e):t&&t.nodeName&&e(t),t}});
\ No newline at end of file
diff --git a/example/index.html b/example/index.html
new file mode 100644
index 0000000..5f5e199
--- /dev/null
+++ b/example/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+ Simple Autosize for textareas
+
+
+
+ max-height 300px
+
+
+ no max-height
+
+
+
+
+
diff --git a/jquery.autosize.js b/jquery.autosize.js
deleted file mode 100644
index 4e96699..0000000
--- a/jquery.autosize.js
+++ /dev/null
@@ -1,273 +0,0 @@
-/*!
- Autosize 1.18.18
- license: MIT
- http://www.jacklmoore.com/autosize
-*/
-(function ($) {
- var
- defaults = {
- className: 'autosizejs',
- id: 'autosizejs',
- append: '\n',
- callback: false,
- resizeDelay: 10,
- placeholder: true
- },
-
- // line-height is conditionally included because IE7/IE8/old Opera do not return the correct value.
- typographyStyles = [
- 'fontFamily',
- 'fontSize',
- 'fontWeight',
- 'fontStyle',
- 'letterSpacing',
- 'textTransform',
- 'wordSpacing',
- 'textIndent',
- 'whiteSpace'
- ],
-
- // to keep track which textarea is being mirrored when adjust() is called.
- mirrored,
-
- // the mirror element, which is used to calculate what size the mirrored element should be.
- mirror = $('').data('autosize', true)[0];
-
- // border:0 is unnecessary, but avoids a bug in Firefox on OSX
- mirror.style.cssText = "position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;";
-
- // test that line-height can be accurately copied.
- mirror.style.lineHeight = '99px';
- if ($(mirror).css('lineHeight') === '99px') {
- typographyStyles.push('lineHeight');
- }
- mirror.style.lineHeight = '';
-
- $.fn.autosize = function (options) {
- if (!this.length) {
- return this;
- }
-
- options = $.extend({}, defaults, options || {});
-
- if (mirror.parentNode !== document.body) {
- $(document.body).append(mirror);
- }
-
- return this.each(function () {
- var
- ta = this,
- $ta = $(ta),
- maxHeight,
- minHeight,
- boxOffset = 0,
- callback = $.isFunction(options.callback),
- originalStyles = {
- height: ta.style.height,
- overflow: ta.style.overflow,
- overflowY: ta.style.overflowY,
- wordWrap: ta.style.wordWrap,
- resize: ta.style.resize
- },
- timeout,
- width = $ta.width(),
- taResize = $ta.css('resize');
-
- if ($ta.data('autosize')) {
- // exit if autosize has already been applied, or if the textarea is the mirror element.
- return;
- }
- $ta.data('autosize', true);
-
- if ($ta.css('box-sizing') === 'border-box' || $ta.css('-moz-box-sizing') === 'border-box' || $ta.css('-webkit-box-sizing') === 'border-box'){
- boxOffset = $ta.outerHeight() - $ta.height();
- }
-
- // IE8 and lower return 'auto', which parses to NaN, if no min-height is set.
- minHeight = Math.max(parseFloat($ta.css('minHeight')) - boxOffset || 0, $ta.height());
-
- $ta.css({
- overflow: 'hidden',
- overflowY: 'hidden',
- wordWrap: 'break-word' // horizontal overflow is hidden, so break-word is necessary for handling words longer than the textarea width
- });
-
- if (taResize === 'vertical') {
- $ta.css('resize','none');
- } else if (taResize === 'both') {
- $ta.css('resize', 'horizontal');
- }
-
- // getComputedStyle is preferred here because it preserves sub-pixel values, while jQuery's .width() rounds to an integer.
- function setWidth() {
- var width;
- var style = window.getComputedStyle ? window.getComputedStyle(ta, null) : null;
-
- if (style) {
- width = parseFloat(style.width);
- if (style.boxSizing === 'border-box' || style.webkitBoxSizing === 'border-box' || style.mozBoxSizing === 'border-box') {
- $.each(['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'], function(i,val){
- width -= parseFloat(style[val]);
- });
- }
- } else {
- width = $ta.width();
- }
-
- mirror.style.width = Math.max(width,0) + 'px';
- }
-
- function initMirror() {
- var styles = {};
-
- mirrored = ta;
- mirror.className = options.className;
- mirror.id = options.id;
- maxHeight = parseFloat($ta.css('maxHeight'));
-
- // mirror is a duplicate textarea located off-screen that
- // is automatically updated to contain the same text as the
- // original textarea. mirror always has a height of 0.
- // This gives a cross-browser supported way getting the actual
- // height of the text, through the scrollTop property.
- $.each(typographyStyles, function(i,val){
- styles[val] = $ta.css(val);
- });
-
- $(mirror).css(styles).attr('wrap', $ta.attr('wrap'));
-
- setWidth();
-
- // Chrome-specific fix:
- // When the textarea y-overflow is hidden, Chrome doesn't reflow the text to account for the space
- // made available by removing the scrollbar. This workaround triggers the reflow for Chrome.
- if (window.chrome) {
- var width = ta.style.width;
- ta.style.width = '0px';
- var ignore = ta.offsetWidth;
- ta.style.width = width;
- }
- }
-
- // Using mainly bare JS in this function because it is going
- // to fire very often while typing, and needs to very efficient.
- function adjust() {
- var height, originalHeight;
-
- if (mirrored !== ta) {
- initMirror();
- } else {
- setWidth();
- }
-
- if (!ta.value && options.placeholder) {
- // If the textarea is empty, copy the placeholder text into
- // the mirror control and use that for sizing so that we
- // don't end up with placeholder getting trimmed.
- mirror.value = ($ta.attr("placeholder") || '');
- } else {
- mirror.value = ta.value;
- }
-
- mirror.value += options.append || '';
- mirror.style.overflowY = ta.style.overflowY;
- originalHeight = parseFloat(ta.style.height) || 0;
-
- // Setting scrollTop to zero is needed in IE8 and lower for the next step to be accurately applied
- mirror.scrollTop = 0;
-
- mirror.scrollTop = 9e4;
-
- // Using scrollTop rather than scrollHeight because scrollHeight is non-standard and includes padding.
- height = mirror.scrollTop;
-
- if (maxHeight && height > maxHeight) {
- ta.style.overflowY = 'scroll';
- height = maxHeight;
- } else {
- ta.style.overflowY = 'hidden';
- if (height < minHeight) {
- height = minHeight;
- }
- }
-
- height += boxOffset;
-
- if (Math.abs(originalHeight - height) > 1/100) {
- ta.style.height = height + 'px';
-
- // Trigger a repaint for IE8 for when ta is nested 2 or more levels inside an inline-block
- mirror.className = mirror.className;
-
- if (callback) {
- options.callback.call(ta,ta);
- }
- $ta.trigger('autosize.resized');
- }
- }
-
- function resize () {
- clearTimeout(timeout);
- timeout = setTimeout(function(){
- var newWidth = $ta.width();
-
- if (newWidth !== width) {
- width = newWidth;
- adjust();
- }
- }, parseInt(options.resizeDelay,10));
- }
-
- if ('onpropertychange' in ta) {
- if ('oninput' in ta) {
- // Detects IE9. IE9 does not fire onpropertychange or oninput for deletions,
- // so binding to onkeyup to catch most of those occasions. There is no way that I
- // know of to detect something like 'cut' in IE9.
- $ta.on('input.autosize keyup.autosize', adjust);
- } else {
- // IE7 / IE8
- $ta.on('propertychange.autosize', function(){
- if(event.propertyName === 'value'){
- adjust();
- }
- });
- }
- } else {
- // Modern Browsers
- $ta.on('input.autosize', adjust);
- }
-
- // Set options.resizeDelay to false if using fixed-width textarea elements.
- // Uses a timeout and width check to reduce the amount of times adjust needs to be called after window resize.
-
- if (options.resizeDelay !== false) {
- $(window).on('resize.autosize', resize);
- }
-
- // Event for manual triggering if needed.
- // Should only be needed when the value of the textarea is changed through JavaScript rather than user input.
- $ta.on('autosize.resize', adjust);
-
- // Event for manual triggering that also forces the styles to update as well.
- // Should only be needed if one of typography styles of the textarea change, and the textarea is already the target of the adjust method.
- $ta.on('autosize.resizeIncludeStyle', function() {
- mirrored = null;
- adjust();
- });
-
- $ta.on('autosize.destroy', function(){
- mirrored = null;
- clearTimeout(timeout);
- $(window).off('resize', resize);
- $ta
- .off('autosize')
- .off('.autosize')
- .css(originalStyles)
- .removeData('autosize');
- });
-
- // Call adjust in case the textarea already contains text.
- adjust();
- });
- };
-}(jQuery || $)); // jQuery or jQuery-like library, such as Zepto
diff --git a/jquery.autosize.min.js b/jquery.autosize.min.js
deleted file mode 100644
index aa7781a..0000000
--- a/jquery.autosize.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
- Autosize 1.18.18
- license: MIT
- http://www.jacklmoore.com/autosize
-*/
-!function(e){var t,o={className:"autosizejs",id:"autosizejs",append:"\n",callback:!1,resizeDelay:10,placeholder:!0},i=["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent","whiteSpace"],a=e('').data("autosize",!0)[0];a.style.cssText="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;",a.style.lineHeight="99px","99px"===e(a).css("lineHeight")&&i.push("lineHeight"),a.style.lineHeight="",e.fn.autosize=function(n){return this.length?(n=e.extend({},o,n||{}),a.parentNode!==document.body&&e(document.body).append(a),this.each(function(){function o(){var t,o=window.getComputedStyle?window.getComputedStyle(u,null):null;o?(t=parseFloat(o.width),("border-box"===o.boxSizing||"border-box"===o.webkitBoxSizing||"border-box"===o.mozBoxSizing)&&e.each(["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"],function(e,i){t-=parseFloat(o[i])})):t=p.width(),a.style.width=Math.max(t,0)+"px"}function s(){var s={};if(t=u,a.className=n.className,a.id=n.id,d=parseFloat(p.css("maxHeight")),e.each(i,function(e,t){s[t]=p.css(t)}),e(a).css(s).attr("wrap",p.attr("wrap")),o(),window.chrome){var r=u.style.width;u.style.width="0px";{u.offsetWidth}u.style.width=r}}function r(){var e,i;t!==u?s():o(),a.value=!u.value&&n.placeholder?p.attr("placeholder")||"":u.value,a.value+=n.append||"",a.style.overflowY=u.style.overflowY,i=parseFloat(u.style.height)||0,a.scrollTop=0,a.scrollTop=9e4,e=a.scrollTop,d&&e>d?(u.style.overflowY="scroll",e=d):(u.style.overflowY="hidden",c>e&&(e=c)),e+=z,Math.abs(i-e)>.01&&(u.style.height=e+"px",a.className=a.className,w&&n.callback.call(u,u),p.trigger("autosize.resized"))}function l(){clearTimeout(h),h=setTimeout(function(){var e=p.width();e!==b&&(b=e,r())},parseInt(n.resizeDelay,10))}var d,c,h,u=this,p=e(u),z=0,w=e.isFunction(n.callback),f={height:u.style.height,overflow:u.style.overflow,overflowY:u.style.overflowY,wordWrap:u.style.wordWrap,resize:u.style.resize},b=p.width(),g=p.css("resize");p.data("autosize")||(p.data("autosize",!0),("border-box"===p.css("box-sizing")||"border-box"===p.css("-moz-box-sizing")||"border-box"===p.css("-webkit-box-sizing"))&&(z=p.outerHeight()-p.height()),c=Math.max(parseFloat(p.css("minHeight"))-z||0,p.height()),p.css({overflow:"hidden",overflowY:"hidden",wordWrap:"break-word"}),"vertical"===g?p.css("resize","none"):"both"===g&&p.css("resize","horizontal"),"onpropertychange"in u?"oninput"in u?p.on("input.autosize keyup.autosize",r):p.on("propertychange.autosize",function(){"value"===event.propertyName&&r()}):p.on("input.autosize",r),n.resizeDelay!==!1&&e(window).on("resize.autosize",l),p.on("autosize.resize",r),p.on("autosize.resizeIncludeStyle",function(){t=null,r()}),p.on("autosize.destroy",function(){t=null,clearTimeout(h),e(window).off("resize",l),p.off("autosize").off(".autosize").css(f).removeData("autosize")}),r())})):this}}(jQuery||$);
\ No newline at end of file
diff --git a/package.json b/package.json
index 3c2813e..c78fbae 100644
--- a/package.json
+++ b/package.json
@@ -1,32 +1,37 @@
{
- "name": "jquery-autosize",
- "description": "Automatically adjust textarea height based on user input.",
- "version": "1.18.18",
- "dependencies": {},
- "repository": {
- "type": "git",
- "url": "git://github.com/jackmoore/autosize.git"
- },
- "keywords": [
- "form",
- "textarea",
- "ui",
- "jQuery",
- "jquery-plugin"
- ],
- "authors": [
- {
- "name": "Jack Moore",
- "url": "http://www.jacklmoore.com",
- "email": "hello@jacklmoore.com"
- }
- ],
- "licenses": [
- {
- "type": "MIT",
- "url": "http://www.opensource.org/licenses/mit-license.php"
- }
- ],
- "homepage": "http://www.jacklmoore.com/autosize",
- "main": "jquery.autosize.js"
-}
\ No newline at end of file
+ "name": "autosize",
+ "description": "Autosize is a small, stand-alone script to automatically adjust textarea height to fit text.",
+ "version": "2.0.0",
+ "keywords": [
+ "textarea",
+ "form",
+ "ui"
+ ],
+ "author": {
+ "name": "Jack Moore",
+ "url": "http://www.jacklmoore.com",
+ "email": "hello@jacklmoore.com"
+ },
+ "license": "MIT",
+ "homepage": "http://www.jacklmoore.com/autosize",
+ "demo": "http://www.jacklmoore.com/autosize",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/jackmoore/autosize.git"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "jshint": "^2.5.6",
+ "uglify-js": "^2.4.15",
+ "watch": "^0.14.0"
+ },
+ "config": {
+ "bower": {
+ "name": "autosize",
+ "ignore": [],
+ "main": "dest/autosize.js"
+ },
+ "title": "Autosize",
+ "fileName": "autosize"
+ }
+}
diff --git a/readme.md b/readme.md
index cbf4572..e6552d0 100644
--- a/readme.md
+++ b/readme.md
@@ -1,216 +1,145 @@
-## Autosize
+## Summary
-Small jQuery plugin to allow dynamic resizing of textarea height, so that it grows as based on visitor input. To use, just call the `.autosize()` method on any textarea element. Example `$('textarea').autosize();`. See the [project page](http://jacklmoore.com/autosize/) for documentation, caveats, and a demonstration. Released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).
+Autosize is a small, stand-alone script to automatically adjust textarea height to fit text.
-## Changelog
+## Install
-##### v.1.18.18 - 2015/02/24
-* Fix Content Security Policy (CSP) warnings about unsafe-inline styles. Fixes #199.
+[Download zip](https://github.com/jackmoore/autosize/archive/master.zip)
-##### v.1.18.17 - 2014/12/10
-* Fixed potential issue when using transforms to scale a textarea. Fixes #190.
+##### Install via NPM
+```bash
+npm install autosize
+```
+##### Install via Bower
+```bash
+bower install autosize
+```
-##### v1.18.16 - 2014/12/9
-* Treat height differences smaller than 1/100px as equal. Merges #189.
+#### Browser compatibility
-##### v1.18.15 - 2014/11/11
-* Replaced parseInt with parseFloat to support sub-pixel values. Merges #185.
+Chrome | Firefox | IE | Safari | iOS Safari | Android | Opera Mini
+------ | --------|----|--------|------------|---------|------------
+yes | yes | 9 | yes | yes | 4 | ?
-##### v1.18.14 - 2014/10/3
-* Fixed potential IE8 issue. Merged #181.
+### Usage
-##### v1.18.13 - 2014/10/3
-* Allow setting the append property to falsey values. Fixes #177, Ref #168, Ref #166.
+The autosize function accepts a single textarea element, or an array or array-like object (such as a NodeList or jQuery collection) of textarea elements.
-##### v1.18.12 - 2014/9/9
-* Replace window.jQuery with jQuery. Fixes #176.
+```javascript
+// from a NodeList
+autosize(document.querySelectorAll('textarea'));
-##### v1.18.11 - 2014/9/9
-* Merged request for autosize.resized event. Fixes #149.
+// from a single Node
+autosize(document.querySelector('textarea'));
-##### v1.18.10 - 2014/9/9
-* Added white-space to the list of monitored textarea properties.
+// from a jQuery collection
+autosize($('textarea'));
+```
-##### v1.18.9 - 2014/5/27
-* Minor change to fix potential IE8 negative width bug. Fixes #157 Fixes #158
+### Lifecycle Events
-##### v1.18.8 - 2014/5/20
-* Minor change to logic for applying the CSS resize property. Fixes #156
+##### autosize.update (triggerable)
-##### v1.18.7 - 2014/4/13
-* Very minor change to better represent condition for taking the element width from the style object. Fixes #147
-* Added a newline character by default to the textarea element for smoother behavior in IE. Reference #148
+Once you've assigned autosize to an element, you can manually trigger the resize event by using the 'autosize.update' event. Autosize has no way of knowing when a script has changed the value of a textarea element, or when the textarea element styles have changed, so this event would be used instruct autosize to resize the textarea.
-##### v1.18.6 - 2014/3/13
-* Fixed incorrect size when setting the HTML5 textarea wrap attribute to 'hard'.
-##### v1.18.5 - 2014/3/10
-* Added 'id' property for setting the id of the mirrored textarea element
+```javascript
+var ta = document.querySelector('textarea');
-##### v1.18.4 - 2014/1/11
-* If textarea displays placeholder text, use placeholder text for sizing. Ref #130, Ref #84.
+autosize(ta);
-##### v1.18.3 - 2014/1/10
-* Allow correct width calculation of hidden textarea elements, when they have a specified width. Fixes #134
+// Change the value of the textarea
+ta.value = "Something really long";
+ta.style.fontSize = '20px';
-##### v1.18.2 - 2014/1/6
-* Checked getComputedStyle return value to avoid potential error exception. Fixes #133
+// Dispatch a 'autosize.update' event to trigger a resize:
+var evt = document.createEvent('Event');
+evt.initEvent('autosize.update', true, false);
+ta.dispatchEvent(evt);
+```
-##### v1.18.1 - 2013/11/5
-* Removed AMD support. Fixes #109 Ref #56.
+##### autosize.destroy (triggerable)
-##### v1.18.0 - 2013/10/20
-* Fixed error that was being thrown in Firefox 3.x. Fixes #112
+```javascript
+var ta = document.querySelector('textarea');
-##### v1.17.8 - 2013/9/7
-* Minor change to not append the mirror element when the plugin is applied to an empty jQuery collection
+// assign autosize to ta
+autosize(ta);
-##### v1.17.7 - 2013/9/3
-* Reverted to an earlier fix for a Chrome issue. Too many issues with using setSelectionRange.
+// remove autosize from ta
+var evt = document.createEvent('Event');
+evt.initEvent('autosize.destroy', true, false);
+ta.dispatchEvent(evt);
+```
-##### v1.17.6 - 2013/8/24
-* Fixed a potential issue introduced in 1.17.4 that causes an 'NS_ERROR_FAILURE' error in Firefox.
+##### autosize.resized (observable)
-##### v1.17.5 - 2013/8/23
-* Fixed oversight in 1.17.4 that caused Firefox fix not to be applied.
+This event is fired every time autosize adjusts the textarea height.
-##### v1.17.4 - 2013/8/22
-* Improved speed of editing large blocks of text in Firefox.
+```javascript
+var ta = document.querySelector('textarea');
-##### v1.17.3 - 2013/8/2013
-* Resolved an issue that was causing slowing down initialization for large blocks of text in Chrome.
-* Renamed minified file from jquery.autosize-min.js to jquery.autosize.min.js
+ta.addEventListener('autosize.resized', function(){
+ console.log('textarea height updated');
+});
-##### v1.17.2 - 2013/7/28
-* Added support for loading as an AMD module.
-* Added package.json for installing through NPM.
+### Differences between v2 and v1
-##### v1.17.1 - 2013/6/22
-* Fixed potential memory leak when using autosize.destroy.
+If you need the v1 version for whatever reason, you can find it in the v1 branch on Github:
+[https://github.com/jackmoore/autosize/tree/v1](https://github.com/jackmoore/autosize/tree/v1)
-##### v1.17.0 - 2013/6/19
-* Renamed 'autosize' event to 'autosize.resize'
-* Renamed 'autosize.includeStyle' event to 'autosize.resizeIncludeStyle'
-* Fixes problem introduced in 1.16.18 with manually triggering the 'autosize' event:
+Autosize v2 is a smaller, simplier script than v1. It is now a stand-alone script instead of a jQuery plugin, and support for IE8 and lower has been dropped (legacy IE users will be presented with an unmodified textarea element). Additionally, Autosize v2 does not take in any optional parameters at this time.
-##### v1.16.20 - 2013/6/18
-* Minor improvement to the destroy event.
+Autosize v2 does not create a mirror textarea element in order to calculate the correct height, which was responsible for much of the original script's complexity. This should be more efficient and reliable, but the new method prevents using a CSS transition to animate the height change.
-##### v1.16.19 - 2013/6/18
-* Added event for removing autosize from a textarea element:
- $('textarea.example').trigger('autosize.destroy');
-##### v1.16.18 - 2013/6/18
-* Added event for manually triggering resize that also accounts for typographic styles that have changed on the textarea element. Example:
- $('textarea.example').css('text-indent', 25);
- $('textarea.example').trigger('autosize.includeStyle');
-* Minor optimization
+### Converting to a jQuery plugin
-##### v1.16.17 - 2013/6/12
-* Fixed a compatibility issue with jQuery versions before 1.9 introduced in the previous update.
+Autosize does not depend on jQuery, but it can easily be turned into a jQuery plugin if desired.
-##### v1.16.16 - 2013/6/11
-* Fixed an issue where the calculated height might be slightly off in modern browsers when the width of the textarea has a sub-pixel value.
+```javascript
+// Create the plugin:
+window.jQuery.fn.autosize = function() {
+ return autosize(this);
+};
-##### v1.16.15 - 2013/6/7
-* Reduced how frequently autosize is triggered when resizing the window. Added resizeDelay property so that the frequency can be adjusted or disabled.
+// Use the plugin:
+jQuery(function($){
+ $('textarea').autosize();
+});
+```
-##### v1.16.14 - 2013/6/6
-* Fixed an issue with autosize working poorly if the mirror element has a transition applied to it's width.
+### Known Issues & Solutions
-##### v1.16.13 - 2013/6/4
-* Fixed a Chrome cursor position issue introduced with the reflow workaround added in 1.16.10.
+#### Incorrect size with hidden textarea elements
-##### v1.16.12 - 2013/5/31
-* Much better efficiency and smoothness for IE8 and lower.
+Autosize needs to be able to calculate the width of the textarea element when it is assigned. JavaScript cannot accurately calculate the width of an element that has been removed from the document flow. If you want to assign Autosize to a hidden textarea element, be sure to either specify the pixel width of the element in your CSS, or trigger the `autosize.update` event after you reveal the textarea element.
-##### v1.16.11 - 2013/5/31
-* Fixed a default height issue in IE8 and lower.
+**Possible ways to resolve:**
-##### v1.16.10 - 2013/5/30
-* Dropped scrollHeight for scrollTop. This fixed a height problem relating to padding. (Fixes #70)
-* Re-added workaround to get Chrome to reflow text after hiding overflow.
+* Specify an exact width for the textarea element in your stylesheet.
+* Wait until after the textarea element has been revealed before assigning Autosize.
+* Trigger the `autosize.update` event after the element has been revealed.
-##### v1.16.9 - 2013/5/20
-* Reverted change from 1.16.8 as it caused an issue in IE8. (Fixes #69)
+```javascript
+var ta = document.querySelector('textarea');
+ta.style.display = 'none';
+autosize(ta);
+ta.style.display = '';
-##### v1.16.8 - 2013/5/7
-* Fixed issue where autosize was creating a horizontal scrollbar for a user
+// Trigger the autosize.update event to recalculate the size:
+var evt = document.createEvent('Event');
+evt.initEvent('autosize.update', true, false);
+ta.dispatchEvent(evt);
+```
-##### v1.16.7 - 2013/3/20
-* Added workaround for a very edge-case iOS bug (Fixes #58).
+* Wait until the textarea has been focused by the user before assigning Autosize.
-##### v1.16.6 - 2013/3/12
-* Replaced jQuery shorthand methods with on() in anticipation of jQuery 2.0 conditional builds
+```javascript
+var ta = document.querySelector('textarea');
+ta.addEventListener('focus', function(){
+ autosize(ta);
+});
+```
-##### v1.16.5 - 2013/3/12
-* Fixed a bug where triggering the autosize event immediately after assigning autosize had no effect.
-
-##### v1.16.4 - 2013/1/29
-* Fixed a conflict with direction:ltr pages.
-
-##### v1.16.3 - 2013/1/23
-* Added minified file back to repository
-
-##### v1.16.2 - 2013/1/20
-* Minor box-sizing issue dealing with min-heights.
-
-##### v1.16.1 - 2013/1/20
-* Added to plugins.jquery.com
-
-##### v1.15 - 2012/11/16
-* Reworked to only create a single mirror element, instead of one for each textarea.
-* Dropped feature detection for FF3 and Safari 4.
-
-##### v1.14 - 2012/10/6
-* Added 'append' option for appending whitespace to the end of the height calculation (an extra newline improves the apperance when animating).
-* Added a demonstration of animating the height change using a CSS transition.
-
-##### v1.13 - 2012/9/21
-* Added optional callback that fires after resize.
-
-##### v1.12 - 2012/9/3
-* Fixed a bug I introduced in the last update.
-
-##### v1.11 - 2012/8/8
-* Added workaround to get Chrome to reflow default text better.
-
-##### v1.10 - 2012/4/30
-* Added 'lineHeight' to the list of styles considered for size detection.
-
-##### v1.9 - 2012/6/19
-* Added 'textIndent' to the list of styles considered for size detection.
-* Added vender prefixes to box-sizing detection
-
-##### v1.8 - 2012/6/7
-* Added conditional so that autosize cannot be applied twice to the same element
-* When autosize is applied to an element, it will have a data property that links it to the mirrored textarea element. This will make it easier to keep track of and remove unneeded mirror elements. Example:
-
- $('textarea.example').data('mirror').remove(); // delete the mirror
-
- $('textarea.example').remove(); // delete the original
-
-##### v1.7 - 2012/5/3
-* Now supports box-sizing:border-box
-
-##### v1.6 - 2012/2/11
-* added binding to allow autosize to be triggered manually. Example:
- $('#myTextArea').trigger('autosize');
-
-##### v1.5 - 2011/12/7
-* fixed a regression in detecting Firefox support
-
-##### v1.4 - 2011/11/22
-* added branching to exclude old browsers (FF3- & Safari4-)
-
-##### v1.3 - 2011/11/13
-* fixed a regression in 1.1 relating to Opera.
-
-##### v1.2 - 2011/11/10
-* fixed a regression in 1.1 that broke autosize for IE9.
-
-##### v1.1 - 2011/11/10
-* autosize now follows the max-height of textareas. OverflowY will be set to scroll once the content height exceeds max-height.
-
-##### v1.0 - 2011/11/7
-* first release
+Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php)
diff --git a/src/autosize.js b/src/autosize.js
new file mode 100644
index 0000000..f776beb
--- /dev/null
+++ b/src/autosize.js
@@ -0,0 +1,141 @@
+(function (root, factory) {
+ 'use strict';
+
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([], 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();
+ } 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 maxHeight;
+ var heightOffset;
+
+ 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';
+ }
+
+ // 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));
+ } else {
+ heightOffset = parseFloat(style.borderTopWidth)+parseFloat(style.borderBottomWidth);
+ }
+
+ adjust();
+ }
+
+ function adjust() {
+ var startHeight = ta.style.height;
+ var htmlTop = document.documentElement.scrollTop;
+ var bodyTop = document.body.scrollTop;
+
+ ta.style.height = 'auto';
+
+ 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';
+ }
+
+ ta.style.height = endHeight+'px';
+
+ // prevents scroll-position jumping
+ document.documentElement.scrollTop = htmlTop;
+ document.body.scrollTop = bodyTop;
+
+ if (startHeight !== ta.style.height) {
+ var evt = document.createEvent('Event');
+ evt.initEvent('autosize.resized', true, false);
+ ta.dispatchEvent(evt);
+ }
+ }
+
+ // 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);
+ }
+
+ window.addEventListener('resize', adjust);
+ ta.addEventListener('input', adjust);
+
+ ta.addEventListener('autosize.update', adjust);
+
+ 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];
+ });
+
+ 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
+ }));
+
+ ta.setAttribute('data-autosize-on', true);
+ ta.style.overflow = 'hidden';
+ ta.style.overflowY = 'hidden';
+
+ init();
+ }
+
+ // Do nothing in IE8 or lower
+ if (typeof window.getComputedStyle !== 'function') {
+ return function(elements) {
+ return elements;
+ };
+ } else {
+ return function(elements) {
+ if (elements && elements.length) {
+ Array.prototype.forEach.call(elements, main);
+ } else if (elements && elements.nodeName) {
+ main(elements);
+ }
+ return elements;
+ };
+ }
+}));