diff --git a/.gitignore b/.gitignore index 7eccc46e1f6..31f0028dcb6 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,9 @@ tool-data/shared/ucsc/ucsc_build_sites.txt tool-data/*.loc tool-data/genome/* tool-data/*.sample +tool-data/testtoolshed.g2.bx.psu.edu/ +tool-data/toolshed.g2.bx.psu.edu/ + # Test output test-data-cache @@ -121,4 +124,3 @@ doc/build .DS_Store *.rej *~ - diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index cfa5f147908..01fc012adb2 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -32,6 +32,7 @@ The following individuals have contributed code to Galaxy: * Ira Cooke * Nate Coraor * Michael Cotterell +* Michael R. Crusoe * Gianmauro Cuccuru * Frederik Delaere * Olivia Doppelt diff --git a/client/galaxy/scripts/galaxy-app-base.js b/client/galaxy/scripts/galaxy-app-base.js index 5825ce743db..d5578099ae8 100644 --- a/client/galaxy/scripts/galaxy-app-base.js +++ b/client/galaxy/scripts/galaxy-app-base.js @@ -137,6 +137,10 @@ GalaxyApp.prototype._initLogger = function _initLogger( loggerOptions ){ } catch( storageErr ){} } self.logger = new metricsLogger.MetricsLogger( loggerOptions ); + self.emit = {}; + [ 'log', 'debug', 'info', 'warn', 'error', 'metric' ].map(function( i ) { + self.emit[ i ] = function( data ) { self.logger.emit( i, arguments[ 0 ], Array.prototype.slice.call( arguments, 1 ) ) }; + }); if( self.config.debug ){ // add this logger to mvc's loggable mixin so that all models can use the logger diff --git a/client/galaxy/scripts/libs/jquery/select2.js b/client/galaxy/scripts/libs/jquery/select2.js index 7116cd77288..1d31ce8f49d 100755 --- a/client/galaxy/scripts/libs/jquery/select2.js +++ b/client/galaxy/scripts/libs/jquery/select2.js @@ -2980,13 +2980,12 @@ the specific language governing permissions and limitations under the Apache Lic // keep track of the search's value before it gets cleared this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val()); - - this.clearSearch(); - this.updateResults(); - + this.moveHighlight(1); if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true); if (this.opts.closeOnSelect) { + this.clearSearch() + this.updateResults() this.close(); this.search.width(10); } else { diff --git a/client/galaxy/scripts/mvc/collection/list-of-pairs-collection-creator.js b/client/galaxy/scripts/mvc/collection/list-of-pairs-collection-creator.js index 8aa18778b37..6e14ae6f18b 100644 --- a/client/galaxy/scripts/mvc/collection/list-of-pairs-collection-creator.js +++ b/client/galaxy/scripts/mvc/collection/list-of-pairs-collection-creator.js @@ -393,8 +393,8 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte strategy = strategy || this.strategy; split = this._splitByFilters(); paired = paired.concat( this[ strategy ].call( this, { - listA : split[0], - listB : split[1] + listA : split[0], + listB : split[1] })); return paired; }, @@ -506,8 +506,8 @@ var PairedCollectionCreator = Backbone.View.extend( baseMVC.LoggableMixin ).exte var fwdName = fwd.name, revName = rev.name, lcs = this._naiveStartingAndEndingLCS( - fwdName.replace( this.filters[0], '' ), - revName.replace( this.filters[1], '' ) + fwdName.replace( new RegExp( this.filters[0] ), '' ), + revName.replace( new RegExp( this.filters[1] ), '' ) ); if( removeExtensions ){ var lastDotIndex = lcs.lastIndexOf( '.' ); diff --git a/client/galaxy/scripts/mvc/form/form-parameters.js b/client/galaxy/scripts/mvc/form/form-parameters.js index 0ddcc484898..6837c51ac02 100644 --- a/client/galaxy/scripts/mvc/form/form-parameters.js +++ b/client/galaxy/scripts/mvc/form/form-parameters.js @@ -71,7 +71,7 @@ define(['utils/utils', } // log - console.debug('tools-form::_addRow() : Auto matched field type (' + input_def.type + ').'); + Galaxy.emit.debug('form-parameters::_addRow()', 'Auto matched field type (' + input_def.type + ').'); } // set field value diff --git a/client/galaxy/scripts/mvc/form/form-repeat.js b/client/galaxy/scripts/mvc/form/form-repeat.js index 89d1b4818f3..0ea5dd7ddd5 100644 --- a/client/galaxy/scripts/mvc/form/form-repeat.js +++ b/client/galaxy/scripts/mvc/form/form-repeat.js @@ -67,7 +67,7 @@ var View = Backbone.View.extend({ add: function(options) { // repeat block already exists if (!options.id || this.list[options.id]) { - console.debug('form-repeat::add - Duplicate repeat block id.'); + Galaxy.emit.debug('form-repeat::add()', 'Duplicate repeat block id.'); return; } @@ -123,7 +123,7 @@ var View = Backbone.View.extend({ del: function(id) { // could not find element if (!this.list[id]) { - console.debug('form-repeat::del - Invalid repeat block id.'); + Galaxy.emit.debug('form-repeat::del()', 'Invalid repeat block id.'); return; } diff --git a/client/galaxy/scripts/mvc/form/form-select-content.js b/client/galaxy/scripts/mvc/form/form-select-content.js index c3445fb017c..2c4d6b20198 100644 --- a/client/galaxy/scripts/mvc/form/form-select-content.js +++ b/client/galaxy/scripts/mvc/form/form-select-content.js @@ -237,7 +237,7 @@ var View = Backbone.View.extend({ } } } catch (err) { - console.debug('tools-select-content::value() - Skipped.'); + Galaxy.emit.debug('tools-select-content::value()', 'Skipped.'); } } else { for (var i in this.list) { diff --git a/client/galaxy/scripts/mvc/form/form-view.js b/client/galaxy/scripts/mvc/form/form-view.js index 2f19ac80c81..51939fea7ae 100644 --- a/client/galaxy/scripts/mvc/form/form-view.js +++ b/client/galaxy/scripts/mvc/form/form-view.js @@ -23,7 +23,7 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', this.options = Utils.merge(options, this.optionsDefault); // log options - console.debug(this.options); + Galaxy.emit.debug('form-view::initialize()', 'Ready to build form.', this.options); // link galaxy modal or create one var galaxy = parent.Galaxy; @@ -69,7 +69,7 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', } field.update(new_options); field.trigger('change'); - console.debug('Updating options for ' + input_id); + Galaxy.emit.debug('form-view::update()', 'Updating options for ' + input_id); } } } @@ -231,7 +231,7 @@ define(['utils/utils', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc', } // log - console.debug('tools-form-base::initialize() - Completed.'); + Galaxy.emit.debug('form-view::initialize()', 'Completed'); } }); }); \ No newline at end of file diff --git a/client/galaxy/scripts/mvc/grid/grid-template.js b/client/galaxy/scripts/mvc/grid/grid-template.js index fc51b34c052..28b640d9589 100644 --- a/client/galaxy/scripts/mvc/grid/grid-template.js +++ b/client/galaxy/scripts/mvc/grid/grid-template.js @@ -213,7 +213,7 @@ return { } else { label_class = 'use-outbound'; } - tmpl += '' + value + ''; + tmpl += '' + value + ''; if (options.operations.length != 0) { tmpl += ''; } diff --git a/client/galaxy/scripts/mvc/library/library-folderrow-view.js b/client/galaxy/scripts/mvc/library/library-folderrow-view.js index 3562a070cde..271142bb8ce 100644 --- a/client/galaxy/scripts/mvc/library/library-folderrow-view.js +++ b/client/galaxy/scripts/mvc/library/library-folderrow-view.js @@ -37,7 +37,7 @@ var FolderRowView = Backbone.View.extend({ } else{ template = this.templateRowFolder(); } - } else if (folder_item.get('type') === 'file' || folder_item.get('model_class') === 'LibraryDataset'){ + } else if (folder_item.get('type') === 'file' || folder_item.get('model_class') === 'LibraryDatasetDatasetAssociation'){ this.options.type = 'file'; if (folder_item.get('deleted')){ template = this.templateRowDeletedFile(); diff --git a/client/galaxy/scripts/mvc/tools/tools-form-base.js b/client/galaxy/scripts/mvc/tools/tools-form-base.js index bd1c82914f0..76dc2cce136 100644 --- a/client/galaxy/scripts/mvc/tools/tools-form-base.js +++ b/client/galaxy/scripts/mvc/tools/tools-form-base.js @@ -33,7 +33,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', this.$el.hide(); this.deferred.execute(function(){ Backbone.View.prototype.remove.call(self); - console.debug('tools-form-base::remove() - Destroy view.'); + Galaxy.emit.debug('tools-form-base::remove()', 'Destroy view.'); }); }, @@ -102,8 +102,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', message : 'Now you are using \'' + self.options.name + '\' version ' + self.options.version + '.', persistent : false }); - console.debug('tools-form::initialize() - Initial tool model ready.'); - console.debug(new_model); + Galaxy.emit.debug('tools-form-base::initialize()', 'Initial tool model ready.', new_model); process.resolve(); }, @@ -127,8 +126,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', } }); } - console.debug('tools-form::initialize() - Initial tool model request failed.'); - console.debug(response); + Galaxy.emit.debug('tools-form::initialize()', 'Initial tool model request failed.', response); process.reject(); } }); @@ -157,8 +155,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', form.wait(true); // log tool state - console.debug('tools-form-base::_updateModel() - Sending current state (see below).'); - console.debug(current_state); + Galaxy.emit.debug('tools-form-base::_updateModel()', 'Sending current state.', current_state); // post job Utils.request({ @@ -169,13 +166,11 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view', self.form.update(new_model['tool_model'] || new_model); self.options.update && self.options.update(new_model); form.wait(false); - console.debug('tools-form-base::_updateModel() - Received new model (see below).'); - console.debug(new_model); + Galaxy.emit.debug('tools-form-base::_updateModel()', 'Received new model.', new_model); process.resolve(); }, error : function(response) { - console.debug('tools-form-base::_updateModel() - Refresh request failed.'); - console.debug(response); + Galaxy.emit.debug('tools-form-base::_updateModel()', 'Refresh request failed.', response); process.reject(); } }); diff --git a/client/galaxy/scripts/mvc/tools/tools-form-workflow.js b/client/galaxy/scripts/mvc/tools/tools-form-workflow.js index ba3618e0631..772302838d5 100644 --- a/client/galaxy/scripts/mvc/tools/tools-form-workflow.js +++ b/client/galaxy/scripts/mvc/tools/tools-form-workflow.js @@ -13,7 +13,7 @@ define(['utils/utils', 'mvc/tools/tools-form-base'], // link with node representation in workflow module this.node = options.node; if (!this.node) { - console.debug('FAILED - tools-form-workflow:initialize() - Node not found in workflow.'); + Galaxy.emit.debug('tools-form-workflow::initialize()', 'Node not found in workflow.'); return; } diff --git a/client/galaxy/scripts/mvc/tools/tools-jobs.js b/client/galaxy/scripts/mvc/tools/tools-jobs.js index 35f28c5e762..5b025bb97d6 100644 --- a/client/galaxy/scripts/mvc/tools/tools-jobs.js +++ b/client/galaxy/scripts/mvc/tools/tools-jobs.js @@ -19,13 +19,13 @@ return { // validate job definition if (!this._validation(form, job_def)) { - console.debug('tools-jobs::submit - Submission canceled. Validation failed.'); + Galaxy.emit.debug('tools-jobs::submit()', 'Submission canceled. Validation failed.'); callback && callback(); return; } // debug - console.debug(job_def); + Galaxy.emit.debug('tools-jobs::submit()', 'Validation complete.', job_def); // post job Utils.request({ @@ -40,7 +40,7 @@ return { }, error : function(response) { callback && callback(); - console.debug(response); + Galaxy.emit.debug('tools-jobs::submit', 'Submission failed.', response); if (response && response.err_data) { var error_messages = form.data.matchResponse(response.err_data); for (var input_id in error_messages) { @@ -84,7 +84,7 @@ return { // check if objects where properly identified if (!input_id || !input_def || !input_field) { - console.debug('tools-jobs::_validation - Retrieving input objects failed.'); + Galaxy.emit.debug('tools-jobs::_validation()', 'Retrieving input objects failed.'); continue; } diff --git a/client/galaxy/scripts/mvc/ui/ui-select-default.js b/client/galaxy/scripts/mvc/ui/ui-select-default.js index 0b4f9c930ab..e103c361ef6 100644 --- a/client/galaxy/scripts/mvc/ui/ui-select-default.js +++ b/client/galaxy/scripts/mvc/ui/ui-select-default.js @@ -29,8 +29,20 @@ var View = Backbone.View.extend({ // link elements this.$select = this.$el.find('.select'); - this.$icon = this.$el.find('.icon'); - this.$button = this.$el.find('.button'); + this.$icon_dropdown = this.$el.find('.icon-dropdown'); + + // allow regular multi-select field to be resized + var minHeight = null; + this.$('.icon-resize').on('mousedown', function(event) { + var currentY = event.pageY; + var currentHeight = self.$select.height(); + minHeight = minHeight || currentHeight; + $('#dd-helper').show().on('mousemove', function(event) { + self.$select.height(Math.max(currentHeight + (event.pageY - currentY), minHeight)); + }).on('mouseup mouseleave', function() { + $('#dd-helper').hide().off(); + }); + }); // multiple select fields have an additional button and other custom properties if (this.options.multiple) { @@ -47,11 +59,11 @@ var View = Backbone.View.extend({ } }); this.$el.prepend(this.all_button.$el); + } else { + this.$el.addClass('ui-select-multiple'); } - // customize style and content - this.$el.addClass('ui-select-multiple'); this.$select.prop('multiple', true); - this.$button.remove(); + this.$icon_dropdown.remove(); } // update initial options @@ -142,15 +154,15 @@ var View = Backbone.View.extend({ /** Show a spinner indicating that the select options are currently loaded */ wait: function() { - this.$icon.removeClass(); - this.$icon.addClass('fa fa-spinner fa-spin'); + this.$icon_dropdown.removeClass(); + this.$icon_dropdown.addClass('icon-dropdown fa fa-spinner fa-spin'); }, /** Hide spinner indicating that the request has been completed */ unwait: function() { - this.$icon.removeClass(); - this.$icon.addClass('fa fa-caret-down'); + this.$icon_dropdown.removeClass(); + this.$icon_dropdown.addClass('icon-dropdown fa fa-caret-down'); }, /** Returns true if the field is disabled @@ -205,7 +217,7 @@ var View = Backbone.View.extend({ // update to searchable field (in this case select2) if (this.options.searchable) { this.$select.select2('destroy'); - this.$select.select2(); + this.$select.select2({ closeOnSelect: !this.options.multiple }); this.$( '.select2-container .select2-search input' ).off( 'blur' ); } @@ -267,8 +279,9 @@ var View = Backbone.View.extend({ _template: function(options) { return '
' + '
'}});return{View:n}}),define("mvc/ui/ui-slider",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:e.uid(),min:null,max:null,step:null,precise:!1,split:1e4},initialize:function(t){var n=this;this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.useslider=null!==this.options.max&&null!==this.options.min&&this.options.max>this.options.min,null===this.options.step&&(this.options.step=1,this.options.precise&&this.useslider&&(this.options.step=(this.options.max-this.options.min)/this.options.split)),this.useslider?(this.$slider=this.$el.find("#slider"),this.$slider.slider(this.options),this.$slider.on("slide",function(e,t){n.value(t.value)})):this.$el.find(".ui-form-slider-text").css("width","100%"),this.$text=this.$el.find("#text"),void 0!==this.options.value&&this.value(this.options.value),this.$text.on("change",function(){n.value($(this).val())});var r=[];this.$text.on("keyup",function(e){r[e.which]=!1,n.options.onchange&&n.options.onchange($(this).val())}),this.$text.on("keydown",function(e){var t=e.which;r[t]=!0,8==t||9==t||13==t||37==t||39==t||t>=48&&57>=t||t>=96&&105>=t||(190==t||110==t)&&-1==$(this).val().indexOf(".")&&n.options.precise||(189==t||109==t)&&-1==$(this).val().indexOf("-")||r[91]||r[17]||event.preventDefault()})},value:function(e){return void 0!==e&&(null!==e&&""!==e&&(isNaN(e)&&(e=0),null!==this.options.max&&(e=Math.min(e,this.options.max)),null!==this.options.min&&(e=Math.max(e,this.options.min))),this.$slider&&this.$slider.slider("value",e),this.$text.val(e),this.options.onchange&&this.options.onchange(e)),this.$text.val()},_template:function(e){return'
'}});return{View:t}}),define("mvc/ui/ui-options",["utils/utils","mvc/ui/ui-buttons"],function(e,t){var n=Backbone.View.extend({initialize:function(n){var r=this;this.options=e.merge(n,{visible:!0,data:[],id:e.uid(),error_text:"No options available.",wait_text:"Please wait...",multiple:!1}),this.setElement('
'),this.$message=$("
"),this.$options=$(this._template(n)),this.$menu=$('
'),this.$el.append(this.$message),this.$el.append(this.$menu),this.$el.append(this.$options),this.options.multiple&&(this.all_button=new t.ButtonCheck({onclick:function(){r.$("input").prop("checked",0!==r.all_button.value()),r.trigger("change")}}),this.$menu.append(this.all_button.$el)),this.options.visible||this.$el.hide(),this.update(this.options.data),void 0!==this.options.value&&this.value(this.options.value),this.on("change",function(){this.options.onchange&&this.options.onchange(this.value())})},update:function(e){var t=this._getValue();if(this.$options.empty(),this._templateOptions)this.$options.append(this._templateOptions(e));else for(var n in e){var r=$(this._templateOption(e[n]));r.addClass("ui-option"),r.tooltip({title:e[n].tooltip,placement:"bottom"}),this.$options.append(r)}var i=this;this.$("input").on("change",function(){i.value(i._getValue()),i.trigger("change")}),this.value(t),this.unwait()},value:function(e){if(void 0!==e&&(this.$("input").prop("checked",!1),null!==e)){e instanceof Array||(e=[e]);for(var t in e)this.$('input[value="'+e[t]+'"]').first().prop("checked",!0)}var n=this._getValue();if(this.all_button){var r=n;r=r instanceof Array?r.length:0,this.all_button.value(r,this._size())}return n},exists:function(e){if(void 0!==e){e instanceof Array||(e=[e]);for(var t in e)if(this.$('input[value="'+e[t]+'"]').length>0)return!0}return!1},first:function(){var e=this.$("input").first();return e.length>0?e.val():null},wait:function(){0==this._size()&&(this._messageShow(this.options.wait_text,"info"),this.$options.hide(),this.$menu.hide())},unwait:function(){var e=this._size();0==e?(this._messageShow(this.options.error_text,"danger"),this.$options.hide(),this.$menu.hide()):(this._messageHide(),this.$options.css("display","inline-block"),this.$menu.show())},_getValue:function(){var t=[];return this.$(":checked").each(function(){t.push($(this).val())}),e.validate(t)?this.options.multiple?t:t[0]:null},_size:function(){return this.$(".ui-option").length},_messageShow:function(e,t){this.$message.show(),this.$message.removeClass(),this.$message.addClass("ui-message alert alert-"+t),this.$message.html(e)},_messageHide:function(){this.$message.hide()},_template:function(){return'
'}}),r=n.extend({_templateOption:function(t){var n=e.uid();return'
"}}),i={};i.View=r.extend({initialize:function(e){e.type="radio",r.prototype.initialize.call(this,e)}});var s={};s.View=r.extend({initialize:function(e){e.multiple=!0,e.type="checkbox",r.prototype.initialize.call(this,e)}});var o={};return o.View=n.extend({initialize:function(e){n.prototype.initialize.call(this,e)},value:function(e){return void 0!==e&&(this.$("input").prop("checked",!1),this.$("label").removeClass("active"),this.$('[value="'+e+'"]').prop("checked",!0).closest("label").addClass("active")),this._getValue()},_templateOption:function(e){var t="fa "+e.icon;e.label||(t+=" no-padding");var n='"},_template:function(){return'
'}}),{Base:n,BaseIcons:r,Radio:i,RadioButton:o,Checkbox:s}}),define("mvc/ui/ui-drilldown",["utils/utils","mvc/ui/ui-options"],function(e,t){var n=t.BaseIcons.extend({initialize:function(e){e.type=e.display||"checkbox",e.multiple="checkbox"==e.display,t.BaseIcons.prototype.initialize.call(this,e),this.initial=!0},value:function(e){var n=t.BaseIcons.prototype.value.call(this,e);if(this.initial&&null!==n&&this.header_index){this.initial=!1;var r=n;$.isArray(r)||(r=[r]);for(var i in r){var s=this.header_index[r[i]];for(var o in s)this._setState(s[o],!0)}}return n},_setState:function(e,t){var n=this.$(".button-"+e),r=this.$(".subgroup-"+e);n.data("is_expanded",t),t?(r.fadeIn("fast"),n.removeClass("toggle-expand"),n.addClass("toggle")):(r.hide(),n.removeClass("toggle"),n.addClass("toggle-expand"))},_templateOptions:function(t){function n(e,t){var n=e.find(".button-"+t);n.on("click",function(){s._setState(t,!n.data("is_expanded"))})}function r(t,o,u){u=u||[];for(i in o){var f=o[i],l=f.options.length>0,h=u.slice(0);s.header_index[f.value]=h.slice(0);var p=$("
");if(l){var v=e.uid(),m=$(''),g=$('