From 9c7212934c87312e04cbbbe23823f051de6b053d Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 4 Jan 2014 17:54:52 -0200 Subject: [PATCH 01/20] removes unused and/or unnceseary js files: *bootstrap-dropdown *bootstrap-modal *bootstrap-popover *bootstrap-transition *bootstratp-twipsy *jquery-ui-1.8.9.custom.min.js if we need the bootstrap files we should include them via the gem bootstrap-sass --- .../bootstrap/bootstrap-dropdown.js | 92 ---- .../javascripts/bootstrap/bootstrap-modal.js | 209 --------- .../bootstrap/bootstrap-popover.js | 77 --- .../bootstrap/bootstrap-transition.js | 51 -- .../javascripts/bootstrap/bootstrap-twipsy.js | 303 ------------ .../javascripts/jquery-ui-1.8.9.custom.min.js | 442 ------------------ 6 files changed, 1174 deletions(-) delete mode 100644 vendor/assets/javascripts/bootstrap/bootstrap-dropdown.js delete mode 100644 vendor/assets/javascripts/bootstrap/bootstrap-modal.js delete mode 100644 vendor/assets/javascripts/bootstrap/bootstrap-popover.js delete mode 100644 vendor/assets/javascripts/bootstrap/bootstrap-transition.js delete mode 100644 vendor/assets/javascripts/bootstrap/bootstrap-twipsy.js delete mode 100755 vendor/assets/javascripts/jquery-ui-1.8.9.custom.min.js diff --git a/vendor/assets/javascripts/bootstrap/bootstrap-dropdown.js b/vendor/assets/javascripts/bootstrap/bootstrap-dropdown.js deleted file mode 100644 index 54b61c5e9..000000000 --- a/vendor/assets/javascripts/bootstrap/bootstrap-dropdown.js +++ /dev/null @@ -1,92 +0,0 @@ -/* ============================================================ - * bootstrap-dropdown.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#dropdowns - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function( $ ){ - - "use strict" - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle="dropdown"]' - , Dropdown = function ( element ) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function ( e ) { - var $this = $(this) - , selector = $this.attr('data-target') - , $parent - , isActive - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - $parent.length || ($parent = $this.parent()) - - isActive = $parent.hasClass('open') - - clearMenus() - !isActive && $parent.toggleClass('open') - - return false - } - - } - - function clearMenus() { - $(toggle).parent().removeClass('open') - } - - - /* DROPDOWN PLUGIN DEFINITION - * ========================== */ - - $.fn.dropdown = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('dropdown') - if (!data) $this.data('dropdown', (data = new Dropdown(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.dropdown.Constructor = Dropdown - - - /* APPLY TO STANDARD DROPDOWN ELEMENTS - * =================================== */ - - $(function () { - $('html').on('click.dropdown.data-api', clearMenus) - $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) - }) - -}( window.jQuery ); \ No newline at end of file diff --git a/vendor/assets/javascripts/bootstrap/bootstrap-modal.js b/vendor/assets/javascripts/bootstrap/bootstrap-modal.js deleted file mode 100644 index bac0dee18..000000000 --- a/vendor/assets/javascripts/bootstrap/bootstrap-modal.js +++ /dev/null @@ -1,209 +0,0 @@ -/* ========================================================= - * bootstrap-modal.js v2.0.0 - * http://twitter.github.com/bootstrap/javascript.html#modals - * ========================================================= - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================= */ - - -!function( $ ){ - - "use strict" - - /* MODAL CLASS DEFINITION - * ====================== */ - - var Modal = function ( content, options ) { - this.options = $.extend({}, $.fn.modal.defaults, options) - this.$element = $(content) - .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) - } - - Modal.prototype = { - - constructor: Modal - - , toggle: function () { - return this[!this.isShown ? 'show' : 'hide']() - } - - , show: function () { - var that = this - - if (this.isShown) return - - $('body').addClass('modal-open') - - this.isShown = true - this.$element.trigger('show') - - escape.call(this) - backdrop.call(this, function () { - var transition = $.support.transition && that.$element.hasClass('fade') - - !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position - - that.$element - .show() - - if (transition) { - that.$element[0].offsetWidth // force reflow - } - - that.$element.addClass('in') - - transition ? - that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) : - that.$element.trigger('shown') - - }) - } - - , hide: function ( e ) { - e && e.preventDefault() - - if (!this.isShown) return - - var that = this - this.isShown = false - - $('body').removeClass('modal-open') - - escape.call(this) - - this.$element - .trigger('hide') - .removeClass('in') - - $.support.transition && this.$element.hasClass('fade') ? - hideWithTransition.call(this) : - hideModal.call(this) - } - - } - - - /* MODAL PRIVATE METHODS - * ===================== */ - - function hideWithTransition() { - var that = this - , timeout = setTimeout(function () { - that.$element.off($.support.transition.end) - hideModal.call(that) - }, 500) - - this.$element.one($.support.transition.end, function () { - clearTimeout(timeout) - hideModal.call(that) - }) - } - - function hideModal( that ) { - this.$element - .hide() - .trigger('hidden') - - backdrop.call(this) - } - - function backdrop( callback ) { - var that = this - , animate = this.$element.hasClass('fade') ? 'fade' : '' - - if (this.isShown && this.options.backdrop) { - var doAnimate = $.support.transition && animate - - this.$backdrop = $('").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ -e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); -;/* - * jQuery UI Effects Fade 1.8.9 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fade - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Fold 1.8.9 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * jquery.effects.core.js - */ -(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], -10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); -;/* - * jQuery UI Effects Highlight 1.8.9 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& -this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Pulsate 1.8.9 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * jquery.effects.core.js - */ -(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); -b.dequeue()})})}})(jQuery); -; -/* - * jQuery UI Sortable 1.8.9 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Sortables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function($,undefined){$.widget("ui.sortable",$.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:'auto',cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:'> *',opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000},_create:function(){var o=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css('float')):false;this.offset=this.element.offset();this._mouseInit();},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var i=this.items.length-1;i>=0;i--) -this.items[i].item.removeData("sortable-item");return this;},_setOption:function(key,value){if(key==="disabled"){this.options[key]=value;this.widget() -[value?"addClass":"removeClass"]("ui-sortable-disabled");}else{$.Widget.prototype._setOption.apply(this,arguments);}},_mouseCapture:function(event,overrideHandle){if(this.reverting){return false;} -if(this.options.disabled||this.options.type=='static')return false;this._refreshItems(event);var currentItem=null,self=this,nodes=$(event.target).parents().each(function(){if($.data(this,'sortable-item')==self){currentItem=$(this);return false;}});if($.data(event.target,'sortable-item')==self)currentItem=$(event.target);if(!currentItem)return false;if(this.options.handle&&!overrideHandle){var validHandle=false;$(this.options.handle,currentItem).find("*").andSelf().each(function(){if(this==event.target)validHandle=true;});if(!validHandle)return false;} -this.currentItem=currentItem;this._removeCurrentsFromItems();return true;},_mouseStart:function(event,overrideHandle,noActivation){var o=this.options,self=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(event);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");$.extend(this.offset,{click:{left:event.pageX-this.offset.left,top:event.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(event);this.originalPageX=event.pageX;this.originalPageY=event.pageY;(o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt));this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide();} -this._createPlaceholder();if(o.containment) -this._setContainment();if(o.cursor){if($('body').css("cursor"))this._storedCursor=$('body').css("cursor");$('body').css("cursor",o.cursor);} -if(o.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",o.opacity);} -if(o.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",o.zIndex);} -if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!='HTML') -this.overflowOffset=this.scrollParent.offset();this._trigger("start",event,this._uiHash());if(!this._preserveHelperProportions) -this._cacheHelperProportions();if(!noActivation){for(var i=this.containers.length-1;i>=0;i--){this.containers[i]._trigger("activate",event,self._uiHash(this));}} -if($.ui.ddmanager) -$.ui.ddmanager.current=this;if($.ui.ddmanager&&!o.dropBehaviour) -$.ui.ddmanager.prepareOffsets(this,event);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(event);return true;},_mouseDrag:function(event){this.position=this._generatePosition(event);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs;} -if(this.options.scroll){var o=this.options,scrolled=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!='HTML'){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-event.pageY=0;i--){var item=this.items[i],itemElement=item.item[0],intersection=this._intersectsWithPointer(item);if(!intersection)continue;if(itemElement!=this.currentItem[0]&&this.placeholder[intersection==1?"next":"prev"]()[0]!=itemElement&&!$.ui.contains(this.placeholder[0],itemElement)&&(this.options.type=='semi-dynamic'?!$.ui.contains(this.element[0],itemElement):true)){this.direction=intersection==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(item)){this._rearrange(event,item);}else{break;} -this._trigger("change",event,this._uiHash());break;}} -this._contactContainers(event);if($.ui.ddmanager)$.ui.ddmanager.drag(this,event);this._trigger('sort',event,this._uiHash());this.lastPositionAbs=this.positionAbs;return false;},_mouseStop:function(event,noPropagation){if(!event)return;if($.ui.ddmanager&&!this.options.dropBehaviour) -$.ui.ddmanager.drop(this,event);if(this.options.revert){var self=this;var cur=self.placeholder.offset();self.reverting=true;$(this.helper).animate({left:cur.left-this.offset.parent.left-self.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:cur.top-this.offset.parent.top-self.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){self._clear(event);});}else{this._clear(event,noPropagation);} -return false;},cancel:function(){var self=this;if(this.dragging){this._mouseUp({target:null});if(this.options.helper=="original") -this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");else -this.currentItem.show();for(var i=this.containers.length-1;i>=0;i--){this.containers[i]._trigger("deactivate",null,self._uiHash(this));if(this.containers[i].containerCache.over){this.containers[i]._trigger("out",null,self._uiHash(this));this.containers[i].containerCache.over=0;}}} -if(this.placeholder){if(this.placeholder[0].parentNode)this.placeholder[0].parentNode.removeChild(this.placeholder[0]);if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode)this.helper.remove();$.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){$(this.domPosition.prev).after(this.currentItem);}else{$(this.domPosition.parent).prepend(this.currentItem);}} -return this;},serialize:function(o){var items=this._getItemsAsjQuery(o&&o.connected);var str=[];o=o||{};$(items).each(function(){var res=($(o.item||this).attr(o.attribute||'id')||'').match(o.expression||(/(.+)[-=_](.+)/));if(res)str.push((o.key||res[1]+'[]')+'='+(o.key&&o.expression?res[1]:res[2]));});if(!str.length&&o.key){str.push(o.key+'=');} -return str.join('&');},toArray:function(o){var items=this._getItemsAsjQuery(o&&o.connected);var ret=[];o=o||{};items.each(function(){ret.push($(o.item||this).attr(o.attribute||'id')||'');});return ret;},_intersectsWith:function(item){var x1=this.positionAbs.left,x2=x1+this.helperProportions.width,y1=this.positionAbs.top,y2=y1+this.helperProportions.height;var l=item.left,r=l+item.width,t=item.top,b=t+item.height;var dyClick=this.offset.click.top,dxClick=this.offset.click.left;var isOverElement=(y1+dyClick)>t&&(y1+dyClick)l&&(x1+dxClick)item[this.floating?'width':'height'])){return isOverElement;}else{return(l0?"down":"up");},_getDragHorizontalDirection:function(){var delta=this.positionAbs.left-this.lastPositionAbs.left;return delta!=0&&(delta>0?"right":"left");},refresh:function(event){this._refreshItems(event);this.refreshPositions();return this;},_connectWith:function(){var options=this.options;return options.connectWith.constructor==String?[options.connectWith]:options.connectWith;},_getItemsAsjQuery:function(connected){var self=this;var items=[];var queries=[];var connectWith=this._connectWith();if(connectWith&&connected){for(var i=connectWith.length-1;i>=0;i--){var cur=$(connectWith[i]);for(var j=cur.length-1;j>=0;j--){var inst=$.data(cur[j],'sortable');if(inst&&inst!=this&&!inst.options.disabled){queries.push([$.isFunction(inst.options.items)?inst.options.items.call(inst.element):$(inst.options.items,inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'),inst]);}};};} -queries.push([$.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):$(this.options.items,this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'),this]);for(var i=queries.length-1;i>=0;i--){queries[i][0].each(function(){items.push(this);});};return $(items);},_removeCurrentsFromItems:function(){var list=this.currentItem.find(":data(sortable-item)");for(var i=0;i=0;i--){var cur=$(connectWith[i]);for(var j=cur.length-1;j>=0;j--){var inst=$.data(cur[j],'sortable');if(inst&&inst!=this&&!inst.options.disabled){queries.push([$.isFunction(inst.options.items)?inst.options.items.call(inst.element[0],event,{item:this.currentItem}):$(inst.options.items,inst.element),inst]);this.containers.push(inst);}};};} -for(var i=queries.length-1;i>=0;i--){var targetData=queries[i][1];var _queries=queries[i][0];for(var j=0,queriesLength=_queries.length;j=0;i--){var item=this.items[i];var t=this.options.toleranceElement?$(this.options.toleranceElement,item.item):item.item;if(!fast){item.width=t.outerWidth();item.height=t.outerHeight();} -var p=t.offset();item.left=p.left;item.top=p.top;};if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this);}else{for(var i=this.containers.length-1;i>=0;i--){var p=this.containers[i].element.offset();this.containers[i].containerCache.left=p.left;this.containers[i].containerCache.top=p.top;this.containers[i].containerCache.width=this.containers[i].element.outerWidth();this.containers[i].containerCache.height=this.containers[i].element.outerHeight();};} -return this;},_createPlaceholder:function(that){var self=that||this,o=self.options;if(!o.placeholder||o.placeholder.constructor==String){var className=o.placeholder;o.placeholder={element:function(){var el=$(document.createElement(self.currentItem[0].nodeName)).addClass(className||self.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!className) -el.style.visibility="hidden";return el;},update:function(container,p){if(className&&!o.forcePlaceholderSize)return;if(!p.height()){p.height(self.currentItem.innerHeight()-parseInt(self.currentItem.css('paddingTop')||0,10)-parseInt(self.currentItem.css('paddingBottom')||0,10));};if(!p.width()){p.width(self.currentItem.innerWidth()-parseInt(self.currentItem.css('paddingLeft')||0,10)-parseInt(self.currentItem.css('paddingRight')||0,10));};}};} -self.placeholder=$(o.placeholder.element.call(self.element,self.currentItem));self.currentItem.after(self.placeholder);o.placeholder.update(self,self.placeholder);},_contactContainers:function(event){var innermostContainer=null,innermostIndex=null;for(var i=this.containers.length-1;i>=0;i--){if($.ui.contains(this.currentItem[0],this.containers[i].element[0])) -continue;if(this._intersectsWith(this.containers[i].containerCache)){if(innermostContainer&&$.ui.contains(this.containers[i].element[0],innermostContainer.element[0])) -continue;innermostContainer=this.containers[i];innermostIndex=i;}else{if(this.containers[i].containerCache.over){this.containers[i]._trigger("out",event,this._uiHash(this));this.containers[i].containerCache.over=0;}}} -if(!innermostContainer)return;if(this.containers.length===1){this.containers[innermostIndex]._trigger("over",event,this._uiHash(this));this.containers[innermostIndex].containerCache.over=1;}else if(this.currentContainer!=this.containers[innermostIndex]){var dist=10000;var itemWithLeastDistance=null;var base=this.positionAbs[this.containers[innermostIndex].floating?'left':'top'];for(var j=this.items.length-1;j>=0;j--){if(!$.ui.contains(this.containers[innermostIndex].element[0],this.items[j].item[0]))continue;var cur=this.items[j][this.containers[innermostIndex].floating?'left':'top'];if(Math.abs(cur-base)this.containment[2])pageX=this.containment[2]+this.offset.click.left;if(event.pageY-this.offset.click.top>this.containment[3])pageY=this.containment[3]+this.offset.click.top;} -if(o.grid){var top=this.originalPageY+Math.round((pageY-this.originalPageY)/o.grid[1])*o.grid[1];pageY=this.containment?(!(top-this.offset.click.topthis.containment[3])?top:(!(top-this.offset.click.topthis.containment[2])?left:(!(left-this.offset.click.left=0;i--){if($.ui.contains(this.containers[i].element[0],this.currentItem[0])&&!noPropagation){delayedTriggers.push((function(c){return function(event){c._trigger("receive",event,this._uiHash(this));};}).call(this,this.containers[i]));delayedTriggers.push((function(c){return function(event){c._trigger("update",event,this._uiHash(this));};}).call(this,this.containers[i]));}};};for(var i=this.containers.length-1;i>=0;i--){if(!noPropagation)delayedTriggers.push((function(c){return function(event){c._trigger("deactivate",event,this._uiHash(this));};}).call(this,this.containers[i]));if(this.containers[i].containerCache.over){delayedTriggers.push((function(c){return function(event){c._trigger("out",event,this._uiHash(this));};}).call(this,this.containers[i]));this.containers[i].containerCache.over=0;}} -if(this._storedCursor)$('body').css("cursor",this._storedCursor);if(this._storedOpacity)this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=='auto'?'':this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!noPropagation){this._trigger("beforeStop",event,this._uiHash());for(var i=0;i Date: Sat, 4 Jan 2014 17:58:11 -0200 Subject: [PATCH 02/20] bump jquery-rails to 3.0.4 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 46d258f58..7bea2a253 100644 --- a/Gemfile +++ b/Gemfile @@ -129,7 +129,7 @@ group :assets do gem 'backbone-on-rails', '1.1.0' gem 'handlebars_assets', '0.12.0' - gem 'jquery-rails', '2.1.4' + gem 'jquery-rails', '3.0.4' # Windows and OSX have an execjs compatible runtime built-in, Linux users should # install Node.js or use 'therubyracer'. diff --git a/Gemfile.lock b/Gemfile.lock index d41e85957..3847db4aa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -206,7 +206,7 @@ GEM selenium-webdriver (>= 0.1.3) jasmine-core (1.3.1) journey (1.0.4) - jquery-rails (2.1.4) + jquery-rails (3.0.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) jquery-ui-rails (3.0.1) @@ -487,7 +487,7 @@ DEPENDENCIES http_accept_language (= 1.0.2) i18n-inflector-rails (= 1.0.7) jasmine (= 1.3.2) - jquery-rails (= 2.1.4) + jquery-rails (= 3.0.4) json (= 1.8.1) markerb (= 1.0.1) messagebus_ruby_api (= 1.0.3) From cc9c6c780a7e85cb44f408987073cc23a85584a1 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 4 Jan 2014 18:01:10 -0200 Subject: [PATCH 03/20] remove require if jquery-ui-1.8.9.custom.min --- app/assets/javascripts/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 02bad5148..3397b3fcb 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -8,7 +8,6 @@ //= require jquery.hotkeys //= require jquery.remotipart //= require jquery.autoresize -//= require jquery-ui-1.8.9.custom.min //= require jquery.charcount //= require jquery.placeholder //= require rails-timeago From d3921f1f2b9cbe94390458fbc92a7232dfe76edf Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 4 Jan 2014 18:04:56 -0200 Subject: [PATCH 04/20] #live is no longer supported, use on instead --- app/assets/javascripts/app/app.js | 2 +- app/assets/javascripts/app/views/hovercard_view.js | 6 +++--- app/assets/javascripts/aspect-edit-pane.js | 4 ++-- app/assets/javascripts/contact-list.js | 2 +- app/assets/javascripts/inbox.js | 11 ++--------- app/assets/javascripts/mobile.js | 2 +- app/assets/javascripts/view.js | 8 ++++---- 7 files changed, 14 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/app/app.js b/app/assets/javascripts/app/app.js index 04f93abb9..07ad66910 100644 --- a/app/assets/javascripts/app/app.js +++ b/app/assets/javascripts/app/app.js @@ -88,7 +88,7 @@ var app = { Backbone.history.start({pushState: true}); // there's probably a better way to do this... - $("a[rel=backbone]").live("click", function(evt){ + $(document).on("click", "a[rel=backbone]", function(evt){ evt.preventDefault(); var link = $(this); diff --git a/app/assets/javascripts/app/views/hovercard_view.js b/app/assets/javascripts/app/views/hovercard_view.js index 89d76cd3f..c32014a71 100644 --- a/app/assets/javascripts/app/views/hovercard_view.js +++ b/app/assets/javascripts/app/views/hovercard_view.js @@ -3,9 +3,9 @@ app.views.Hovercard = Backbone.View.extend({ el: '#hovercard_container', initialize: function() { - $('.hovercardable') - .live('mouseenter', _.bind(this._mouseenterHandler, this)) - .live('mouseleave', _.bind(this._mouseleaveHandler, this)); + $(document) + .on('mouseenter', '.hovercardable', _.bind(this._mouseenterHandler, this)) + .on('mouseleave', '.hovercardable', _.bind(this._mouseleaveHandler, this)); this.show_me = false; diff --git a/app/assets/javascripts/aspect-edit-pane.js b/app/assets/javascripts/aspect-edit-pane.js index 01b15896a..aeaa196e0 100644 --- a/app/assets/javascripts/aspect-edit-pane.js +++ b/app/assets/javascripts/aspect-edit-pane.js @@ -17,11 +17,11 @@ function updatePageAspectName( an_id, new_name) { } $(document).ready(function() { - $('#rename_aspect_link').live('click', function(){ + $('#aspect_name_title').on('click', '#rename_aspect_link', function(){ toggleAspectTitle(); }); - $('form.edit_aspect').live('ajax:success', function(evt, data, status, xhr) { + $(document).on('ajax:success', 'form.edit_aspect', function(evt, data, status, xhr) { updateAspectName(data['name']); updatePageAspectName( data['id'], data['name'] ); toggleAspectTitle(); diff --git a/app/assets/javascripts/contact-list.js b/app/assets/javascripts/contact-list.js index 17700a851..5d8785a6e 100644 --- a/app/assets/javascripts/contact-list.js +++ b/app/assets/javascripts/contact-list.js @@ -5,7 +5,7 @@ var List = { initialize: function() { - $(".contact_list_search").live("keyup", function(e) { + $(document).on("keyup", ".contact_list_search", function(e) { var search = $(this); var list = $(".contacts", ".searchable"); var query = new RegExp(search.val(),'i'); diff --git a/app/assets/javascripts/inbox.js b/app/assets/javascripts/inbox.js index 905e033cc..3ab0c4cf5 100644 --- a/app/assets/javascripts/inbox.js +++ b/app/assets/javascripts/inbox.js @@ -28,13 +28,13 @@ $(document).ready(function(){ function(){ $(this).find('.participants').slideDown('300'); }, - + function(){ $(this).find('.participants').slideUp('300'); } ); - $('.conversation-wrapper').live('click', function(){ + $(document).on('click', '.conversation-wrapper', function(){ var conversation_path = $(this).data('conversation-path'); $.getScript(conversation_path, function() { @@ -101,11 +101,4 @@ $(document).ready(function(){ $(document).ajaxError(function(e,xhr,opt){ if (xhr.status == 404) { $('a.next_page').remove(); } }); - - $('#reply_to_conversation').live('click', function(evt) { - evt.preventDefault(); - $('html, body').animate({scrollTop:$(window).height()}, 'medium', function(){ - $('#message_text').focus(); - }); - }); }); diff --git a/app/assets/javascripts/mobile.js b/app/assets/javascripts/mobile.js index 4e7d84450..0ba372480 100644 --- a/app/assets/javascripts/mobile.js +++ b/app/assets/javascripts/mobile.js @@ -217,7 +217,7 @@ $(document).ready(function(){ form.remove(); }); - $(".new_comment").live("submit", function(evt){ + $(document).on("submit", ".new_comment", function(evt){ evt.preventDefault(); var form = $(this); diff --git a/app/assets/javascripts/view.js b/app/assets/javascripts/view.js index 2e9cdf3d2..6e7d7f9ec 100644 --- a/app/assets/javascripts/view.js +++ b/app/assets/javascripts/view.js @@ -20,8 +20,8 @@ var View = { .keypress(this.search.keyPress); /* Dropdowns */ - $(this.dropdowns.selector) - .live('click', this.dropdowns.click); + $(document) + .on('click', this.dropdowns.selector, this.dropdowns.click); /* Avatars */ $(this.avatars.selector).error(this.avatars.fallback); @@ -45,7 +45,7 @@ var View = { }); }; - $('form[data-remote]').live('ajax:success', function (e) { + $(document).on('ajax:success', 'form[data-remote]', function (e) { $(this).clearForm(); $(this).focusout(); }); @@ -73,7 +73,7 @@ var View = { }); /* facebox 'done' buttons */ - $("*[rel*=close]").live('click', function(){ $.facebox.close(); }); + $(document).on('click', "*[rel*=close]", function(){ $.facebox.close(); }); /* notification routing */ $("#notification").delegate('.hard_object_link', 'click', function(evt){ From 8d8d3c649a12f10270efcf9331c72110181999a7 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 4 Jan 2014 18:08:24 -0200 Subject: [PATCH 05/20] remove aspect sorting logic --- app/assets/javascripts/aspect-sorting.js | 18 ------------------ app/assets/javascripts/main.js | 1 - app/controllers/users_controller.rb | 2 -- app/models/user.rb | 8 -------- 4 files changed, 29 deletions(-) delete mode 100644 app/assets/javascripts/aspect-sorting.js diff --git a/app/assets/javascripts/aspect-sorting.js b/app/assets/javascripts/aspect-sorting.js deleted file mode 100644 index 74d08e17a..000000000 --- a/app/assets/javascripts/aspect-sorting.js +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (c) 2010-2011, Diaspora Inc. This file is - * licensed under the Affero General Public License version 3 or later. See - * the COPYRIGHT file. - */ - -$(document).ready(function() { - $('#aspect_nav.left_nav .all_aspects .sub_nav').sortable({ - items: "li[data-aspect_id]", - update: function(event, ui) { - var order = $(this).sortable("toArray", {attribute: "data-aspect_id"}), - obj = { 'reorder_aspects': order, '_method': 'put' }; - $.ajax('/user', { type: 'post', dataType: 'script', data: obj }); - }, - revert: true, - helper: 'clone' - }); -}); - diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 3397b3fcb..63f5fc755 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -35,7 +35,6 @@ //= require aspects-dropdown //= require contact-edit //= require contact-list -//= require aspect-sorting //= require mentions //= require bootstrap-tooltip //= require bootstrap-popover diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index f7a2b3f94..97ed376eb 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -71,8 +71,6 @@ class UsersController < ApplicationController flash[:error] = I18n.t 'users.update.follow_settings_not_changed' end end - elsif aspect_order = params[:reorder_aspects] - @user.reorder_aspects(aspect_order) end respond_to do |format| diff --git a/app/models/user.rb b/app/models/user.rb index 8105d0961..0df8d75df 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -422,14 +422,6 @@ class User < ActiveRecord::Base end end - def reorder_aspects(aspect_order) - i = 0 - aspect_order.each do |id| - self.aspects.find(id).update_attributes({ :order_id => i }) - i += 1 - end - end - # Generate public/private keys for User and associated Person def generate_keys key_size = (Rails.env == 'test' ? 512 : 4096) From 9fc70a03a9782503f6fd85e2233dd7682fefa82c Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 4 Jan 2014 21:00:03 -0200 Subject: [PATCH 06/20] remove unused variable --- app/models/user.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 0df8d75df..0261857f9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -245,8 +245,6 @@ class User < ActiveRecord::Base end def add_to_streams(post, aspects_to_insert) - inserted_aspect_ids = aspects_to_insert.map{|x| x.id} - aspects_to_insert.each do |aspect| aspect << post end From 1c09b75cc2d412eaff1d336b5488427b46d9653b Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Mon, 6 Jan 2014 22:48:55 -0200 Subject: [PATCH 07/20] remove comment, for the record, it was an arbitrary number picked due to performance reasons --- app/views/contacts/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/contacts/index.html.haml b/app/views/contacts/index.html.haml index 5ffdc67b4..383cfd187 100644 --- a/app/views/contacts/index.html.haml +++ b/app/views/contacts/index.html.haml @@ -18,7 +18,7 @@ #people_stream.stream.contacts - if @aspect #aspect_controls - - if @contacts_size > 0 && @contacts_size < 20 #TODO Fla: why 20? Technical restriction? We already warn the user if > 16 + - if @contacts_size > 0 && @contacts_size < 20 = start_a_conversation_link(@aspect, @contacts_size) = link_to edit_aspect_path(@aspect), rel: "facebox", class: "button" do = t('aspects.edit.manage') From 4042e502891d9e86758b00eeab3cec94eb3316f2 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Mon, 18 Nov 2013 22:49:13 -0200 Subject: [PATCH 08/20] Removes client_side_validations Conflicts: Gemfile Gemfile.lock --- Gemfile | 1 - Gemfile.lock | 2 - app/assets/javascripts/main.js | 1 - app/views/registrations/new.html.erb | 2 +- app/views/registrations/new.mobile.haml | 2 +- .../initializers/client_side_validations.rb | 14 - .../assets/javascripts/rails.validations.js | 404 ------------------ 7 files changed, 2 insertions(+), 424 deletions(-) delete mode 100644 config/initializers/client_side_validations.rb delete mode 100644 vendor/assets/javascripts/rails.validations.js diff --git a/Gemfile b/Gemfile index 7bea2a253..219dc2532 100644 --- a/Gemfile +++ b/Gemfile @@ -97,7 +97,6 @@ gem 'typhoeus', '0.6.7' # Views -gem 'client_side_validations', '3.2.6' gem 'gon', '4.1.1' gem 'haml', '4.0.5' gem 'mobile-fu', '1.2.2' diff --git a/Gemfile.lock b/Gemfile.lock index 3847db4aa..b6c729d42 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,7 +66,6 @@ GEM childprocess (0.3.9) ffi (~> 1.0, >= 1.0.11) chunky_png (1.2.9) - client_side_validations (3.2.6) coderay (1.1.0) coffee-rails (3.2.2) coffee-script (>= 2.2.0) @@ -461,7 +460,6 @@ DEPENDENCIES bootstrap-sass (= 2.2.2.0) capybara (= 2.2.1) carrierwave (= 0.9.0) - client_side_validations (= 3.2.6) compass-rails (= 1.0.3) configurate (= 0.0.8) cucumber-rails (= 1.4.0) diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 63f5fc755..9c73b198c 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -4,7 +4,6 @@ */ //= require underscore //= require backbone -//= require rails.validations //= require jquery.hotkeys //= require jquery.remotipart //= require jquery.autoresize diff --git a/app/views/registrations/new.html.erb b/app/views/registrations/new.html.erb index 650864c5c..2adb3414b 100644 --- a/app/views/registrations/new.html.erb +++ b/app/views/registrations/new.html.erb @@ -19,7 +19,7 @@ <%= t('.sign_up') %> - <%= form_for(resource, :validate => true, :url => registration_path(resource_name), :html => {:class => "form-horizontal block-form", :autocomplete => "off"}) do |f| %> + <%= form_for(resource, :url => registration_path(resource_name), :html => {:class => "form-horizontal block-form", :autocomplete => "off"}) do |f| %>
}.html_safe -# else -# %{
#{html_tag}
}.html_safe -# end -# end - diff --git a/vendor/assets/javascripts/rails.validations.js b/vendor/assets/javascripts/rails.validations.js deleted file mode 100644 index c11030d24..000000000 --- a/vendor/assets/javascripts/rails.validations.js +++ /dev/null @@ -1,404 +0,0 @@ -/*! - * Rails 3 Client Side Validations - v3.1.0 - * https://github.com/bcardarlela/client_side_validations - * - * Copyright (c) 2011 Brian Cardarella - * Licensed under the MIT license - * http://www.opensource.org/licenses/mit-license.php - */ - -(function($) { - $.fn.validate = function() { - return this.filter('form[data-validate]').each(function() { - var form = $(this); - var settings = window[form.attr('id')]; - - // Set up the events for the form - form - .submit(function() { return form.isValid(settings.validators); }) - .bind('ajax:beforeSend', function() { return form.isValid(settings.validators); }) - // Callbacks - .bind('form:validate:after', function(eventData) { clientSideValidations.callbacks.form.after( form, eventData); }) - .bind('form:validate:before', function(eventData) { clientSideValidations.callbacks.form.before(form, eventData); }) - .bind('form:validate:fail', function(eventData) { clientSideValidations.callbacks.form.fail( form, eventData); }) - .bind('form:validate:pass', function(eventData) { clientSideValidations.callbacks.form.pass( form, eventData); }) - - // Set up the events for each validatable form element - .find('[data-validate]:input:not(:radio)') - .live('focusout', function() { $(this).isValid(settings.validators); }) - .live('change', function() { $(this).data('changed', true); }) - // Callbacks - .live('element:validate:after', function(eventData) { clientSideValidations.callbacks.element.after( $(this), eventData); }) - .live('element:validate:before', function(eventData) { clientSideValidations.callbacks.element.before($(this), eventData); }) - .live('element:validate:fail', function(eventData, message) { - var element = $(this); - clientSideValidations.callbacks.element.fail(element, message, function() { - addError(element, message); - }, eventData) }) - .live('element:validate:pass', function(eventData) { - var element = $(this); - clientSideValidations.callbacks.element.pass(element, function() { - removeError(element); - }, eventData) }) - // Checkboxes - Live events don't support filter - .end().find('[data-validate]:checkbox') - .live('click', function() { $(this).isValid(settings.validators); }) - // Inputs for confirmations - .end().find('[id*=_confirmation]').each(function() { - var confirmationElement = $(this), - element = form.find('#' + this.id.match(/(.+)_confirmation/)[1] + '[data-validate]:input'); - - if (element[0]) { - $('#' + confirmationElement.attr('id')) - .live('focusout', function() { - element.data('changed', true).isValid(settings.validators); - }) - .live('keyup', function() { - element.data('changed', true).isValid(settings.validators); - }) - } - }); - - var addError = function(element, message) { - clientSideValidations.formBuilders[settings.type].add(element, settings, message); - } - - var removeError = function(element) { - clientSideValidations.formBuilders[settings.type].remove(element, settings); - } - }); - } - - $.fn.isValid = function(validators) { - if ($(this[0]).is('form')) { - return validateForm($(this[0]), validators); - } else { - return validateElement($(this[0]), validators[this[0].name]); - } - } - - var validateForm = function(form, validators) { - var valid = true; - - form.trigger('form:validate:before').find('[data-validate]:input').each(function() { - if (!$(this).isValid(validators)) { valid = false; } - }); - - if (valid) { - form.trigger('form:validate:pass'); - } else { - form.trigger('form:validate:fail'); - } - - form.trigger('form:validate:after'); - return valid; - } - - var validateElement = function(element, validators) { - element.trigger('element:validate:before'); - - if (element.data('changed') !== false) { - var valid = true; - element.data('changed', false); - - // Because 'length' is defined on the list of validators we cannot call jQuery.each on - // the clientSideValidations.validators.all() object - for (kind in clientSideValidations.validators.all()) { - if (validators[kind] && (message = clientSideValidations.validators.all()[kind](element, validators[kind]))) { - element.trigger('element:validate:fail', message).data('valid', false); - valid = false; - break; - } - } - - if (valid) { element.data('valid', null); element.trigger('element:validate:pass'); } - } - - element.trigger('element:validate:after'); - return element.data('valid') === false ? false : true; - } - - // Main hook - // If new forms are dynamically introduced into the DOM the .validate() method - // must be invoked on that form - $(function() { $('form[data-validate]').validate(); }) -})(jQuery); - -var clientSideValidations = { - validators: { - all: function() { return jQuery.extend({}, clientSideValidations.validators.local, clientSideValidations.validators.remote) }, - local: { - presence: function(element, options) { - if (/^\s*$/.test(element.val() || "")) { - return options.message; - } - }, - acceptance: function(element, options) { - switch (element.attr('type')) { - case 'checkbox': - if (!element.attr('checked')) { - return options.message; - } - break; - case 'text': - if (element.val() != (options.accept || '1')) { - return options.message; - } - break; - } - }, - format: function(element, options) { - if ((message = this.presence(element, options)) && options.allow_blank == true) { - return; - } else if (message) { - return message; - } else { - if (options['with'] && !options['with'].test(element.val())) { - return options.message; - } else if (options['without'] && options['without'].test(element.val())) { - return options.message; - } - } - }, - numericality: function(element, options) { - if (!/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d*)?$/.test(element.val())) { - return options.messages.numericality; - } - - if (options.only_integer && !/^\d+$/.test(element.val())) { - return options.messages.only_integer; - } - - var CHECKS = { greater_than: '>', greater_than_or_equal_to: '>=', - equal_to: '==', less_than: '<', less_than_or_equal_to: '<=' } - - for (var check in CHECKS) { - if (options[check] != undefined && !(new Function("return " + element.val() + CHECKS[check] + options[check])())) { - return options.messages[check]; - } - } - - if (options.odd && !(parseInt(element.val()) % 2)) { - return options.messages.odd; - } - - if (options.even && (parseInt(element.val()) % 2)) { - return options.messages.even; - } - }, - length: function(element, options) { - var blankOptions = {}; - if (options.is) { - blankOptions.message = options.messages.is; - } else if (options.minimum) { - blankOptions.message = options.messages.minimum; - } - if ((message = this.presence(element, blankOptions)) && options.allow_blank == true) { - return; - } else if (message) { - return message; - } else { - var CHECKS = { is: '==', minimum: '>=', maximum: '<=' } - var tokenizer = options.js_tokenizer || "split('')"; - var tokenized_length = new Function("element", "return (element.val()." + tokenizer + " || '').length;")(element); - - for (var check in CHECKS) { - if (options[check] && !(new Function("return " + tokenized_length + CHECKS[check] + options[check])())) { - return options.messages[check]; - } - } - } - }, - exclusion: function(element, options) { - if ((message = this.presence(element, options)) && options.allow_blank == true) { - return; - } else if (message) { - return message; - } else { - if (options['in']) { - for (var i = 0; i < options['in'].length; i++) { - if (options['in'][i] == element.val()) { - return options.message; - } - } - } else if (options['range']) { - var lower = options['range'][0], - upper = options['range'][1]; - if (element.val() >= lower && element.val() <= upper) { - return options.message; - } - } - } - }, - inclusion: function(element, options) { - if ((message = this.presence(element, options)) && options.allow_blank == true) { - return; - } else if (message) { - return message; - } else { - if (options['in']) { - for (var i = 0; i < options['in'].length; i++) { - if (options['in'][i] == element.val()) { - return; - } - } - return options.message; - } else if (options['range']) { - var lower = options['range'][0], - upper = options['range'][1]; - - if (element.val() >= lower && element.val() <= upper) { - return; - } else { - return options.message; - } - } - } - }, - confirmation: function(element, options) { - if (element.val() != jQuery('#' + element.attr('id') + '_confirmation').val()) { - return options.message; - } - } - }, - remote: { - uniqueness: function(element, options) { - var data = {}; - data['case_sensitive'] = !!options.case_sensitive; - if (options.id) { - data['id'] = options.id; - } - - if (options.scope) { - data.scope = {} - for (key in options.scope) { - var scoped_element = jQuery('[name="' + element.attr('name').replace(/\[\w+]$/, '[' + key + ']' + '"]')); - if (scoped_element[0] && scoped_element.val() != options.scope[key]) { - data.scope[key] = scoped_element.val(); - scoped_element.unbind('change.' + element.id).bind('change.' + element.id, function() { element.trigger('change'); element.trigger('focusout'); }); - } else { - data.scope[key] = options.scope[key]; - } - } - } - - // Kind of a hack but this will isolate the resource name and attribute. - // e.g. user[records_attributes][0][title] => records[title] - // e.g. user[record_attributes][title] => record[title] - // Server side handles classifying the resource properly - if (/_attributes]/.test(element.attr('name'))) { - var name = element.attr('name').match(/\[\w+_attributes]/g).pop().match(/\[(\w+)_attributes]/).pop(); - name += /(\[\w+])$/.exec(element.attr('name'))[1]; - } else { - var name = element.attr('name'); - } - - // Override the name if a nested module class is passed - if (options['class']) { - name = options['class'] + '[' + name.split('[')[1] - } - data[name] = element.val(); - - if (jQuery.ajax({ - url: '/validators/uniqueness', - data: data, - async: false - }).status == 200) { - return options.message; - } - } - } - }, - formBuilders: { - 'ActionView::Helpers::FormBuilder': { - add: function(element, settings, message) { - if (element.data('valid') !== false && jQuery('label.message[for="' + element.attr('id') + '"]')[0] == undefined) { - var inputErrorField = jQuery(settings.input_tag), - labelErrorField = jQuery(settings.label_tag), - label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)'); - - if (element.attr('autofocus')) { element.attr('autofocus', false) }; - element.before(inputErrorField); - inputErrorField.find('span#input_tag').replaceWith(element); - inputErrorField.find('label.message').attr('for', element.attr('id')); - labelErrorField.find('label.message').attr('for', element.attr('id')); - label.replaceWith(labelErrorField); - labelErrorField.find('label#label_tag').replaceWith(label); - } - jQuery('label.message[for="' + element.attr('id') + '"]').text(message); - }, - remove: function(element, settings) { - var errorFieldClass = jQuery(settings.input_tag).attr('class'), - inputErrorField = element.closest('.' + errorFieldClass), - label = jQuery('label[for="' + element.attr('id') + '"]:not(.message)'), - labelErrorField = label.closest('.' + errorFieldClass); - - if (inputErrorField[0]) { - inputErrorField.find('#' + element.attr('id')).detach(); - inputErrorField.replaceWith(element); - label.detach(); - labelErrorField.replaceWith(label); - } - } - }, - 'SimpleForm::FormBuilder': { - add: function(element, settings, message) { - if (element.data('valid') !== false) { - var wrapper = element.closest(settings.wrapper_tag); - wrapper.addClass(settings.wrapper_error_class); - var errorElement = $('<' + settings.error_tag + ' class="' + settings.error_class + '">' + message + ''); - wrapper.append(errorElement); - } else { - element.parent().find(settings.error_tag + '.' + settings.error_class).text(message); - } - }, - remove: function(element, settings) { - var wrapper = element.closest(settings.wrapper_tag + '.' + settings.wrapper_error_class); - wrapper.removeClass(settings.wrapper_error_class); - var errorElement = wrapper.find(settings.error_tag + '.' + settings.error_class); - errorElement.remove(); - } - - }, - 'Formtastic::FormBuilder': { - add: function(element, settings, message) { - if (element.data('valid') !== false) { - var wrapper = element.closest('li'); - wrapper.addClass('error'); - var errorElement = $('

' + message + '

'); - wrapper.append(errorElement); - } else { - element.parent().find('p.' + settings.inline_error_class).text(message); - } - }, - remove: function(element, settings) { - var wrapper = element.closest('li.error'); - wrapper.removeClass('error'); - var errorElement = wrapper.find('p.' + settings.inline_error_class); - errorElement.remove(); - } - }, - 'NestedForm::Builder': { - add: function(element, settings, message) { - clientSideValidations.formBuilders['ActionView::Helpers::FormBuilder'].add(element, settings, message); - }, - remove: function(element, settings, message) { - clientSideValidations.formBuilders['ActionView::Helpers::FormBuilder'].remove(element, settings, message); - } - } - }, - callbacks: { - element: { - after: function(element, eventData) { }, - before: function(element, eventData) { }, - fail: function(element, message, addError, eventData) { addError() }, - pass: function(element, removeError, eventData) { removeError() } - }, - form: { - after: function(form, eventData) { }, - before: function(form, eventData) { }, - fail: function(form, eventData) { }, - pass: function(form, eventData) { } - } - } -}; From 97ede99c0fa6bd931c1a943d4c732e077754d111 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 11 Jan 2014 17:59:15 -0200 Subject: [PATCH 09/20] #toggle was removed --- .../javascripts/widgets/notifications-badge.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/widgets/notifications-badge.js b/app/assets/javascripts/widgets/notifications-badge.js index 1f60bc794..b70868891 100644 --- a/app/assets/javascripts/widgets/notifications-badge.js +++ b/app/assets/javascripts/widgets/notifications-badge.js @@ -13,7 +13,15 @@ }); if( ! $.browser.msie ) { - self.badgeLink.toggle(self.showDropdown, self.hideDropdown); + self.badge.on('click', self.badgeLink, function(evt){ + evt.preventDefault(); + evt.stopPropagation(); + if (self.dropdownShowing()){ + self.hideDropdown(); + } else { + self.showDropdown(); + } + }); } self.dropdown.click(function(evt) { @@ -32,9 +40,7 @@ return this.dropdown.css("display") === "block"; }; - this.showDropdown = function(evt) { - evt.preventDefault(); - + this.showDropdown = function() { self.ajaxLoader.show(); self.badge.addClass("active"); self.dropdown.css("display", "block"); @@ -42,9 +48,7 @@ self.getNotifications(); }; - this.hideDropdown = function(evt) { - evt.preventDefault(); - + this.hideDropdown = function() { self.badge.removeClass("active"); self.dropdown.css("display", "none"); }; From f0ae80b82f14aed98ab4afb6f138cec08b0f3abb Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sun, 12 Jan 2014 20:43:49 -0200 Subject: [PATCH 10/20] add browser detection --- app/assets/javascripts/browser_detection.js | 5 +++++ app/assets/javascripts/main.js | 1 + 2 files changed, 6 insertions(+) create mode 100644 app/assets/javascripts/browser_detection.js diff --git a/app/assets/javascripts/browser_detection.js b/app/assets/javascripts/browser_detection.js new file mode 100644 index 000000000..9387c379f --- /dev/null +++ b/app/assets/javascripts/browser_detection.js @@ -0,0 +1,5 @@ +jQuery.browser = {}; +jQuery.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase()); +jQuery.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase()); +jQuery.browser.opera = /opera/.test(navigator.userAgent.toLowerCase()); +jQuery.browser.msie = /msie/.test(navigator.userAgent.toLowerCase()); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 9c73b198c..a17df7c4a 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -11,6 +11,7 @@ //= require jquery.placeholder //= require rails-timeago //= require facebox +//= require browser_detection //= require jquery.events.input //= require jquery.elastic //= require jquery.mentionsInput From 5aa86a5def3f19060b78387cab21a2f32cc93190 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sun, 12 Jan 2014 20:44:23 -0200 Subject: [PATCH 11/20] fix infinitescroll in contacts pages --- vendor/assets/javascripts/jquery.infinitescroll-custom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/assets/javascripts/jquery.infinitescroll-custom.js b/vendor/assets/javascripts/jquery.infinitescroll-custom.js index 7e5c70fc0..d9f521892 100644 --- a/vendor/assets/javascripts/jquery.infinitescroll-custom.js +++ b/vendor/assets/javascripts/jquery.infinitescroll-custom.js @@ -608,7 +608,7 @@ if (scrollTimeout) { clearTimeout(scrollTimeout); } scrollTimeout = setTimeout(function() { - jQuery.event.handle.apply( context, args ); + jQuery.event.dispatch.apply( context, args ); }, execAsap === "execAsap"? 0 : 100); } }; From b27edcb2d1b06eeaf0e29950f86952ae89dfa862 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sun, 16 Feb 2014 14:12:33 +0100 Subject: [PATCH 12/20] fix search specs --- .../javascripts/app/views/header_view.js | 9 ++++- .../javascripts/app/views/header_view_spec.js | 24 +++++++++++++ spec/javascripts/view-spec.js | 34 ------------------- spec/javascripts/widgets/i18n-spec.js | 2 +- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/app/assets/javascripts/app/views/header_view.js b/app/assets/javascripts/app/views/header_view.js index b1ed5151f..bb0643e75 100644 --- a/app/assets/javascripts/app/views/header_view.js +++ b/app/assets/javascripts/app/views/header_view.js @@ -5,7 +5,9 @@ app.views.Header = app.views.Base.extend({ className : "dark-header", events : { - "click ul.dropdown li:first-child" : "toggleDropdown" + "click ul.dropdown li:first-child" : "toggleDropdown", + "focus #q": "toggleSearchActive", + "blur #q": "toggleSearchActive" }, initialize : function(options) { @@ -31,5 +33,10 @@ app.views.Header = app.views.Base.extend({ if(this.menuElement().hasClass("active") && !$(evt.target).parents("#user_menu").length) { this.menuElement().removeClass("active"); } + }, + + toggleSearchActive: function(ev) { + $(ev.target).toggleClass('active', ev.type=='focusin'); + return false; } }); diff --git a/spec/javascripts/app/views/header_view_spec.js b/spec/javascripts/app/views/header_view_spec.js index f8825a2e6..7ed99fe70 100644 --- a/spec/javascripts/app/views/header_view_spec.js +++ b/spec/javascripts/app/views/header_view_spec.js @@ -71,4 +71,28 @@ describe("app.views.Header", function() { expect(this.view.$(".dropdown")).not.toHaveClass("active"); }); }); + + + describe("search", function() { + var input; + + beforeEach(function() { + $('#jasmine_content').html(this.view.el); + input = $(this.view.el).find('#q'); + }); + + describe("focus", function() { + it("adds the class 'active' when the user focuses the text field", function() { + input.trigger('focus'); + expect(input).toHaveClass("active"); + }); + }); + + describe("blur", function() { + it("removes the class 'active' when the user blurs the text field", function() { + input.focus().blur(); + expect(input).not.toHaveClass("active"); + }); + }); + }); }); diff --git a/spec/javascripts/view-spec.js b/spec/javascripts/view-spec.js index 1a2dd9277..5542b8fae 100644 --- a/spec/javascripts/view-spec.js +++ b/spec/javascripts/view-spec.js @@ -7,38 +7,4 @@ describe("View", function() { it("is the object that helps the UI", function() { expect(typeof View === "object").toBeTruthy(); }); - - describe("publisher", function() { - beforeEach(function() { - $("#jasmine_content").html( - '
' + - '
' + - '' + - '
' + - '
' - ); - }); - }); - - describe("search", function() { - beforeEach(function() { - $("#jasmine_content").html( - '' - ); - }); - describe("focus", function() { - it("adds the class 'active' when the user focuses the text field", function() { - View.initialize(); - $(View.search.selector).focus(); - expect($(View.search.selector)).toHaveClass("active"); - }); - }); - describe("blur", function() { - it("removes the class 'active' when the user blurs the text field", function() { - View.initialize(); - $(View.search.selector).focus().blur(); - expect($(View.search.selector)).not.toHaveClass("active"); - }); - }); - }); }); diff --git a/spec/javascripts/widgets/i18n-spec.js b/spec/javascripts/widgets/i18n-spec.js index f48a96107..8740a5dee 100644 --- a/spec/javascripts/widgets/i18n-spec.js +++ b/spec/javascripts/widgets/i18n-spec.js @@ -34,7 +34,7 @@ describe("Diaspora", function() { extended = $.extend(locale, data); Diaspora.I18n.loadLocale(locale); - Diaspora.I18n.loadLocale(data; + Diaspora.I18n.loadLocale(data); expect(Diaspora.I18n.locale).toEqual(extended); }); From e3b22ed95ce97e1314cdad485533bc43b9a55b88 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Mon, 17 Feb 2014 23:32:09 +0100 Subject: [PATCH 13/20] fix likes spec --- app/assets/javascripts/app/views/likes_info_view.js | 2 +- spec/javascripts/app/views/header_view_spec.js | 2 +- spec/javascripts/app/views/stream_post_spec.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/app/views/likes_info_view.js b/app/assets/javascripts/app/views/likes_info_view.js index bd8b45ac4..737b82792 100644 --- a/app/assets/javascripts/app/views/likes_info_view.js +++ b/app/assets/javascripts/app/views/likes_info_view.js @@ -9,7 +9,7 @@ app.views.LikesInfo = app.views.Base.extend({ tooltipSelector : ".avatar", initialize : function() { - this.model.interactions.bind('change', this.render, this) + this.model.interactions.bind('change', this.render, this); }, presenter : function() { diff --git a/spec/javascripts/app/views/header_view_spec.js b/spec/javascripts/app/views/header_view_spec.js index 7ed99fe70..8535464ad 100644 --- a/spec/javascripts/app/views/header_view_spec.js +++ b/spec/javascripts/app/views/header_view_spec.js @@ -90,7 +90,7 @@ describe("app.views.Header", function() { describe("blur", function() { it("removes the class 'active' when the user blurs the text field", function() { - input.focus().blur(); + input.trigger('focus').trigger('blur'); expect(input).not.toHaveClass("active"); }); }); diff --git a/spec/javascripts/app/views/stream_post_spec.js b/spec/javascripts/app/views/stream_post_spec.js index dd782ba6a..d6459dfde 100644 --- a/spec/javascripts/app/views/stream_post_spec.js +++ b/spec/javascripts/app/views/stream_post_spec.js @@ -58,13 +58,13 @@ describe("app.views.StreamPost", function(){ context("likes", function(){ it("displays a like count", function(){ - this.statusMessage.set({likes_count : 1}) + this.statusMessage.interactions.set({likes_count : 1}) var view = new this.PostViewClass({model : this.statusMessage}).render(); expect($(view.el).html()).toContain(Diaspora.I18n.t('stream.likes', {count: 1})) }) it("does not display a like count for 'zero'", function(){ - this.statusMessage.set({likes_count : 0}) + this.statusMessage.interactions.set({likes_count : 0}) var view = new this.PostViewClass({model : this.statusMessage}).render(); expect($(view.el).html()).not.toContain("0 Likes") From 69a1718d089985958620ffb8751edec8a2f4b1a7 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Tue, 18 Feb 2014 11:14:02 +0100 Subject: [PATCH 14/20] fix comment spec, jasmine should be ok now --- spec/javascripts/app/views/comment_stream_view_spec.js | 2 +- spec/javascripts/app/views/header_view_spec.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/spec/javascripts/app/views/comment_stream_view_spec.js b/spec/javascripts/app/views/comment_stream_view_spec.js index 22b2db68d..e9b1750cf 100644 --- a/spec/javascripts/app/views/comment_stream_view_spec.js +++ b/spec/javascripts/app/views/comment_stream_view_spec.js @@ -53,7 +53,7 @@ describe("app.views.CommentStream", function(){ }); it("adds the comment to the view", function() { - this.request.response({status: 200}); + this.request.response({status: 200, responseText: '[]'}); expect(this.view.$(".comment-content p").text()).toEqual("a new comment"); }); diff --git a/spec/javascripts/app/views/header_view_spec.js b/spec/javascripts/app/views/header_view_spec.js index 8535464ad..39778c436 100644 --- a/spec/javascripts/app/views/header_view_spec.js +++ b/spec/javascripts/app/views/header_view_spec.js @@ -84,7 +84,12 @@ describe("app.views.Header", function() { describe("focus", function() { it("adds the class 'active' when the user focuses the text field", function() { input.trigger('focus'); - expect(input).toHaveClass("active"); + waitsFor(function() { + return input.is('.active'); + }); + runs(function() { + expect(input).toHaveClass("active"); + }); }); }); From b0502ef07ee11f2be659e75568a5390adc8988e5 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Tue, 18 Feb 2014 12:48:23 +0100 Subject: [PATCH 15/20] don't depend on the order of events (focus has two variants in jQuery) --- app/assets/javascripts/app/views/header_view.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/app/views/header_view.js b/app/assets/javascripts/app/views/header_view.js index bb0643e75..821ec468d 100644 --- a/app/assets/javascripts/app/views/header_view.js +++ b/app/assets/javascripts/app/views/header_view.js @@ -36,7 +36,10 @@ app.views.Header = app.views.Base.extend({ }, toggleSearchActive: function(ev) { - $(ev.target).toggleClass('active', ev.type=='focusin'); + // jQuery produces two events for focus/blur (for bubbling) + // don't rely on which event arrives first, by allowing for both variants + var is_active = (_.indexOf(['focus','focusin'], ev.type) != -1); + $(ev.target).toggleClass('active', is_active); return false; } }); From dc1c15617575ed2f744c47a2afb12df722903fc2 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Tue, 18 Feb 2014 15:47:18 +0100 Subject: [PATCH 16/20] try to appease CI --- app/assets/javascripts/app/views/header_view.js | 4 ++-- spec/javascripts/app/views/header_view_spec.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/app/views/header_view.js b/app/assets/javascripts/app/views/header_view.js index 821ec468d..db55694cc 100644 --- a/app/assets/javascripts/app/views/header_view.js +++ b/app/assets/javascripts/app/views/header_view.js @@ -6,8 +6,8 @@ app.views.Header = app.views.Base.extend({ events : { "click ul.dropdown li:first-child" : "toggleDropdown", - "focus #q": "toggleSearchActive", - "blur #q": "toggleSearchActive" + "focusin #q": "toggleSearchActive", + "focusout #q": "toggleSearchActive" }, initialize : function(options) { diff --git a/spec/javascripts/app/views/header_view_spec.js b/spec/javascripts/app/views/header_view_spec.js index 39778c436..3b8d76ca0 100644 --- a/spec/javascripts/app/views/header_view_spec.js +++ b/spec/javascripts/app/views/header_view_spec.js @@ -83,7 +83,7 @@ describe("app.views.Header", function() { describe("focus", function() { it("adds the class 'active' when the user focuses the text field", function() { - input.trigger('focus'); + input.trigger('focusin'); waitsFor(function() { return input.is('.active'); }); @@ -95,7 +95,7 @@ describe("app.views.Header", function() { describe("blur", function() { it("removes the class 'active' when the user blurs the text field", function() { - input.trigger('focus').trigger('blur'); + input.trigger('focusin').trigger('focusout'); expect(input).not.toHaveClass("active"); }); }); From 061ae52e4d5fc10c2ac63895cb18cb2d6129df22 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Fri, 21 Feb 2014 11:28:28 +0100 Subject: [PATCH 17/20] captcha needs to be present, but can be bogus in test ENV --- features/desktop/signs_up.feature | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/features/desktop/signs_up.feature b/features/desktop/signs_up.feature index 5839d5cf9..d6f9213b5 100644 --- a/features/desktop/signs_up.feature +++ b/features/desktop/signs_up.feature @@ -4,10 +4,11 @@ Feature: new user registration Background: When I go to the new user registration page And I fill in the following: - | user_username | ohai | - | user_email | ohai@example.com | - | user_password | secret | - | user_password_confirmation | secret | + | user_username | ohai | + | user_email | ohai@example.com | + | user_password | secret | + | user_password_confirmation | secret | + | user_captcha | 123456 | And I press "Continue" Then I should be on the getting started page And I should see "Well, hello there!" and "Who are you?" and "What are you into?" From e2adaa07a29b59d06181ba6bf81da5ce764c3bf4 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 22 Feb 2014 00:37:05 +0100 Subject: [PATCH 18/20] should fix remaining failing cukes from captcha and removal of client-side-validations gem --- features/desktop/accepts_invitation.feature | 12 ++---------- features/desktop/signs_up.feature | 16 +++++++--------- features/mobile/getting_started.feature | 6 +----- features/step_definitions/custom_web_steps.rb | 4 ++++ features/step_definitions/session_steps.rb | 4 ++++ features/step_definitions/user_steps.rb | 5 +---- features/step_definitions/web_steps.rb | 3 +-- features/support/application_cuke_helpers.rb | 12 ++++++++++++ features/support/paths.rb | 5 +++++ features/support/user_cuke_helpers.rb | 15 +++++++++++++++ 10 files changed, 52 insertions(+), 30 deletions(-) diff --git a/features/desktop/accepts_invitation.feature b/features/desktop/accepts_invitation.feature index 1be46c6f2..330b58d76 100644 --- a/features/desktop/accepts_invitation.feature +++ b/features/desktop/accepts_invitation.feature @@ -3,11 +3,7 @@ Feature: invitation acceptance Scenario: accept invitation from admin Given I have been invited by an admin And I am on my acceptance form page - And I fill in the following: - | user_username | ohai | - | user_email | woot@sweet.com | - | user_password | secret | - | user_password_confirmation | secret | + And I fill in the new user form And I press "Continue" Then I should be on the getting started page And I should see "Well, hello there!" @@ -21,11 +17,7 @@ Feature: invitation acceptance Scenario: accept invitation from user Given I have been invited by bob And I am on my acceptance form page - And I fill in the following: - | user_username | ohai | - | user_email | woot@sweet.com | - | user_password | secret | - | user_password_confirmation | secret | + And I fill in the new user form And I press "Continue" Then I should be on the getting started page And I should see "Well, hello there!" diff --git a/features/desktop/signs_up.feature b/features/desktop/signs_up.feature index d6f9213b5..606fee713 100644 --- a/features/desktop/signs_up.feature +++ b/features/desktop/signs_up.feature @@ -3,12 +3,7 @@ Feature: new user registration Background: When I go to the new user registration page - And I fill in the following: - | user_username | ohai | - | user_email | ohai@example.com | - | user_password | secret | - | user_password_confirmation | secret | - | user_captcha | 123456 | + And I fill in the new user form And I press "Continue" Then I should be on the getting started page And I should see "Well, hello there!" and "Who are you?" and "What are you into?" @@ -52,16 +47,19 @@ Feature: new user registration And I fill in the following: | user_username | $%&(/&%$&/=)(/ | And I press "Continue" - Then I should see a flash message containing "Email can't be blank - Password can't be blank - Username is invalid." + Then I should not be able to sign up + And I should have a validation error on "user_username, user_password, user_email" When I fill in the following: | user_username | valid_user | | user_email | this is not a valid email $%&/()( | And I press "Continue" - Then I should see a flash message containing "Email is invalid - Password can't be blank" + Then I should not be able to sign up + And I should have a validation error on "user_password, user_email" When I fill in the following: | user_email | valid@email.com | | user_password | 1 | And I press "Continue" - Then I should see a flash message containing "Password doesn't match confirmation - Password is too short (minimum is 6 characters)" + Then I should not be able to sign up + And I should have a validation error on "user_password, user_password_confirmation" diff --git a/features/mobile/getting_started.feature b/features/mobile/getting_started.feature index 4eadd6b63..7dc61e204 100644 --- a/features/mobile/getting_started.feature +++ b/features/mobile/getting_started.feature @@ -3,11 +3,7 @@ Feature: editing the gettig started in the mobile view Scenario: editing gettig started fields When I go to the new user registration page - And I fill in the following: - | user_username | amparito | - | user_email | amp@arito.com | - | user_password | secret | - | user_password_confirmation | secret | + And I fill in the new user form And I press "Continue" And I visit the mobile getting started page And I should see "Well, hello there!" and "Who are you?" and "What are you into?" diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index bab1c44ec..0954c57d1 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -277,3 +277,7 @@ Given /^"([^"]*)" is hidden$/ do |selector| page.should have_selector(selector, visible: false) page.should_not have_selector(selector) end + +Then(/^I should have a validation error on "(.*?)"$/) do |field_list| + check_fields_validation_error field_list +end diff --git a/features/step_definitions/session_steps.rb b/features/step_definitions/session_steps.rb index 6b590e34c..67921bc0a 100644 --- a/features/step_definitions/session_steps.rb +++ b/features/step_definitions/session_steps.rb @@ -58,3 +58,7 @@ end When /^I (?:log|sign) out manually$/ do manual_logout end + +Then(/^I should not be able to sign up$/) do + confirm_not_signed_up +end diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb index 018949cb6..89f49be03 100644 --- a/features/step_definitions/user_steps.rb +++ b/features/step_definitions/user_steps.rb @@ -206,10 +206,7 @@ Given /^I visit alice's invitation code url$/ do end When /^I fill in the new user form$/ do - step 'I fill in "user_username" with "ohai"' - step 'I fill in "user_email" with "ohai@example.com"' - step 'I fill in "user_password" with "secret"' - step 'I fill in "user_password_confirmation" with "secret"' + fill_in_new_user_form end And /^I should be able to friend Alice$/ do diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index fa718fe41..49f20ddc2 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -169,8 +169,7 @@ Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do | end Then /^(?:|I )should be on (.+)$/ do |page_name| - current_path = URI.parse(current_url).path - current_path.should == path_to(page_name) + confirm_on_page(page_name) end Then /^(?:|I )should have the following query string:$/ do |expected_pairs| diff --git a/features/support/application_cuke_helpers.rb b/features/support/application_cuke_helpers.rb index b7a3b1b35..f2ddb417f 100644 --- a/features/support/application_cuke_helpers.rb +++ b/features/support/application_cuke_helpers.rb @@ -16,6 +16,18 @@ module ApplicationCukeHelpers selector &&= "#flash_#{selector}" find(selector || '.message', {match: :first}.merge(opts)) end + + def confirm_form_validation_error(element) + is_invalid = page.evaluate_script("$('#{element}').is(':invalid')") + is_invalid.should be_true + end + + def check_fields_validation_error(field_list) + field_list.split(',').each do |f| + confirm_form_validation_error('input#'+f.strip) + end + end + end World(ApplicationCukeHelpers) diff --git a/features/support/paths.rb b/features/support/paths.rb index c5d7756bd..1b2fa1790 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -65,6 +65,11 @@ module NavigationHelpers find(await_elem.delete(:selector), await_elem) end end + + def confirm_on_page(page_name) + current_path = URI.parse(current_url).path + current_path.should == path_to(page_name) + end end World(NavigationHelpers) diff --git a/features/support/user_cuke_helpers.rb b/features/support/user_cuke_helpers.rb index 0dc9f0a87..d22185b0a 100644 --- a/features/support/user_cuke_helpers.rb +++ b/features/support/user_cuke_helpers.rb @@ -59,6 +59,17 @@ module UserCukeHelpers find("#user_menu li:last-child a").click end + def fill_in_new_user_form + fill_in('user_username', with: 'ohai') + fill_in('user_email', with: 'ohai@example.com') + fill_in('user_password', with: 'secret') + fill_in('user_password_confirmation', with: 'secret') + + # captcha needs to be filled out, because the field is required (HTML5) + # in test env, the captcha will always pass successfully + fill_in('user_captcha', with: '123456') + end + # fill change password section on the user edit page def fill_change_password_section(cur_pass, new_pass, confirm_pass) fill_in 'user_current_password', :with => cur_pass @@ -87,6 +98,10 @@ module UserCukeHelpers find(".button").click end + def confirm_not_signed_up + confirm_on_page('the new user registration page') + confirm_form_validation_error('form#new_user') + end end World(UserCukeHelpers) From 1f98e1c639a5f1f91329e32c00a2967db692e906 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 22 Feb 2014 14:01:49 +0100 Subject: [PATCH 19/20] cleanup 'getting started' cukes a bit --- features/desktop/signs_up.feature | 2 +- features/mobile/getting_started.feature | 3 +-- features/step_definitions/session_steps.rb | 4 ++++ features/support/user_cuke_helpers.rb | 14 ++++++++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/features/desktop/signs_up.feature b/features/desktop/signs_up.feature index 606fee713..93a07470d 100644 --- a/features/desktop/signs_up.feature +++ b/features/desktop/signs_up.feature @@ -6,7 +6,7 @@ Feature: new user registration And I fill in the new user form And I press "Continue" Then I should be on the getting started page - And I should see "Well, hello there!" and "Who are you?" and "What are you into?" + Then I should see the 'getting started' contents Scenario: new user goes through the setup wizard When I fill in the following: diff --git a/features/mobile/getting_started.feature b/features/mobile/getting_started.feature index 7dc61e204..ad0bedd57 100644 --- a/features/mobile/getting_started.feature +++ b/features/mobile/getting_started.feature @@ -6,8 +6,7 @@ Feature: editing the gettig started in the mobile view And I fill in the new user form And I press "Continue" And I visit the mobile getting started page - And I should see "Well, hello there!" and "Who are you?" and "What are you into?" - And I should see "amparito" + Then I should see the 'getting started' contents When I attach the file "spec/fixtures/bad_urls.txt" to "file" within "#file-upload" And I confirm the alert diff --git a/features/step_definitions/session_steps.rb b/features/step_definitions/session_steps.rb index 67921bc0a..1679e4506 100644 --- a/features/step_definitions/session_steps.rb +++ b/features/step_definitions/session_steps.rb @@ -62,3 +62,7 @@ end Then(/^I should not be able to sign up$/) do confirm_not_signed_up end + +Then (/^I should see the 'getting started' contents$/) do + confirm_getting_started_contents +end diff --git a/features/support/user_cuke_helpers.rb b/features/support/user_cuke_helpers.rb index d22185b0a..497dcf87a 100644 --- a/features/support/user_cuke_helpers.rb +++ b/features/support/user_cuke_helpers.rb @@ -60,8 +60,9 @@ module UserCukeHelpers end def fill_in_new_user_form - fill_in('user_username', with: 'ohai') - fill_in('user_email', with: 'ohai@example.com') + @username = "ohai" + fill_in('user_username', with: @username) + fill_in('user_email', with: "#{@username}@example.com") fill_in('user_password', with: 'secret') fill_in('user_password_confirmation', with: 'secret') @@ -102,6 +103,15 @@ module UserCukeHelpers confirm_on_page('the new user registration page') confirm_form_validation_error('form#new_user') end + + def confirm_getting_started_contents + page.should have_content("Well, hello there!") + page.should have_content("Who are you?") + page.should have_content("What are you into?") + + # the username that was just entered for registration + page.should have_content(@username) + end end World(UserCukeHelpers) From a2aff720a25b882444a0de18d582c4a096ab67c0 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sun, 23 Feb 2014 17:13:01 +0100 Subject: [PATCH 20/20] clear locale on each spec run, fix indentation --- app/assets/javascripts/helpers/i18n.js | 36 +++++--- spec/javascripts/widgets/i18n-spec.js | 113 ++++++++++++++----------- 2 files changed, 86 insertions(+), 63 deletions(-) diff --git a/app/assets/javascripts/helpers/i18n.js b/app/assets/javascripts/helpers/i18n.js index f675e9624..0ece8f53b 100644 --- a/app/assets/javascripts/helpers/i18n.js +++ b/app/assets/javascripts/helpers/i18n.js @@ -2,20 +2,21 @@ * licensed under the Affero General Public License version 3 or later. See * the COPYRIGHT file. */ - Diaspora.I18n = { - language: "en", - locale: {}, - loadLocale: function(locale, language) { - this.locale = $.extend(this.locale, locale); - this.language = language; - rule = this.t('pluralization_rule'); - if (rule === "") - rule = 'function (n) { return n == 1 ? "one" : "other" }'; - eval("this.pluralizationKey = "+rule); - }, +Diaspora.I18n = { + language: "en", + locale: {}, - t: function(item, views) { + loadLocale: function(locale, language) { + this.locale = $.extend(this.locale, locale); + this.language = language; + rule = this.t('pluralization_rule'); + if (rule === "") + rule = 'function (n) { return n == 1 ? "one" : "other" }'; + eval("this.pluralizationKey = "+rule); + }, + + t: function(item, views) { var items = item.split("."), translatedMessage, nextNamespace; @@ -35,5 +36,12 @@ } return _.template(translatedMessage, views || {}); - } - }; + }, + + reset: function() { + this.locale = {}; + + if( arguments.length > 0 && !(_.isEmpty(arguments[0])) ) + this.locale = arguments[0]; + } +}; diff --git a/spec/javascripts/widgets/i18n-spec.js b/spec/javascripts/widgets/i18n-spec.js index 8740a5dee..7f51f5c76 100644 --- a/spec/javascripts/widgets/i18n-spec.js +++ b/spec/javascripts/widgets/i18n-spec.js @@ -3,69 +3,84 @@ * the COPYRIGHT file. */ -describe("Diaspora", function() { - describe("widgets", function() { - describe("i18n", function() { - var locale = {namespace: { - message: "hey", - template: "<%= myVar %>", - otherNamespace: { - message: "hello from another namespace", - otherMessage: { - zero: "none", - one: "just one", - few: "just a few", - many: "way too many", - other: "what?" - } - } +describe("Diaspora.I18n", function() { + var locale = {namespace: { + message: "hey", + template: "<%= myVar %>", + otherNamespace: { + message: "hello from another namespace", + otherMessage: { + zero: "none", + one: "just one", + few: "just a few", + many: "way too many", + other: "what?" } - }; + } + } + }; - describe("loadLocale", function() { - it("sets the class's locale variable", function() { - Diaspora.I18n.loadLocale(locale); + beforeEach(function(){ + Diaspora.I18n.reset(); // run tests with clean locale + }); - expect(Diaspora.I18n.locale).toEqual(locale); - }); + describe("::loadLocale", function() { + it("sets the class's locale variable", function() { + Diaspora.I18n.loadLocale(locale); - it("extends the class's locale variable on multiple calls", function() { - var data = {another: 'section'}, - extended = $.extend(locale, data); + expect(Diaspora.I18n.locale).toEqual(locale); + }); - Diaspora.I18n.loadLocale(locale); - Diaspora.I18n.loadLocale(data); + it("extends the class's locale variable on multiple calls", function() { + var data = {another: 'section'}, + extended = $.extend(locale, data); - expect(Diaspora.I18n.locale).toEqual(extended); - }); - }); + Diaspora.I18n.loadLocale(locale); + Diaspora.I18n.loadLocale(data); - describe("t", function() { - var translation; - beforeEach(function() { Diaspora.I18n.loadLocale(locale); }); + expect(Diaspora.I18n.locale).toEqual(extended); + }); + }); - it("returns the specified translation", function() { - translation = Diaspora.I18n.t("namespace.message"); + describe("::t", function() { + var translation; + beforeEach(function() { Diaspora.I18n.loadLocale(locale); }); - expect(translation).toEqual("hey"); - }); + it("returns the specified translation", function() { + translation = Diaspora.I18n.t("namespace.message"); - it("will go through a infinitely deep object", function() { - translation = Diaspora.I18n.t("namespace.otherNamespace.message"); + expect(translation).toEqual("hey"); + }); - expect(translation).toEqual("hello from another namespace"); - }); + it("will go through a infinitely deep object", function() { + translation = Diaspora.I18n.t("namespace.otherNamespace.message"); - it("can render a mustache template", function() { - translation = Diaspora.I18n.t("namespace.template", { myVar: "it works!" }); + expect(translation).toEqual("hello from another namespace"); + }); - expect(translation).toEqual("it works!"); - }); + it("can render a mustache template", function() { + translation = Diaspora.I18n.t("namespace.template", { myVar: "it works!" }); - it("returns an empty string if the translation is not found", function() { - expect(Diaspora.I18n.t("missing.locale")).toEqual(""); - }); - }); + expect(translation).toEqual("it works!"); + }); + + it("returns an empty string if the translation is not found", function() { + expect(Diaspora.I18n.t("missing.locale")).toEqual(""); + }); + }); + + describe("::reset", function(){ + it("clears the current locale", function() { + Diaspora.I18n.loadLocale(locale); + Diaspora.I18n.reset() + expect(Diaspora.I18n.locale).toEqual({}); + }); + + it("sets the locale to only a specific value", function() { + var data = { some: 'value' }; + Diaspora.I18n.loadLocale(locale); + Diaspora.I18n.reset(data); + expect(Diaspora.I18n.locale).toEqual(data); }); }); });