[Pkg-javascript-commits] [autosize.js] 01/04: New upstream version 3.0.21~dfsg1

Alexandre Viau aviau at moszumanska.debian.org
Tue Jul 4 19:09:20 UTC 2017


This is an automated email from the git hooks/post-receive script.

aviau pushed a commit to branch master
in repository autosize.js.

commit 407681a90d718a5edae11c57b2a02f535c136628
Author: aviau <aviau at debian.org>
Date:   Tue Jul 4 15:05:57 2017 -0400

    New upstream version 3.0.21~dfsg1
---
 build.js         |   2 +-
 changelog.md     |  19 ++++++++
 dist/autosize.js | 138 +++++++++++++++++++++++++++++++++++--------------------
 package.json     |   8 ++--
 src/autosize.js  | 125 ++++++++++++++++++++++++++++++++-----------------
 5 files changed, 196 insertions(+), 96 deletions(-)

diff --git a/build.js b/build.js
index bab0cd6..83246e9 100644
--- a/build.js
+++ b/build.js
@@ -32,7 +32,7 @@ function lint(full) {
 		eqeqeq: true,
 		eqnull: true,
 		noarg: true,
-		predef: ['define', 'module', 'exports', 'Set']
+		predef: ['define', 'module', 'exports', 'Map']
 	});
 
 	if (jshint.errors.length) {
diff --git a/changelog.md b/changelog.md
index 52604a3..9f0487e 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,24 @@
 ## Changelog
 
+##### v.3.0.21 - 2016-05-19
+* Fixed bug with overflow detection which degraded performance of textareas that exceed their max-width. Fixes #333.
+
+##### v.3.0.20 - 2016-12-04
+* Fixed minor bug where the `resized` event would not fire under specific conditions when changing the overflow.
+
+##### v.3.0.19 - 2016-11-23
+* Bubble dispatched events. Merged #319.
+
+##### v.3.0.18 - 2016-10-26
+* Fixed Firefox issue where calling dispatchEvent on a detached element throws an error.  Fixes #317.
+
+##### v.3.0.17 - 2016-7-25
+* Fixed Chromium issue where getComputedStyle pixel value did not exactly match the style pixel value.  Fixes #306.
+* Removed undocumented argument, minor refactoring, more comments.
+
+##### v.3.0.16 - 2016-7-13
+* Fixed issue with overflowing parent elements. Fixes #298.
+
 ##### v.3.0.15 - 2016-1-26
 * Used newer Event constructor, when available. Fixes #280.
 
diff --git a/dist/autosize.js b/dist/autosize.js
index c807509..f844dfb 100644
--- a/dist/autosize.js
+++ b/dist/autosize.js
@@ -1,5 +1,5 @@
 /*!
-	Autosize 3.0.15
+	Autosize 3.0.21
 	license: MIT
 	http://www.jacklmoore.com/autosize
 */
@@ -18,23 +18,35 @@
 })(this, function (exports, module) {
 	'use strict';
 
-	var set = typeof Set === 'function' ? new Set() : (function () {
-		var list = [];
+	var map = typeof Map === "function" ? new Map() : (function () {
+		var keys = [];
+		var values = [];
 
 		return {
 			has: function has(key) {
-				return Boolean(list.indexOf(key) > -1);
+				return keys.indexOf(key) > -1;
 			},
-			add: function add(key) {
-				list.push(key);
+			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) {
-				list.splice(list.indexOf(key), 1);
-			} };
+				var index = keys.indexOf(key);
+				if (index > -1) {
+					keys.splice(index, 1);
+					values.splice(index, 1);
+				}
+			}
+		};
 	})();
 
 	var createEvent = function createEvent(name) {
-		return new Event(name);
+		return new Event(name, { bubbles: true });
 	};
 	try {
 		new Event('test');
@@ -48,24 +60,15 @@
 	}
 
 	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;
+		if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return;
 
 		var heightOffset = null;
-		var overflowY = null;
 		var clientWidth = ta.clientWidth;
+		var cachedHeight = null;
 
 		function init() {
 			var style = window.getComputedStyle(ta, null);
 
-			overflowY = style.overflowY;
-
 			if (style.resize === 'vertical') {
 				ta.style.resize = 'none';
 			} else if (style.resize === 'both') {
@@ -99,19 +102,29 @@
 				ta.style.width = width;
 			}
 
-			overflowY = value;
+			ta.style.overflowY = value;
+		}
+
+		function getParentOverflows(el) {
+			var arr = [];
 
-			if (setOverflowY) {
-				ta.style.overflowY = value;
+			while (el && el.parentNode && el.parentNode instanceof Element) {
+				if (el.parentNode.scrollTop) {
+					arr.push({
+						node: el.parentNode,
+						scrollTop: el.parentNode.scrollTop
+					});
+				}
+				el = el.parentNode;
 			}
 
-			resize();
+			return arr;
 		}
 
 		function resize() {
-			var htmlTop = window.pageYOffset;
-			var bodyTop = document.body.scrollTop;
 			var originalHeight = ta.style.height;
+			var overflows = getParentOverflows(ta);
+			var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240)
 
 			ta.style.height = 'auto';
 
@@ -129,30 +142,50 @@
 			clientWidth = ta.clientWidth;
 
 			// prevents scroll-position jumping
-			document.documentElement.scrollTop = htmlTop;
-			document.body.scrollTop = bodyTop;
+			overflows.forEach(function (el) {
+				el.node.scrollTop = el.scrollTop;
+			});
+
+			if (docTop) {
+				document.documentElement.scrollTop = docTop;
+			}
 		}
 
 		function update() {
-			var startHeight = ta.style.height;
-
 			resize();
 
-			var style = window.getComputedStyle(ta, null);
+			var styleHeight = Math.round(parseFloat(ta.style.height));
+			var computed = window.getComputedStyle(ta, null);
+
+			// Using offsetHeight as a replacement for computed.height in IE, because IE does not account use of border-box
+			var actualHeight = computed.boxSizing === 'content-box' ? Math.round(parseFloat(computed.height)) : ta.offsetHeight;
 
-			if (style.height !== ta.style.height) {
-				if (overflowY !== 'visible') {
-					changeOverflow('visible');
+			// 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 {
-				if (overflowY !== 'hidden') {
+				// 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 (startHeight !== ta.style.height) {
+			if (cachedHeight !== actualHeight) {
+				cachedHeight = actualHeight;
 				var evt = createEvent('autosize:resized');
-				ta.dispatchEvent(evt);
+				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
+				}
 			}
 		}
 
@@ -168,17 +201,19 @@
 			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];
 			});
+
+			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 });
+			wordWrap: ta.style.wordWrap
+		});
 
 		ta.addEventListener('autosize:destroy', destroy, false);
 
@@ -192,26 +227,29 @@
 		window.addEventListener('resize', pageResize, false);
 		ta.addEventListener('input', update, false);
 		ta.addEventListener('autosize:update', update, false);
-		set.add(ta);
+		ta.style.overflowX = 'hidden';
+		ta.style.wordWrap = 'break-word';
 
-		if (setOverflowX) {
-			ta.style.overflowX = 'hidden';
-			ta.style.wordWrap = 'break-word';
-		}
+		map.set(ta, {
+			destroy: destroy,
+			update: update
+		});
 
 		init();
 	}
 
 	function destroy(ta) {
-		if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
-		var evt = createEvent('autosize:destroy');
-		ta.dispatchEvent(evt);
+		var methods = map.get(ta);
+		if (methods) {
+			methods.destroy();
+		}
 	}
 
 	function update(ta) {
-		if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
-		var evt = createEvent('autosize:update');
-		ta.dispatchEvent(evt);
+		var methods = map.get(ta);
+		if (methods) {
+			methods.update();
+		}
 	}
 
 	var autosize = null;
diff --git a/package.json b/package.json
index 18ef012..88d9d51 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "autosize",
   "description": "Autosize is a small, stand-alone script to automatically adjust textarea height to fit text.",
-  "version": "3.0.15",
+  "version": "3.0.21",
   "keywords": [
     "textarea",
     "form",
@@ -27,9 +27,9 @@
   "dependencies": {},
   "devDependencies": {
     "babel": "^5.4.3",
-    "gaze": "^0.5.1",
-    "jshint": "^2.5.6",
-    "uglify-js": "^2.4.22"
+    "gaze": "^1.1.2",
+    "jshint": "^2.9.4",
+    "uglify-js": "^2.7.4"
   },
   "config": {
     "bower": {
diff --git a/src/autosize.js b/src/autosize.js
index d0e47ce..dd891c3 100644
--- a/src/autosize.js
+++ b/src/autosize.js
@@ -1,20 +1,31 @@
-const set = (typeof Set === "function") ? new Set() : (function () {
-	const list = [];
+const map = (typeof Map === "function") ? new Map() : (function () {
+	const keys = [];
+	const values = [];
 
 	return {
 		has(key) {
-			return Boolean(list.indexOf(key) > -1);
+			return keys.indexOf(key) > -1;
 		},
-		add(key) {
-			list.push(key);
+		get(key) {
+			return values[keys.indexOf(key)];
+		},
+		set(key, value) {
+			if (keys.indexOf(key) === -1) {
+				keys.push(key);
+				values.push(value);
+			}
 		},
 		delete(key) {
-			list.splice(list.indexOf(key), 1);
+			const index = keys.indexOf(key);
+			if (index > -1) {
+				keys.splice(index, 1);
+				values.splice(index, 1);
+			}
 		},
 	}
 })();
 
-let createEvent = (name)=> new Event(name);
+let createEvent = (name)=> new Event(name, {bubbles: true});
 try {
 	new Event('test');
 } catch(e) {
@@ -26,18 +37,16 @@ try {
 	};
 }
 
-function assign(ta, {setOverflowX = true, setOverflowY = true} = {}) {
-	if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return;
+function assign(ta) {
+	if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return;
 
 	let heightOffset = null;
-	let overflowY = null;
 	let clientWidth = ta.clientWidth;
+	let cachedHeight = null;
 
 	function init() {
 		const style = window.getComputedStyle(ta, null);
 
-		overflowY = style.overflowY;
-
 		if (style.resize === 'vertical') {
 			ta.style.resize = 'none';
 		} else if (style.resize === 'both') {
@@ -71,19 +80,29 @@ function assign(ta, {setOverflowX = true, setOverflowY = true} = {}) {
 			ta.style.width = width;
 		}
 
-		overflowY = value;
+		ta.style.overflowY = value;
+	}
+
+	function getParentOverflows(el) {
+		const arr = [];
 
-		if (setOverflowY) {
-			ta.style.overflowY = value;
+		while (el && el.parentNode && el.parentNode instanceof Element) {
+			if (el.parentNode.scrollTop) {
+				arr.push({
+					node: el.parentNode,
+					scrollTop: el.parentNode.scrollTop,
+				})
+			}
+			el = el.parentNode;
 		}
 
-		resize();
+		return arr;
 	}
 
 	function resize() {
-		const htmlTop = window.pageYOffset;
-		const bodyTop = document.body.scrollTop;
 		const originalHeight = ta.style.height;
+		const overflows = getParentOverflows(ta);
+		const docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240)
 
 		ta.style.height = 'auto';
 
@@ -101,30 +120,50 @@ function assign(ta, {setOverflowX = true, setOverflowY = true} = {}) {
 		clientWidth = ta.clientWidth;
 
 		// prevents scroll-position jumping
-		document.documentElement.scrollTop = htmlTop;
-		document.body.scrollTop = bodyTop;
+		overflows.forEach(el => {
+			el.node.scrollTop = el.scrollTop
+		});
+
+		if (docTop) {
+			document.documentElement.scrollTop = docTop;
+		}
 	}
 
 	function update() {
-		const startHeight = ta.style.height;
-
 		resize();
 
-		const style = window.getComputedStyle(ta, null);
+		const styleHeight = Math.round(parseFloat(ta.style.height));
+		const computed = window.getComputedStyle(ta, null);
 
-		if (style.height !== ta.style.height) {
-			if (overflowY !== 'visible') {
-				changeOverflow('visible');
+		// Using offsetHeight as a replacement for computed.height in IE, because IE does not account use of border-box
+		var 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 {
-			if (overflowY !== 'hidden') {
+			// 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 (startHeight !== ta.style.height) {
+		if (cachedHeight !== actualHeight) {
+			cachedHeight = actualHeight;
 			const evt = createEvent('autosize:resized');
-			ta.dispatchEvent(evt);
+			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
+			}
 		}
 	}
 
@@ -140,11 +179,12 @@ function assign(ta, {setOverflowX = true, setOverflowY = true} = {}) {
 		ta.removeEventListener('keyup', update, false);
 		ta.removeEventListener('autosize:destroy', destroy, false);
 		ta.removeEventListener('autosize:update', update, false);
-		set.delete(ta);
 
 		Object.keys(style).forEach(key => {
 			ta.style[key] = style[key];
 		});
+
+		map.delete(ta);
 	}.bind(ta, {
 		height: ta.style.height,
 		resize: ta.style.resize,
@@ -165,26 +205,29 @@ function assign(ta, {setOverflowX = true, setOverflowY = true} = {}) {
 	window.addEventListener('resize', pageResize, false);
 	ta.addEventListener('input', update, false);
 	ta.addEventListener('autosize:update', update, false);
-	set.add(ta);
+	ta.style.overflowX = 'hidden';
+	ta.style.wordWrap = 'break-word';
 
-	if (setOverflowX) {
-		ta.style.overflowX = 'hidden';
-		ta.style.wordWrap = 'break-word';
-	}
+	map.set(ta, {
+		destroy,
+		update,
+	});
 
 	init();
 }
 
 function destroy(ta) {
-	if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
-	const evt = createEvent('autosize:destroy');
-	ta.dispatchEvent(evt);
+	const methods = map.get(ta);
+	if (methods) {
+		methods.destroy();
+	}
 }
 
 function update(ta) {
-	if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
-	const evt = createEvent('autosize:update');
-	ta.dispatchEvent(evt);
+	const methods = map.get(ta);
+	if (methods) {
+		methods.update();
+	}
 }
 
 let autosize = null;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/autosize.js.git



More information about the Pkg-javascript-commits mailing list