diff --git a/config/assets.yml b/config/assets.yml index 7cfd5a3e9..ad16c439e 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -21,10 +21,10 @@ javascripts: - public/javascripts/app/views/content_view.js - public/javascripts/app/views/* - - public/javascripts/rails.validations.js + - public/javascripts/rails.validations.s - public/javascripts/rails.js - public/javascripts/vendor/jquery.hotkeys.js - - public/javascripts/vendor/jquery.autoresize.min.js + - public/javascripts/vendor/jquery.autoresize.js - public/javascripts/vendor/jquery-ui-1.8.9.custom.min.js - public/javascripts/vendor/jquery.charcount.js - public/javascripts/vendor/jquery.expander.js diff --git a/public/javascripts/app/views/commment_stream_view.js b/public/javascripts/app/views/commment_stream_view.js index f47a1a00c..0e2a991ee 100644 --- a/public/javascripts/app/views/commment_stream_view.js +++ b/public/javascripts/app/views/commment_stream_view.js @@ -12,14 +12,14 @@ app.views.CommentStream = app.views.Base.extend({ initialize: function(options) { this.model.comments.bind('add', this.appendComment, this); - - // add autoexpanders to new comment textarea - this.$('textarea').autoResize(); }, postRenderTemplate : function() { this.$("label").inFieldLabels(); this.model.comments.each(this.appendComment, this); + + // add autoexpanders to new comment textarea + this.$("textarea").autoResize({'extraSpace' : 10}); }, createComment: function(evt) { @@ -29,7 +29,7 @@ app.views.CommentStream = app.views.Base.extend({ "text" : this.$(".comment_box").val() }); - this.$(".comment_box").val(""); + this.$(".comment_box").empty() return this; }, diff --git a/public/javascripts/publisher.js b/public/javascripts/publisher.js index e416afc1b..746ca4976 100644 --- a/public/javascripts/publisher.js +++ b/public/javascripts/publisher.js @@ -451,8 +451,6 @@ var Publisher = { selection.popover(options); selection.bind("click", function(){$(this).popover("hide")}); - - setTimeout(function(){ selection.popover("show"); @@ -480,7 +478,7 @@ var Publisher = { if(Publisher.hiddenInput().val() === "") { Publisher.hiddenInput().val(Publisher.input().val()); } - Publisher.input().autoResize(); + Publisher.input().autoResize({'extraSpace' : 10}); Publisher.input().keydown(Publisher.autocompletion.keyDownHandler); Publisher.input().keyup(Publisher.autocompletion.keyUpHandler); Publisher.input().mouseup(Publisher.autocompletion.keyUpHandler); diff --git a/public/javascripts/vendor/jquery.autoresize.js b/public/javascripts/vendor/jquery.autoresize.js new file mode 100644 index 000000000..4bc0959ae --- /dev/null +++ b/public/javascripts/vendor/jquery.autoresize.js @@ -0,0 +1,274 @@ +/* + * jQuery.fn.autoResize 1.14 + * -- + * https://github.com/padolsey/jQuery.fn.autoResize + * -- + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. */ + +(function($){ + + var uid = 'ar' + +new Date, + + defaults = autoResize.defaults = { + onResize: function(){}, + onBeforeResize: function(){return 123}, + onAfterResize: function(){return 555}, + animate: { + duration: 200, + complete: function(){} + }, + extraSpace: 50, + minHeight: 'original', + maxHeight: 500, + minWidth: 'original', + maxWidth: 500 + }; + + autoResize.cloneCSSProperties = [ + 'lineHeight', 'textDecoration', 'letterSpacing', + 'fontSize', 'fontFamily', 'fontStyle', 'fontWeight', + 'textTransform', 'textAlign', 'direction', 'wordSpacing', 'fontSizeAdjust', + 'paddingTop', 'paddingLeft', 'paddingBottom', 'paddingRight', 'width' + ]; + + autoResize.cloneCSSValues = { + position: 'absolute', + top: -9999, + left: -9999, + opacity: 0, + overflow: 'hidden' + }; + + autoResize.resizableFilterSelector = [ + 'textarea:not(textarea.' + uid + ')', + 'input:not(input[type])', + 'input[type=text]', + 'input[type=password]', + 'input[type=email]', + 'input[type=url]' + ].join(','); + + autoResize.AutoResizer = AutoResizer; + + $.fn.autoResize = autoResize; + + function autoResize(config) { + this.filter(autoResize.resizableFilterSelector).each(function(){ + new AutoResizer( $(this), config ); + }); + return this; + } + + function AutoResizer(el, config) { + + if (el.data('AutoResizer')) { + el.data('AutoResizer').destroy(); + } + + config = this.config = $.extend({}, autoResize.defaults, config); + this.el = el; + + this.nodeName = el[0].nodeName.toLowerCase(); + + this.originalHeight = el.height(); + this.previousScrollTop = null; + + this.value = el.val(); + + if (config.maxWidth === 'original') config.maxWidth = el.width(); + if (config.minWidth === 'original') config.minWidth = el.width(); + if (config.maxHeight === 'original') config.maxHeight = el.height(); + if (config.minHeight === 'original') config.minHeight = el.height(); + + if (this.nodeName === 'textarea') { + el.css({ + resize: 'none', + overflowY: 'hidden' + }); + } + + el.data('AutoResizer', this); + + // Make sure onAfterResize is called upon animation completion + config.animate.complete = (function(f){ + return function() { + config.onAfterResize.call(el); + return f.apply(this, arguments); + }; + }(config.animate.complete)); + + this.bind(); + + } + + AutoResizer.prototype = { + + bind: function() { + + var check = $.proxy(function(){ + this.check(); + return true; + }, this); + + this.unbind(); + + this.el + .bind('keyup.autoResize', check) + //.bind('keydown.autoResize', check) + .bind('change.autoResize', check) + .bind('paste.autoResize', function() { + setTimeout(function() { check(); }, 0); + }); + + if (!this.el.is(':hidden')) { + this.check(null, true); + } + + }, + + unbind: function() { + this.el.unbind('.autoResize'); + }, + + createClone: function() { + + var el = this.el, + clone = this.nodeName === 'textarea' ? el.clone() : $(''); + + this.clone = clone; + + $.each(autoResize.cloneCSSProperties, function(i, p){ + clone[0].style[p] = el.css(p); + }); + + clone + .removeAttr('name') + .removeAttr('id') + .addClass(uid) + .attr('tabIndex', -1) + .css(autoResize.cloneCSSValues); + + if (this.nodeName === 'textarea') { + clone.height('auto'); + } else { + clone.width('auto').css({ + whiteSpace: 'nowrap' + }); + } + + }, + + check: function(e, immediate) { + + if (!this.clone) { + this.createClone(); + this.injectClone(); + } + + var config = this.config, + clone = this.clone, + el = this.el, + value = el.val(); + + // Do nothing if value hasn't changed + if (value === this.prevValue) { return true; } + this.prevValue = value; + + if (this.nodeName === 'input') { + + clone.text(value); + + // Calculate new width + whether to change + var cloneWidth = clone.width(), + newWidth = (cloneWidth + config.extraSpace) >= config.minWidth ? + cloneWidth + config.extraSpace : config.minWidth, + currentWidth = el.width(); + + newWidth = Math.min(newWidth, config.maxWidth); + + if ( + (newWidth < currentWidth && newWidth >= config.minWidth) || + (newWidth >= config.minWidth && newWidth <= config.maxWidth) + ) { + + config.onBeforeResize.call(el); + config.onResize.call(el); + + el.scrollLeft(0); + + if (config.animate && !immediate) { + el.stop(1,1).animate({ + width: newWidth + }, config.animate); + } else { + el.width(newWidth); + config.onAfterResize.call(el); + } + + } + + return; + + } + + // TEXTAREA + + clone.width(el.width()).height(0).val(value).scrollTop(10000); + + var scrollTop = clone[0].scrollTop; + + // Don't do anything if scrollTop hasen't changed: + if (this.previousScrollTop === scrollTop) { + return; + } + + this.previousScrollTop = scrollTop; + + if (scrollTop + config.extraSpace >= config.maxHeight) { + el.css('overflowY', ''); + scrollTop = config.maxHeight; + immediate = true; + } else if (scrollTop <= config.minHeight) { + scrollTop = config.minHeight; + } else { + el.css('overflowY', 'hidden'); + scrollTop += config.extraSpace; + } + + config.onBeforeResize.call(el); + config.onResize.call(el); + + // Either animate or directly apply height: + if (config.animate && !immediate) { + el.stop(1,1).animate({ + height: scrollTop + }, config.animate); + } else { + el.height(scrollTop); + config.onAfterResize.call(el); + } + + }, + + destroy: function() { + this.unbind(); + this.el.removeData('AutoResizer'); + this.clone.remove(); + delete this.el; + delete this.clone; + }, + + injectClone: function() { + ( + autoResize.cloneContainer || + (autoResize.cloneContainer = $('').appendTo('body')) + ).append(this.clone); + } + + }; + +})(jQuery); diff --git a/public/javascripts/vendor/jquery.autoresize.min.js b/public/javascripts/vendor/jquery.autoresize.min.js deleted file mode 100644 index 5f94833a9..000000000 --- a/public/javascripts/vendor/jquery.autoresize.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * jQuery autoResize (textarea auto-resizer) - * @copyright James Padolsey http://james.padolsey.com - * @version 1.04 - */ - -(function(a){a.fn.autoResize=function(j){var b=a.extend({onResize:function(){},animate:true,animateDuration:150,animateCallback:function(){},extraSpace:20,limit:1000},j);this.filter('textarea').each(function(){var c=a(this).css({resize:'none','overflow-y':'hidden'}),k=c.height(),f=(function(){var l=['height','width','lineHeight','textDecoration','letterSpacing'],h={};a.each(l,function(d,e){h[e]=c.css(e)});return c.clone().removeAttr('id').removeAttr('name').css({position:'absolute',top:0,left:-9999}).css(h).attr('tabIndex','-1').insertBefore(c)})(),i=null,g=function(){f.height(0).val(a(this).val()).scrollTop(10000);var d=Math.max(f.scrollTop(),k)+b.extraSpace,e=a(this).add(f);if(i===d){return}i=d;if(d>=b.limit){a(this).css('overflow-y','');return}b.onResize.call(this);b.animate&&c.css('display')==='block'?e.stop().animate({height:d},b.animateDuration,b.animateCallback):e.height(d)};c.unbind('.dynSiz').bind('keyup.dynSiz',g).bind('keydown.dynSiz',g).bind('change.dynSiz',g)});return this}})(jQuery); \ No newline at end of file diff --git a/public/javascripts/view.js b/public/javascripts/view.js index f15be2979..f099ed62a 100644 --- a/public/javascripts/view.js +++ b/public/javascripts/view.js @@ -39,19 +39,6 @@ var View = { $(this).siblings("#tag_following_submit").removeClass('hidden'); }); - /* Autoexpand textareas */ - var startAutoResize = function() { - if (arguments.length > 1){ - target = $(Array.prototype.slice.call(arguments,1)).find('textarea'); - }else{ - target = $('textarea') - } - target.autoResize({ - 'animate': false, - 'extraSpace': 5 - }); - } - /* photo exporting in the works */ $("#photo-export-button").bind("click", function(evt){ evt.preventDefault(); diff --git a/spec/javascripts/app/views/comment_stream_view_spec.js b/spec/javascripts/app/views/comment_stream_view_spec.js new file mode 100644 index 000000000..64b67f7e8 --- /dev/null +++ b/spec/javascripts/app/views/comment_stream_view_spec.js @@ -0,0 +1,21 @@ +describe("app.views.CommentStream", function(){ + beforeEach(function(){ + this.view = new app.views.CommentStream({model : factory.post()}) + }) + + describe("postRenderTemplate", function(){ + it("applies infield labels", function(){ + spyOn($.fn, "inFieldLabels") + this.view.postRenderTemplate() + expect($.fn.inFieldLabels).toHaveBeenCalled() + expect($.fn.inFieldLabels.mostRecentCall.object.selector).toBe("label") + }) + + it("autoResizes the new comment textarea", function(){ + spyOn($.fn, "autoResize") + this.view.postRenderTemplate() + expect($.fn.autoResize).toHaveBeenCalled() + expect($.fn.autoResize.mostRecentCall.object.selector).toBe("textarea") + }) + }) +})