From c5d24a6b0798ee0af94312eea33e4c63631ef9c0 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 14 Sep 2016 13:48:03 +0200 Subject: [PATCH 1/4] Add autosize --- bower.json | 3 +- core/js/core.json | 3 +- core/vendor/.gitignore | 7 + core/vendor/autosize/.bower.json | 40 ++++ core/vendor/autosize/LICENSE.md | 21 +++ core/vendor/autosize/dist/autosize.js | 262 ++++++++++++++++++++++++++ 6 files changed, 334 insertions(+), 2 deletions(-) create mode 100644 core/vendor/autosize/.bower.json create mode 100644 core/vendor/autosize/LICENSE.md create mode 100644 core/vendor/autosize/dist/autosize.js 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 From 5ca50d9f317cdba788005b2212161c9a59df7d12 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Wed, 14 Sep 2016 14:20:26 +0200 Subject: [PATCH 2/4] Add autosize to comments input Signed-off-by: Roeland Jago Douma --- apps/comments/css/comments.css | 6 +++++- apps/comments/js/commentstabview.js | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css index 7f64f1cf7d..d4b72d2147 100644 --- a/apps/comments/css/comments.css +++ b/apps/comments/css/comments.css @@ -25,7 +25,7 @@ #commentsTabView .newCommentForm .submit { position: absolute; - top: 1px; + bottom: 1px; right: 8px; width: 30px; margin: 0; @@ -47,6 +47,10 @@ margin-right: 6px; } +#commentsTabView .newCommentForm textarea { + resize: none; +} + #commentsTabView .comment { position: relative; z-index: 1; diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js index 82244d61e9..fe3695569b 100644 --- a/apps/comments/js/commentstabview.js +++ b/apps/comments/js/commentstabview.js @@ -32,7 +32,7 @@ '{{/if}}' + ' ' + '
' + - ' ' + + ' ' + ' ' + '{{#if isEditMode}}' + ' ' + @@ -174,6 +174,8 @@ } this.delegateEvents(); this.$el.find('.message').on('keydown input change', this._onTypeComment); + + autosize(this.$el.find('.newCommentRow textarea')) }, _formatItem: function(commentModel) { @@ -281,6 +283,9 @@ $formRow.find('.avatar').replaceWith($comment.find('.avatar').clone()); $formRow.find('.has-tooltip').tooltip(); + // Enable autosize + autosize($formRow.find('textarea')); + return false; }, @@ -346,7 +351,6 @@ } }); - return false; }, From c83b3e6bd57ed39d88ad1dd847e18d937d44ee28 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 4 Oct 2016 13:07:44 +0200 Subject: [PATCH 3/4] Fix js test --- apps/comments/tests/js/commentstabviewSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/comments/tests/js/commentstabviewSpec.js b/apps/comments/tests/js/commentstabviewSpec.js index 33c959e430..470ff0d221 100644 --- a/apps/comments/tests/js/commentstabviewSpec.js +++ b/apps/comments/tests/js/commentstabviewSpec.js @@ -328,7 +328,7 @@ describe('OCA.Comments.CommentsTabView tests', function() { var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]'); expect($formRow.length).toEqual(1); - $formRow.find('input').val('modified message'); + $formRow.find('textarea').val('modified message'); $formRow.find('form').submit(); expect(saveStub.calledOnce).toEqual(true); From dcddd4b9d5f2298ccfe302cf7041c2220ac79bee Mon Sep 17 00:00:00 2001 From: skjnldsv Date: Tue, 11 Oct 2016 12:31:17 +0200 Subject: [PATCH 4/4] fix textarea submit --- apps/comments/css/comments.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.css index d4b72d2147..b905fef24b 100644 --- a/apps/comments/css/comments.css +++ b/apps/comments/css/comments.css @@ -21,15 +21,16 @@ width: calc(100% - 81px); /* 36 (left margin) + 30 (right padding) + 15 (right padding of surrounding box) */ margin-left: 36px; padding-right: 30px; + display: block; } #commentsTabView .newCommentForm .submit { position: absolute; - bottom: 1px; + bottom: 0px; right: 8px; width: 30px; margin: 0; - padding: 9px; + padding: 7px 9px; background-color: transparent; border: none; opacity: .3;