diff --git a/bower.json b/bower.json index 7dca491e1f..def704c4e8 100644 --- a/bower.json +++ b/bower.json @@ -31,6 +31,7 @@ "davclient.js": "https://github.com/evert/davclient.js.git", "es6-promise": "https://github.com/jakearchibald/es6-promise.git#~2.3.0", "base64": "~0.3.0", - "clipboard": "^1.5.12" + "clipboard": "^1.5.12", + "autosize": "^3.0.17" } } diff --git a/core/js/core.json b/core/js/core.json index 5254e7b3d0..e651c9d759 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -11,7 +11,8 @@ "backbone/backbone.js", "es6-promise/dist/es6-promise.js", "davclient.js/lib/client.js", - "clipboard/dist/clipboard.js" + "clipboard/dist/clipboard.js", + "autosize/dist/autosize.js" ], "libraries": [ "jquery-showpassword.js", diff --git a/core/vendor/.gitignore b/core/vendor/.gitignore index 70636c3932..7982f7de93 100644 --- a/core/vendor/.gitignore +++ b/core/vendor/.gitignore @@ -142,3 +142,10 @@ base64/*min.js clipboard/** !clipboard/dist !clipboard/dist/clipboard.js + +# autosize +autosize/** +!autosize/dist +!autosize/dist/autosize.js +!autosize/.bower.json +!autosize/LICENCE.md diff --git a/core/vendor/autosize/.bower.json b/core/vendor/autosize/.bower.json new file mode 100644 index 0000000000..56e4b46a16 --- /dev/null +++ b/core/vendor/autosize/.bower.json @@ -0,0 +1,40 @@ +{ + "name": "autosize", + "description": "Autosize is a small, stand-alone script to automatically adjust textarea height to fit text.", + "dependencies": {}, + "keywords": [ + "textarea", + "form", + "ui" + ], + "authors": [ + { + "name": "Jack Moore", + "url": "http://www.jacklmoore.com", + "email": "hello@jacklmoore.com" + } + ], + "license": "MIT", + "homepage": "http://www.jacklmoore.com/autosize", + "ignore": [], + "repository": { + "type": "git", + "url": "http://github.com/jackmoore/autosize.git" + }, + "main": "dist/autosize.js", + "moduleType": [ + "amd", + "node" + ], + "version": "3.0.17", + "_release": "3.0.17", + "_resolution": { + "type": "version", + "tag": "3.0.17", + "commit": "144040e4f545fbea9b304706a5200eba9961ee3f" + }, + "_source": "https://github.com/jackmoore/autosize.git", + "_target": "^3.0.17", + "_originalSource": "autosize", + "_direct": true +} \ No newline at end of file diff --git a/core/vendor/autosize/LICENSE.md b/core/vendor/autosize/LICENSE.md new file mode 100644 index 0000000000..2de673bfa0 --- /dev/null +++ b/core/vendor/autosize/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jack Moore + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/core/vendor/autosize/dist/autosize.js b/core/vendor/autosize/dist/autosize.js new file mode 100644 index 0000000000..49b8b0b957 --- /dev/null +++ b/core/vendor/autosize/dist/autosize.js @@ -0,0 +1,262 @@ +/*! + Autosize 3.0.17 + license: MIT + http://www.jacklmoore.com/autosize +*/ +(function (global, factory) { + if (typeof define === 'function' && define.amd) { + define(['exports', 'module'], factory); + } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { + factory(exports, module); + } else { + 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; + }; + } + + function assign(ta) { + if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return; + + var heightOffset = null; + var clientWidth = ta.clientWidth; + var 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; + + resize(); + } + + 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() { + 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'; + + var endHeight = ta.scrollHeight + heightOffset; + + 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'; + + // 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 computed = window.getComputedStyle(ta, null); + var computedHeight = Math.round(parseFloat(computed.height)); + var styleHeight = Math.round(parseFloat(ta.style.height)); + + // The computed height not matching the height set via resize indicates that + // the max-height has been exceeded, in which case the overflow should be set to visible. + if (computedHeight !== styleHeight) { + if (computed.overflowY !== 'visible') { + changeOverflow('visible'); + } + } else { + // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. + if (computed.overflowY !== 'hidden') { + changeOverflow('hidden'); + } + } + + if (cachedHeight !== computedHeight) { + cachedHeight = computedHeight; + 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', update, false); + } + + 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'; + + init(); + } + + function destroy(ta) { + if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; + var evt = createEvent('autosize:destroy'); + ta.dispatchEvent(evt); + } + + function update(ta) { + if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; + var evt = createEvent('autosize:update'); + ta.dispatchEvent(evt); + } + + 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 { + 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 el; + }; + autosize.update = function (el) { + if (el) { + Array.prototype.forEach.call(el.length ? el : [el], update); + } + return el; + }; + } + + module.exports = autosize; +}); \ No newline at end of file