galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
December 2014
- 2 participants
- 245 discussions
commit/galaxy-central: natefoo: Update tag latest_2014.10.06 for changeset 3e7adbbe91a0
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2db0fb9594d6/
Changeset: 2db0fb9594d6
Branch: stable
User: natefoo
Date: 2014-12-09 19:00:15+00:00
Summary: Update tag latest_2014.10.06 for changeset 3e7adbbe91a0
Affected #: 1 file
diff -r 3e7adbbe91a06d30a96e7a7101707e040376aba1 -r 2db0fb9594d6c315e4e0a4be70f64373cfc708f6 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -20,4 +20,4 @@
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
548ab24667d6206780237bd807f7d857a484c461 latest_2014.08.11
2092948937ac30ef82f71463a235c66d34987088 release_2014.10.06
-782cf1a1f6b56f8a9c0b3e5e9ffd29fd93b16ce3 latest_2014.10.06
+3e7adbbe91a06d30a96e7a7101707e040376aba1 latest_2014.10.06
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: remove references to ui.js in client and templates; mv scripts/jq-plugins/ui to more generic/catch-all scripts/ui/
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/336a1e96bf51/
Changeset: 336a1e96bf51
User: carlfeberhard
Date: 2014-12-09 18:52:24+00:00
Summary: Client build: remove references to ui.js in client and templates; mv scripts/jq-plugins/ui to more generic/catch-all scripts/ui/
Affected #: 73 files
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/fa-icon-button.js
--- a/client/galaxy/scripts/jq-plugins/ui/fa-icon-button.js
+++ /dev/null
@@ -1,48 +0,0 @@
-(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- define([], factory);
- } else {
- root.faIconButton = factory();
- }
-
-}(this, function () {
-//============================================================================
- /** Returns a jQuery object containing a clickable font-awesome button.
- * options:
- * tooltipConfig : option map for bootstrap tool tip
- * classes : array of class names (will always be classed as icon-btn)
- * disabled : T/F - add the 'disabled' class?
- * title : tooltip/title string
- * target : optional href target
- * href : optional href
- * faIcon : which font awesome icon to use
- * onclick : function to call when the button is clicked
- */
- var faIconButton = function( options ){
- options = options || {};
- options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' };
-
- options.classes = [ 'icon-btn' ].concat( options.classes || [] );
- if( options.disabled ){
- options.classes.push( 'disabled' );
- }
-
- var html = [
- '<a class="', options.classes.join( ' ' ), '"',
- (( options.title )?( ' title="' + options.title + '"' ):( '' )),
- (( !options.disabled && options.target )? ( ' target="' + options.target + '"' ):( '' )),
- ' href="', (( !options.disabled && options.href )?( options.href ):( 'javascript:void(0);' )), '">',
- // could go with something less specific here - like 'html'
- '<span class="fa ', options.faIcon, '"></span>',
- '</a>'
- ].join( '' );
- var $button = $( html ).tooltip( options.tooltipConfig );
- if( _.isFunction( options.onclick ) ){
- $button.click( options.onclick );
- }
- return $button;
- };
-
-//============================================================================
- return faIconButton;
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/filter-control.js
--- a/client/galaxy/scripts/jq-plugins/ui/filter-control.js
+++ /dev/null
@@ -1,204 +0,0 @@
-// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
-// Uses AMD or browser globals to create a jQuery plugin.
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-
-}(function ($) {
- //==============================================================================
- /**
- * Template function that produces a bootstrap dropdown to replace the
- * vanilla HTML select input. Pass in an array of options and an initial selection:
- * $( '.my-div' ).append( dropDownSelect( [ 'option1', 'option2' ], 'option2' );
- *
- * When the user changes the selected option a 'change.dropdown-select' event will
- * fire with both the jq event and the new selection text as arguments.
- *
- * Get the currently selected choice using:
- * var userChoice = $( '.my-div .dropdown-select .dropdown-select-selected' ).text();
- *
- */
- function dropDownSelect( options, selected ){
- // replacement for vanilla select element using bootstrap dropdowns instead
- selected = selected || (( !_.isEmpty( options ) )?( options[0] ):( '' ));
- var $select = $([
- '<div class="dropdown-select btn-group">',
- '<button type="button" class="btn btn-default">',
- '<span class="dropdown-select-selected">' + selected + '</span>',
- '</button>',
- '</div>'
- ].join( '\n' ));
-
- // if there's only one option, do not style/create as buttons, dropdown - use simple span
- // otherwise, a dropdown displaying the current selection
- if( options && options.length > 1 ){
- $select.find( 'button' )
- .addClass( 'dropdown-toggle' ).attr( 'data-toggle', 'dropdown' )
- .append( ' <span class="caret"></span>' );
- $select.append([
- '<ul class="dropdown-menu" role="menu">',
- _.map( options, function( option ){
- return [
- '<li><a href="javascript:void(0)">', option, '</a></li>'
- ].join( '' );
- }).join( '\n' ),
- '</ul>'
- ].join( '\n' ));
- }
-
- // trigger 'change.dropdown-select' when a new selection is made using the dropdown
- function selectThis( event ){
- var $this = $( this ),
- $select = $this.parents( '.dropdown-select' ),
- newSelection = $this.text();
- $select.find( '.dropdown-select-selected' ).text( newSelection );
- $select.trigger( 'change.dropdown-select', newSelection );
- }
-
- $select.find( 'a' ).click( selectThis );
- return $select;
- }
-
- //==============================================================================
- /**
- * Creates a three part bootstrap button group (key, op, value) meant to
- * allow the user control of filters (e.g. { key: 'name', op: 'contains', value: 'my_history' })
- *
- * Each field uses a dropDownSelect (from ui.js) to allow selection
- * (with the 'value' field appearing as an input when set to do so).
- *
- * Any change or update in any of the fields will trigger a 'change.filter-control'
- * event which will be passed an object containing those fields (as the example above).
- *
- * Pass in an array of possible filter objects to control what the user can select.
- * Each filter object should have:
- * key : generally the attribute name on which to filter something
- * ops : an array of 1 or more filter operations (e.g. [ 'is', '<', 'contains', '!=' ])
- * values (optional) : an array of possible values for the filter (e.g. [ 'true', 'false' ])
- * @example:
- * $( '.my-div' ).filterControl({
- * filters : [
- * { key: 'name', ops: [ 'is exactly', 'contains' ] }
- * { key: 'deleted', ops: [ 'is' ], values: [ 'true', 'false' ] }
- * ]
- * });
- * // after initialization, you can prog. get the current value using:
- * $( '.my-div' ).filterControl( 'val' )
- *
- */
- function FilterControl( element, options ){
- return this.init( element, options );
- }
- /** the data key that this object will be stored under in the DOM element */
- FilterControl.prototype.DATA_KEY = 'filter-control';
-
- /** parses options, sets up instance vars, and does initial render */
- FilterControl.prototype.init = function _init( element, options ){
- options = options || { filters: [] };
- this.$element = $( element ).addClass( 'filter-control btn-group' );
- this.options = jQuery.extend( true, {}, this.defaults, options );
-
- this.currFilter = this.options.filters[0];
- return this.render();
- };
-
- /** render (or re-render) the controls on the element */
- FilterControl.prototype.render = function _render(){
- this.$element.empty()
- .append([ this._renderKeySelect(), this._renderOpSelect(), this._renderValueInput() ]);
- return this;
- };
-
- /** render the key dropDownSelect, bind a change event to it, and return it */
- FilterControl.prototype._renderKeySelect = function __renderKeySelect(){
- var filterControl = this;
- var keys = this.options.filters.map( function( filter ){
- return filter.key;
- });
- this.$keySelect = dropDownSelect( keys, this.currFilter.key )
- .addClass( 'filter-control-key' )
- .on( 'change.dropdown-select', function( event, selection ){
- filterControl.currFilter = _.findWhere( filterControl.options.filters, { key: selection });
- // when the filter/key changes, re-render the control entirely
- filterControl.render()._triggerChange();
- });
- return this.$keySelect;
- };
-
- /** render the op dropDownSelect, bind a change event to it, and return it */
- FilterControl.prototype._renderOpSelect = function __renderOpSelect(){
- var filterControl = this,
- ops = this.currFilter.ops;
- //TODO: search for currOp in avail. ops: use that for selected if there; otherwise: first op
- this.$opSelect = dropDownSelect( ops, ops[0] )
- .addClass( 'filter-control-op' )
- .on( 'change.dropdown-select', function( event, selection ){
- filterControl._triggerChange();
- });
- return this.$opSelect;
- };
-
- /** render the value control, bind a change event to it, and return it */
- FilterControl.prototype._renderValueInput = function __renderValueInput(){
- var filterControl = this;
- // if a values attribute is prov. on the filter - make this a dropdown; otherwise, use an input
- if( this.currFilter.values ){
- this.$valueSelect = dropDownSelect( this.currFilter.values, this.currFilter.values[0] )
- .on( 'change.dropdown-select', function( event, selection ){
- filterControl._triggerChange();
- });
- } else {
- //TODO: allow setting a value type (mainly for which html5 input to use: range, number, etc.)
- this.$valueSelect = $( '<input/>' ).addClass( 'form-control' )
- .on( 'change', function( event, value ){
- filterControl._triggerChange();
- });
- }
- this.$valueSelect.addClass( 'filter-control-value' );
- return this.$valueSelect;
- };
-
- /** return the current state/setting for the filter as a three key object: key, op, value */
- FilterControl.prototype.val = function _val(){
- var key = this.$element.find( '.filter-control-key .dropdown-select-selected' ).text(),
- op = this.$element.find( '.filter-control-op .dropdown-select-selected' ).text(),
- // handle either a dropdown or plain input
- $value = this.$element.find( '.filter-control-value' ),
- value = ( $value.hasClass( 'dropdown-select' ) )?( $value.find( '.dropdown-select-selected' ).text() )
- :( $value.val() );
- return { key: key, op: op, value: value };
- };
-
- // single point of change for change event
- FilterControl.prototype._triggerChange = function __triggerChange(){
- this.$element.trigger( 'change.filter-control', this.val() );
- };
-
- // as jq plugin
- jQuery.fn.extend({
- filterControl : function $filterControl( options ){
- var nonOptionsArgs = jQuery.makeArray( arguments ).slice( 1 );
- return this.map( function(){
- var $this = $( this ),
- data = $this.data( FilterControl.prototype.DATA_KEY );
-
- if( jQuery.type( options ) === 'object' ){
- data = new FilterControl( $this, options );
- $this.data( FilterControl.prototype.DATA_KEY, data );
- }
- if( data && jQuery.type( options ) === 'string' ){
- var fn = data[ options ];
- if( jQuery.type( fn ) === 'function' ){
- return fn.apply( data, nonOptionsArgs );
- }
- }
- return this;
- });
- }
- });
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/loading-indicator.js
--- a/client/galaxy/scripts/jq-plugins/ui/loading-indicator.js
+++ /dev/null
@@ -1,98 +0,0 @@
-(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define([], factory);
- } else {
- // Browser globals
- root.LoadingIndicator = factory();
- }
-
-//============================================================================
-}(this, function () {
- //TODO: too specific to history panel
- function LoadingIndicator( $where, options ){
-
- var self = this;
- // defaults
- options = jQuery.extend({
- cover : false
- }, options || {} );
-
- function render(){
- var html = [
- '<div class="loading-indicator">',
- '<div class="loading-indicator-text">',
- '<span class="fa fa-spinner fa-spin fa-lg"></span>',
- '<span class="loading-indicator-message">loading...</span>',
- '</div>',
- '</div>'
- ].join( '\n' );
-
- var $indicator = $( html ).hide().css( options.css || {
- position : 'fixed'
- }),
- $text = $indicator.children( '.loading-indicator-text' );
-
- if( options.cover ){
- $indicator.css({
- 'z-index' : 2,
- top : $where.css( 'top' ),
- bottom : $where.css( 'bottom' ),
- left : $where.css( 'left' ),
- right : $where.css( 'right' ),
- opacity : 0.5,
- 'background-color': 'white',
- 'text-align': 'center'
- });
- $text = $indicator.children( '.loading-indicator-text' ).css({
- 'margin-top' : '20px'
- });
-
- } else {
- $text = $indicator.children( '.loading-indicator-text' ).css({
- margin : '12px 0px 0px 10px',
- opacity : '0.85',
- color : 'grey'
- });
- $text.children( '.loading-indicator-message' ).css({
- margin : '0px 8px 0px 0px',
- 'font-style' : 'italic'
- });
- }
- return $indicator;
- }
-
- self.show = function( msg, speed, callback ){
- msg = msg || 'loading...';
- speed = speed || 'fast';
- // remove previous
- $where.parent().find( '.loading-indicator' ).remove();
- // since position is fixed - we insert as sibling
- self.$indicator = render().insertBefore( $where );
- self.message( msg );
- self.$indicator.fadeIn( speed, callback );
- return self;
- };
-
- self.message = function( msg ){
- self.$indicator.find( 'i' ).text( msg );
- };
-
- self.hide = function( speed, callback ){
- speed = speed || 'fast';
- if( self.$indicator && self.$indicator.size() ){
- self.$indicator.fadeOut( speed, function(){
- self.$indicator.remove();
- if( callback ){ callback(); }
- });
- } else {
- if( callback ){ callback(); }
- }
- return self;
- };
- return self;
- }
-
-//============================================================================
- return LoadingIndicator;
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/mode-button.js
--- a/client/galaxy/scripts/jq-plugins/ui/mode-button.js
+++ /dev/null
@@ -1,191 +0,0 @@
-// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
-// Uses AMD or browser globals to create a jQuery plugin.
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
- // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
- // relying on jquery being loaded globally* in order to preserve plugins.
- define([], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-
-}(function () {
-
- /** Multi 'mode' button (or any element really) that changes the html
- * contents of itself when clicked. Pass in an ordered list of
- * objects with 'html' and (optional) onclick functions.
- *
- * When clicked in a particular node, the onclick function will
- * be called (with the element as this) and the element will
- * switch to the next mode, replacing its html content with
- * that mode's html.
- *
- * If there is no next mode, the element will switch back to
- * the first mode.
- * @example:
- * $( '.myElement' ).modeButton({
- * modes : [
- * {
- * mode: 'bler',
- * html: '<h5>Bler</h5>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'red' );
- * }
- * },
- * {
- * mode: 'bloo',
- * html: '<h4>Bloo</h4>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'blue' );
- * }
- * },
- * {
- * mode: 'blah',
- * html: '<h3>Blah</h3>',
- * onclick : function(){
- * $( 'body' ).css( 'background-color', 'grey' );
- * }
- * },
- * ]
- * });
- * $( '.myElement' ).modeButton( 'callModeFn', 'bler' );
- */
- /** constructor */
- function ModeButton( element, options ){
- this.currModeIndex = 0;
- return this._init( element, options );
- }
-
- /** html5 data key to store this object inside an element */
- ModeButton.prototype.DATA_KEY = 'mode-button';
- /** default options */
- ModeButton.prototype.defaults = {
- switchModesOnClick : true
- };
-
- // ---- private interface
- /** set up options, intial mode, and the click handler */
- ModeButton.prototype._init = function _init( element, options ){
- //console.debug( 'ModeButton._init:', element, options );
- options = options || {};
- this.$element = $( element );
- this.options = $.extend( true, {}, this.defaults, options );
- if( !options.modes ){
- throw new Error( 'ModeButton requires a "modes" array' );
- }
-
- var modeButton = this;
- this.$element.click( function _ModeButtonClick( event ){
- // call the curr mode fn
- modeButton.callModeFn();
- // inc the curr mode index
- if( modeButton.options.switchModesOnClick ){ modeButton._incModeIndex(); }
- // set the element html
- $( this ).html( modeButton.options.modes[ modeButton.currModeIndex ].html );
- });
- return this.reset();
- };
- /** increment the mode index to the next in the array, looping back to zero if at the last */
- ModeButton.prototype._incModeIndex = function _incModeIndex(){
- this.currModeIndex += 1;
- if( this.currModeIndex >= this.options.modes.length ){
- this.currModeIndex = 0;
- }
- return this;
- };
- /** get the mode index in the modes array for the given key (mode name) */
- ModeButton.prototype._getModeIndex = function _getModeIndex( modeKey ){
- for( var i=0; i<this.options.modes.length; i+=1 ){
- if( this.options.modes[ i ].mode === modeKey ){ return i; }
- }
- throw new Error( 'mode not found: ' + modeKey );
- };
- /** set the current mode to the one with the given index and set button html */
- ModeButton.prototype._setModeByIndex = function _setModeByIndex( index ){
- var newMode = this.options.modes[ index ];
- if( !newMode ){
- throw new Error( 'mode index not found: ' + index );
- }
- this.currModeIndex = index;
- if( newMode.html ){
- this.$element.html( newMode.html );
- }
- return this;
- };
-
- // ---- public interface
- /** get the current mode object (not just the mode name) */
- ModeButton.prototype.currentMode = function currentMode(){
- return this.options.modes[ this.currModeIndex ];
- };
- /** return the mode key of the current mode */
- ModeButton.prototype.current = function current(){
- // sugar for returning mode name
- return this.currentMode().mode;
- };
- /** get the mode with the given modeKey or the current mode if modeKey is undefined */
- ModeButton.prototype.getMode = function getMode( modeKey ){
- if( !modeKey ){ return this.currentMode(); }
- return this.options.modes[( this._getModeIndex( modeKey ) )];
- };
- /** T/F if the button has the given mode */
- ModeButton.prototype.hasMode = function hasMode( modeKey ){
- try {
- return !!this.getMode( modeKey );
- } catch( err ){}
- return false;
- };
- /** set the current mode to the mode with the given name */
- ModeButton.prototype.setMode = function setMode( modeKey ){
- return this._setModeByIndex( this._getModeIndex( modeKey ) );
- };
- /** reset to the initial mode */
- ModeButton.prototype.reset = function reset(){
- this.currModeIndex = 0;
- if( this.options.initialMode ){
- this.currModeIndex = this._getModeIndex( this.options.initialMode );
- }
- return this._setModeByIndex( this.currModeIndex );
- };
- /** manually call the click handler of the given mode */
- ModeButton.prototype.callModeFn = function callModeFn( modeKey ){
- var modeFn = this.getMode( modeKey ).onclick;
- if( modeFn && $.type( modeFn === 'function' ) ){
- // call with the element as context (std jquery pattern)
- return modeFn.call( this.$element.get(0) );
- }
- return undefined;
- };
-
- // as jq plugin
- $.fn.modeButton = function $modeButton( options ){
- if( !this.size() ){ return this; }
-
- //TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
- if( $.type( options ) === 'object' ){
- return this.map( function(){
- var $this = $( this );
- $this.data( 'mode-button', new ModeButton( $this, options ) );
- return this;
- });
- }
-
- var $first = $( this[0] ),
- button = $first.data( 'mode-button' );
-
- if( !button ){
- throw new Error( 'modeButton needs an options object or string name of a function' );
- }
-
- if( button && $.type( options ) === 'string' ){
- var fnName = options;
- if( button && $.type( button[ fnName ] ) === 'function' ){
- return button[ fnName ].apply( button, $.makeArray( arguments ).slice( 1 ) );
- }
- }
- return button;
- };
-
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/pagination.js
--- a/client/galaxy/scripts/jq-plugins/ui/pagination.js
+++ /dev/null
@@ -1,226 +0,0 @@
-// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
-// Uses AMD or browser globals to create a jQuery plugin.
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-
-}(function ($) {
-
- /** Builds (twitter bootstrap styled) pagination controls.
- * If the totalDataSize is not null, a horizontal list of page buttons is displayed.
- * If totalDataSize is null, two links ('Prev' and 'Next) are displayed.
- * When pages are changed, a 'pagination.page-change' event is fired
- * sending the event and the (0-based) page requested.
- */
- function Pagination( element, options ){
- /** the total number of pages */
- this.numPages = null;
- /** the current, active page */
- this.currPage = 0;
- return this.init( element, options );
- }
-
- /** data key under which this object will be stored in the element */
- Pagination.prototype.DATA_KEY = 'pagination';
- /** default options */
- Pagination.prototype.defaults = {
- /** which page to begin at */
- startingPage : 0,
- /** number of data per page */
- perPage : 20,
- /** the total number of data (null == unknown) */
- totalDataSize : null,
- /** size of current data on current page */
- currDataSize : null
- };
-
- /** init the control, calc numPages if possible, and render
- * @param {jQuery} the element that will contain the pagination control
- * @param {Object} options a map containing overrides to the pagination default options
- */
- Pagination.prototype.init = function _init( $element, options ){
- options = options || {};
- this.$element = $element;
- this.options = jQuery.extend( true, {}, this.defaults, options );
-
- this.currPage = this.options.startingPage;
- if( this.options.totalDataSize !== null ){
- this.numPages = Math.ceil( this.options.totalDataSize / this.options.perPage );
- // limit currPage by numPages
- if( this.currPage >= this.numPages ){
- this.currPage = this.numPages - 1;
- }
- }
- //console.debug( 'Pagination.prototype.init:', this.$element, this.currPage );
- //console.debug( JSON.stringify( this.options ) );
-
- // bind to data of element
- this.$element.data( Pagination.prototype.DATA_KEY, this );
-
- this._render();
- return this;
- };
-
- /** helper to create a simple li + a combo */
- function _make$Li( contents ){
- return $([
- '<li><a href="javascript:void(0);">', contents, '</a></li>'
- ].join( '' ));
- }
-
- /** render previous and next pagination buttons */
- Pagination.prototype._render = function __render(){
- // no data - no pagination
- if( this.options.totalDataSize === 0 ){ return this; }
- // only one page
- if( this.numPages === 1 ){ return this; }
-
- // when the number of pages are known, render each page as a link
- if( this.numPages > 0 ){
- this._renderPages();
- this._scrollToActivePage();
-
- // when the number of pages is not known, render previous or next
- } else {
- this._renderPrevNext();
- }
- return this;
- };
-
- /** render previous and next pagination buttons */
- Pagination.prototype._renderPrevNext = function __renderPrevNext(){
- var pagination = this,
- $prev = _make$Li( 'Prev' ),
- $next = _make$Li( 'Next' ),
- $paginationContainer = $( '<ul/>' ).addClass( 'pagination pagination-prev-next' );
-
- // disable if it either end
- if( this.currPage === 0 ){
- $prev.addClass( 'disabled' );
- } else {
- $prev.click( function(){ pagination.prevPage(); });
- }
- if( ( this.numPages && this.currPage === ( this.numPages - 1 ) )
- || ( this.options.currDataSize && this.options.currDataSize < this.options.perPage ) ){
- $next.addClass( 'disabled' );
- } else {
- $next.click( function(){ pagination.nextPage(); });
- }
-
- this.$element.html( $paginationContainer.append([ $prev, $next ]) );
- //console.debug( this.$element, this.$element.html() );
- return this.$element;
- };
-
- /** render page links for each possible page (if we can) */
- Pagination.prototype._renderPages = function __renderPages(){
- // it's better to scroll the control and let the user see all pages
- // than to force her/him to change pages in order to find the one they want (as traditional << >> does)
- var pagination = this,
- $scrollingContainer = $( '<div>' ).addClass( 'pagination-scroll-container' ),
- $paginationContainer = $( '<ul/>' ).addClass( 'pagination pagination-page-list' ),
- page$LiClick = function( ev ){
- pagination.goToPage( $( this ).data( 'page' ) );
- };
-
- for( var i=0; i<this.numPages; i+=1 ){
- // add html5 data tag 'page' for later click event handler use
- var $pageLi = _make$Li( i + 1 ).attr( 'data-page', i ).click( page$LiClick );
- // highlight the current page
- if( i === this.currPage ){
- $pageLi.addClass( 'active' );
- }
- //console.debug( '\t', $pageLi );
- $paginationContainer.append( $pageLi );
- }
- return this.$element.html( $scrollingContainer.html( $paginationContainer ) );
- };
-
- /** scroll scroll-container (if any) to show the active page */
- Pagination.prototype._scrollToActivePage = function __scrollToActivePage(){
- // scroll to show active page in center of scrollable area
- var $container = this.$element.find( '.pagination-scroll-container' );
- // no scroll container : don't scroll
- if( !$container.size() ){ return this; }
-
- var $activePage = this.$element.find( 'li.active' ),
- midpoint = $container.width() / 2;
- //console.debug( $container, $activePage, midpoint );
- $container.scrollLeft( $container.scrollLeft() + $activePage.position().left - midpoint );
- return this;
- };
-
- /** go to a certain page */
- Pagination.prototype.goToPage = function goToPage( page ){
- if( page <= 0 ){ page = 0; }
- if( this.numPages && page >= this.numPages ){ page = this.numPages - 1; }
- if( page === this.currPage ){ return this; }
-
- //console.debug( '\t going to page ' + page )
- this.currPage = page;
- this.$element.trigger( 'pagination.page-change', this.currPage );
- //console.info( 'pagination:page-change', this.currPage );
- this._render();
- return this;
- };
-
- /** go to the previous page */
- Pagination.prototype.prevPage = function prevPage(){
- return this.goToPage( this.currPage - 1 );
- };
-
- /** go to the next page */
- Pagination.prototype.nextPage = function nextPage(){
- return this.goToPage( this.currPage + 1 );
- };
-
- /** return the current page */
- Pagination.prototype.page = function page(){
- return this.currPage;
- };
-
- // alternate constructor invocation
- Pagination.create = function _create( $element, options ){
- return new Pagination( $element, options );
- };
-
- // as jq plugin
- jQuery.fn.extend({
- pagination : function $pagination( options ){
- var nonOptionsArgs = jQuery.makeArray( arguments ).slice( 1 );
-
- // if passed an object - use that as an options map to create pagination for each selected
- if( jQuery.type( options ) === 'object' ){
- return this.map( function(){
- Pagination.create( $( this ), options );
- return this;
- });
- }
-
- // (other invocations only work on the first element in selected)
- var $firstElement = $( this[0] ),
- previousControl = $firstElement.data( Pagination.prototype.DATA_KEY );
- // if a pagination control was found for this element, either...
- if( previousControl ){
- // invoke a function on the pagination object if passed a string (the function name)
- if( jQuery.type( options ) === 'string' ){
- var fn = previousControl[ options ];
- if( jQuery.type( fn ) === 'function' ){
- return fn.apply( previousControl, nonOptionsArgs );
- }
-
- // if passed nothing, return the previously set control
- } else {
- return previousControl;
- }
- }
- // if there is no control already set, return undefined
- return undefined;
- }
- });
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/peek-column-selector.js
--- a/client/galaxy/scripts/jq-plugins/ui/peek-column-selector.js
+++ /dev/null
@@ -1,317 +0,0 @@
-// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
-// Uses AMD or browser globals to create a jQuery plugin.
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-
-}(function ($) {
- //==============================================================================
- /** Column selection using the peek display as the control.
- * Adds rows to the bottom of the peek with clickable areas in each cell
- * to allow the user to select columns.
- * Column selection can be limited to a single column or multiple.
- * (Optionally) adds a left hand column of column selection prompts.
- * (Optionally) allows the column headers to be clicked/renamed
- * and set to some initial value.
- * (Optionally) hides comment rows.
- * (Optionally) allows pre-selecting and disabling certain columns for
- * each row control.
- *
- * Construct by selecting a peek table to be used with jQuery and
- * calling 'peekColumnSelector' with options.
- * Options must include a 'controls' array and can include other options
- * listed below.
- * @example:
- * $( 'pre.peek' ).peekColumnSelector({
- * columnNames : ["Chromosome", "Start", "Base", "", "", "Qual" ],
- * controls : [
- * { label: 'X Column', id: 'xColumn' },
- * { label: 'Y Column', id: 'yColumn', selected: 2 },
- * { label: 'ID Column', id: 'idColumn', selected: 4, disabled: [ 1, 5 ] },
- * { label: 'Heatmap', id: 'heatmap', selected: [ 2, 4 ], disabled: [ 0, 1 ], multiselect: true,
- * selectedText: 'Included', unselectedText: 'Excluded' }
- * ],
- * renameColumns : true,
- * hideCommentRows : true,
- * includePrompts : true,
- * topLeftContent : 'Data sample:'
- * }).on( 'peek-column-selector.change', function( ev, selection ){
- * console.info( 'new selection:', selection );
- * //{ yColumn: 2 }
- * }).on( 'peek-column-selector.rename', function( ev, names ){
- * console.info( 'column names', names );
- * //[ 'Bler', 'Start', 'Base', '', '', 'Qual' ]
- * });
- *
- * An event is fired when column selection is changed and the event
- * is passed an object in the form: { the row id : the new selection value }.
- * An event is also fired when the table headers are re-named and
- * is passed the new array of column names.
- */
-
- /** option defaults */
- var defaults = {
- /** does this control allow renaming headers? */
- renameColumns : false,
- /** does this control allow renaming headers? */
- columnNames : [],
- /** the comment character used by the peek's datatype */
- commentChar : '#',
- /** should comment rows be shown or hidden in the peek */
- hideCommentRows : false,
- /** should a column of row control prompts be used */
- includePrompts : true,
- /** what is the content of the top left cell (often a title) */
- topLeftContent : 'Columns:'
- },
- /** class added to the pre.peek element (to allow css on just the control) */
- PEEKCONTROL_CLASS = 'peek-column-selector',
- /** the string of the event fired when a control row changes */
- CHANGE_EVENT = 'peek-column-selector.change',
- /** the string of the event fired when a column is renamed */
- RENAME_EVENT = 'peek-column-selector.rename',
- /** class added to the control rows */
- ROW_CLASS = 'control',
- /** class added to the left-hand cells that serve as row prompts */
- PROMPT_CLASS = 'control-prompt',
- /** class added to selected _cells_/tds */
- SELECTED_CLASS = 'selected',
- /** class added to disabled/un-clickable cells/tds */
- DISABLED_CLASS = 'disabled',
- /** class added to the clickable surface within a cell to select it */
- BUTTON_CLASS = 'button',
- /** class added to peek table header (th) cells to indicate they can be clicked and are renamable */
- RENAMABLE_HEADER_CLASS = 'renamable-header',
- /** the data key used for each cell to store the column index ('data-...') */
- COLUMN_INDEX_DATA_KEY = 'column-index',
- /** renamable header data key used to store the column name (w/o the number and dot: '1.Bler') */
- COLUMN_NAME_DATA_KEY = 'column-name';
-
- //TODO: not happy with pure functional here - rows should polymorph (multi, single, etc.)
- //TODO: needs clean up, move handlers to outer scope
-
- // ........................................................................
- /** validate the control data sent in for each row */
- function validateControl( control ){
- if( control.disabled && jQuery.type( control.disabled ) !== 'array' ){
- throw new Error( '"disabled" must be defined as an array of indeces: ' + JSON.stringify( control ) );
- }
- if( control.multiselect && control.selected && jQuery.type( control.selected ) !== 'array' ){
- throw new Error( 'Mulitselect rows need an array for "selected": ' + JSON.stringify( control ) );
- }
- if( !control.label || !control.id ){
- throw new Error( 'Peek controls need a label and id for each control row: ' + JSON.stringify( control ) );
- }
- if( control.disabled && control.disabled.indexOf( control.selected ) !== -1 ){
- throw new Error( 'Selected column is in the list of disabled columns: ' + JSON.stringify( control ) );
- }
- return control;
- }
-
- /** build the inner control surface (i.e. button-like) */
- function buildButton( control, columnIndex ){
- return $( '<div/>' ).addClass( BUTTON_CLASS ).text( control.label );
- }
-
- /** build the basic (shared) cell structure */
- function buildControlCell( control, columnIndex ){
- var $td = $( '<td/>' )
- .html( buildButton( control, columnIndex ) )
- .attr( 'data-' + COLUMN_INDEX_DATA_KEY, columnIndex );
-
- // disable if index in disabled array
- if( control.disabled && control.disabled.indexOf( columnIndex ) !== -1 ){
- $td.addClass( DISABLED_CLASS );
- }
- return $td;
- }
-
- /** set the text of the control based on selected/un */
- function setSelectedText( $cell, control, columnIndex ){
- var $button = $cell.children( '.' + BUTTON_CLASS );
- if( $cell.hasClass( SELECTED_CLASS ) ){
- $button.html( ( control.selectedText !== undefined )?( control.selectedText ):( control.label ) );
- } else {
- $button.html( ( control.unselectedText !== undefined )?( control.unselectedText ):( control.label ) );
- }
- }
-
- /** build a cell for a row that only allows one selection */
- function buildSingleSelectCell( control, columnIndex ){
- // only one selection - selected is single index
- var $cell = buildControlCell( control, columnIndex );
- if( control.selected === columnIndex ){
- $cell.addClass( SELECTED_CLASS );
- }
- setSelectedText( $cell, control, columnIndex );
-
- // only add the handler to non-disabled controls
- if( !$cell.hasClass( DISABLED_CLASS ) ){
- $cell.click( function selectClick( ev ){
- var $cell = $( this );
- // don't re-select or fire event if already selected
- if( !$cell.hasClass( SELECTED_CLASS ) ){
- // only one can be selected - remove selected on all others, add it here
- var $otherSelected = $cell.parent().children( '.' + SELECTED_CLASS ).removeClass( SELECTED_CLASS );
- $otherSelected.each( function(){
- setSelectedText( $( this ), control, columnIndex );
- });
-
- $cell.addClass( SELECTED_CLASS );
- setSelectedText( $cell, control, columnIndex );
-
- // fire the event from the table itself, passing the id and index of selected
- var eventData = {},
- key = $cell.parent().attr( 'id' ),
- val = $cell.data( COLUMN_INDEX_DATA_KEY );
- eventData[ key ] = val;
- $cell.parents( '.peek' ).trigger( CHANGE_EVENT, eventData );
- }
- });
- }
- return $cell;
- }
-
- /** build a cell for a row that allows multiple selections */
- function buildMultiSelectCell( control, columnIndex ){
- var $cell = buildControlCell( control, columnIndex );
- // multiple selection - selected is an array
- if( control.selected && control.selected.indexOf( columnIndex ) !== -1 ){
- $cell.addClass( SELECTED_CLASS );
- }
- setSelectedText( $cell, control, columnIndex );
-
- // only add the handler to non-disabled controls
- if( !$cell.hasClass( DISABLED_CLASS ) ){
- $cell.click( function multiselectClick( ev ){
- var $cell = $( this );
- // can be more than one selected - toggle selected on this cell
- $cell.toggleClass( SELECTED_CLASS );
- setSelectedText( $cell, control, columnIndex );
- var selectedColumnIndeces = $cell.parent().find( '.' + SELECTED_CLASS ).map( function( i, e ){
- return $( e ).data( COLUMN_INDEX_DATA_KEY );
- });
- // fire the event from the table itself, passing the id and index of selected
- var eventData = {},
- key = $cell.parent().attr( 'id' ),
- val = jQuery.makeArray( selectedColumnIndeces );
- eventData[ key ] = val;
- $cell.parents( '.peek' ).trigger( CHANGE_EVENT, eventData );
- });
- }
- return $cell;
- }
-
- /** iterate over columns in peek and create a control for each */
- function buildControlCells( count, control ){
- var $cells = [];
- // build a control for each column - using a build fn based on control
- for( var columnIndex=0; columnIndex<count; columnIndex+=1 ){
- $cells.push( control.multiselect? buildMultiSelectCell( control, columnIndex )
- : buildSingleSelectCell( control, columnIndex ) );
- }
- return $cells;
- }
-
- /** build a row of controls for the peek */
- function buildControlRow( cellCount, control, includePrompts ){
- var $controlRow = $( '<tr/>' ).attr( 'id', control.id ).addClass( ROW_CLASS );
- if( includePrompts ){
- var $promptCell = $( '<td/>' ).addClass( PROMPT_CLASS ).text( control.label + ':' );
- $controlRow.append( $promptCell );
- }
- $controlRow.append( buildControlCells( cellCount, control ) );
- return $controlRow;
- }
-
- // ........................................................................
- /** add to the peek, using options for configuration, return the peek */
- function peekColumnSelector( options ){
- options = jQuery.extend( true, {}, defaults, options );
-
- var $peek = $( this ).addClass( PEEKCONTROL_CLASS ),
- $peektable = $peek.find( 'table' ),
- // get the size of the tables - width and height, number of comment rows
- columnCount = $peektable.find( 'th' ).size(),
- rowCount = $peektable.find( 'tr' ).size(),
- // get the rows containing text starting with the comment char (also make them grey)
- $commentRows = $peektable.find( 'td[colspan]' ).map( function( e, i ){
- var $this = $( this );
- if( $this.text() && $this.text().match( new RegExp( '^' + options.commentChar ) ) ){
- return $( this ).css( 'color', 'grey' ).parent().get(0);
- }
- return null;
- });
-
- // should comment rows in the peek be hidden?
- if( options.hideCommentRows ){
- $commentRows.hide();
- rowCount -= $commentRows.size();
- }
- //console.debug( 'rowCount:', rowCount, 'columnCount:', columnCount, '$commentRows:', $commentRows );
-
- // should a first column of control prompts be added?
- if( options.includePrompts ){
- var $topLeft = $( '<th/>' ).addClass( 'top-left' ).text( options.topLeftContent )
- .attr( 'rowspan', rowCount );
- $peektable.find( 'tr' ).first().prepend( $topLeft );
- }
-
- // save either the options column name or the parsed text of each column header in html5 data attr and text
- var $headers = $peektable.find( 'th:not(.top-left)' ).each( function( i, e ){
- var $this = $( this ),
- // can be '1.name' or '1'
- text = $this.text().replace( /^\d+\.*/, '' ),
- name = options.columnNames[ i ] || text;
- $this.attr( 'data-' + COLUMN_NAME_DATA_KEY, name )
- .text( ( i + 1 ) + (( name )?( '.' + name ):( '' )) );
- });
-
- // allow renaming of columns when the header is clicked
- if( options.renameColumns ){
- $headers.addClass( RENAMABLE_HEADER_CLASS )
- .click( function renameColumn(){
- // prompt for new name
- var $this = $( this ),
- index = $this.index() + ( options.includePrompts? 0: 1 ),
- prevName = $this.data( COLUMN_NAME_DATA_KEY ),
- newColumnName = prompt( 'New column name:', prevName );
- if( newColumnName !== null && newColumnName !== prevName ){
- // set the new text and data
- $this.text( index + ( newColumnName?( '.' + newColumnName ):'' ) )
- .data( COLUMN_NAME_DATA_KEY, newColumnName )
- .attr( 'data-', COLUMN_NAME_DATA_KEY, newColumnName );
- // fire event for new column names
- var columnNames = jQuery.makeArray(
- $this.parent().children( 'th:not(.top-left)' ).map( function(){
- return $( this ).data( COLUMN_NAME_DATA_KEY );
- }));
- $this.parents( '.peek' ).trigger( RENAME_EVENT, columnNames );
- }
- });
- }
-
- // build a row for each control
- options.controls.forEach( function( control, i ){
- validateControl( control );
- var $controlRow = buildControlRow( columnCount, control, options.includePrompts );
- $peektable.find( 'tbody' ).append( $controlRow );
- });
- return this;
- }
-
- // ........................................................................
- // as jq plugin
- jQuery.fn.extend({
- peekColumnSelector : function $peekColumnSelector( options ){
- return this.map( function(){
- return peekColumnSelector.call( this, options );
- });
- }
- });
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/jq-plugins/ui/search-input.js
--- a/client/galaxy/scripts/jq-plugins/ui/search-input.js
+++ /dev/null
@@ -1,159 +0,0 @@
-// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
-// Uses AMD or browser globals to create a jQuery plugin.
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
- // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
- // relying on jquery being loaded globally* in order to preserve plugins.
- define([], factory);
- } else {
- // Browser globals
- factory(jQuery);
- }
-
-}(function () {
- var _l = window._l || function( s ){ return s; };
-
- /** searchInput: (jQuery plugin)
- * Creates a search input, a clear button, and loading indicator
- * within the selected node.
- *
- * When the user either presses return or enters some minimal number
- * of characters, a callback is called. Pressing ESC when the input
- * is focused will clear the input and call a separate callback.
- */
- function searchInput( parentNode, options ){
-//TODO: consolidate with tool menu functionality, use there
- var KEYCODE_ESC = 27,
- KEYCODE_RETURN = 13,
- $parentNode = $( parentNode ),
- firstSearch = true,
- defaults = {
- initialVal : '',
- name : 'search',
- placeholder : 'search',
- classes : '',
- onclear : function(){},
- onfirstsearch : null,
- onsearch : function( inputVal ){},
- minSearchLen : 0,
- escWillClear : true,
- oninit : function(){}
- };
-
- // .................................................................... input rendering and events
- // visually clear the search, trigger an event, and call the callback
- function clearSearchInput( event ){
- var $input = $( this ).parent().children( 'input' );
- //console.debug( this, 'clear', $input );
- $input.focus().val( '' ).trigger( 'clear:searchInput' );
- options.onclear();
- }
-
- // search for searchTerms, trigger an event, call the appropo callback (based on whether this is the first)
- function search( event, searchTerms ){
- //console.debug( this, 'searching', searchTerms );
- //TODO: I don't think this is classic jq custom event form? search.searchInput?
- $( this ).trigger( 'search:searchInput', searchTerms );
- if( typeof options.onfirstsearch === 'function' && firstSearch ){
- firstSearch = false;
- options.onfirstsearch( searchTerms );
- } else {
- options.onsearch( searchTerms );
- }
- }
-
- // .................................................................... input rendering and events
- function inputTemplate(){
- // class search-query is bootstrap 2.3 style that now lives in base.less
- return [ '<input type="text" name="', options.name, '" placeholder="', options.placeholder, '" ',
- 'class="search-query ', options.classes, '" ', '/>' ].join( '' );
- }
-
- // the search input that responds to keyboard events and displays the search value
- function $input(){
- return $( inputTemplate() )
- // select all text on a focus
- .focus( function( event ){
- $( this ).select();
- })
- // attach behaviors to esc, return if desired, search on some min len string
- .keyup( function( event ){
- event.preventDefault();
- event.stopPropagation();
-//TODO: doesn't work
- if( !$( this ).val() ){ $( this ).blur(); }
-
- // esc key will clear if desired
- if( event.which === KEYCODE_ESC && options.escWillClear ){
- clearSearchInput.call( this, event );
-
- } else {
- var searchTerms = $( this ).val();
- // return key or the search string len > minSearchLen (if not 0) triggers search
- if( ( event.which === KEYCODE_RETURN )
- || ( options.minSearchLen && searchTerms.length >= options.minSearchLen ) ){
- search.call( this, event, searchTerms );
- } else if( !searchTerms.length ){
- clearSearchInput.call( this, event );
- }
- }
- })
- .on( 'change', function( event ){
- search.call( this, event, $( this ).val() );
- })
- .val( options.initialVal );
- }
-
- // .................................................................... clear button rendering and events
- // a button for clearing the search bar, placed on the right hand side
- function $clearBtn(){
- return $([ '<span class="search-clear fa fa-times-circle" ',
- 'title="', _l( 'clear search (esc)' ), '"></span>' ].join('') )
- .tooltip({ placement: 'bottom' })
- .click( function( event ){
- clearSearchInput.call( this, event );
- });
- }
-
- // .................................................................... loadingIndicator rendering
- // a button for clearing the search bar, placed on the right hand side
- function $loadingIndicator(){
- return $([ '<span class="search-loading fa fa-spinner fa-spin" ',
- 'title="', _l( 'loading...' ), '"></span>' ].join('') )
- .hide().tooltip({ placement: 'bottom' });
- }
-
- // .................................................................... commands
- // visually swap the load, clear buttons
- function toggleLoadingIndicator(){
- $parentNode.find( '.search-loading' ).toggle();
- $parentNode.find( '.search-clear' ).toggle();
- }
-
- // .................................................................... init
- // string command (not constructor)
- if( jQuery.type( options ) === 'string' ){
- if( options === 'toggle-loading' ){
- toggleLoadingIndicator();
- }
- return $parentNode;
- }
-
- // initial render
- if( jQuery.type( options ) === 'object' ){
- options = jQuery.extend( true, {}, defaults, options );
- }
- //NOTE: prepended
- return $parentNode.addClass( 'search-input' ).prepend([ $input(), $clearBtn(), $loadingIndicator() ]);
- }
-
- // as jq plugin
- jQuery.fn.extend({
- searchInput : function $searchInput( options ){
- return this.each( function(){
- return searchInput( this, options );
- });
- }
- });
-}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/dataset/dataset-li-edit.js
--- a/client/galaxy/scripts/mvc/dataset/dataset-li-edit.js
+++ b/client/galaxy/scripts/mvc/dataset/dataset-li-edit.js
@@ -3,7 +3,7 @@
"mvc/dataset/dataset-li",
"mvc/tags",
"mvc/annotations",
- "jq-plugins/ui/fa-icon-button",
+ "ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization"
], function( STATES, DATASET_LI, TAGS, ANNOTATIONS, faIconButton, BASE_MVC, _l ){
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/dataset/dataset-li.js
--- a/client/galaxy/scripts/mvc/dataset/dataset-li.js
+++ b/client/galaxy/scripts/mvc/dataset/dataset-li.js
@@ -1,7 +1,7 @@
define([
"mvc/list/list-item",
"mvc/dataset/states",
- "jq-plugins/ui/fa-icon-button",
+ "ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization"
], function( LIST_ITEM, STATES, faIconButton, BASE_MVC, _l ){
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/history/hdca-li-edit.js
--- a/client/galaxy/scripts/mvc/history/hdca-li-edit.js
+++ b/client/galaxy/scripts/mvc/history/hdca-li-edit.js
@@ -1,7 +1,7 @@
define([
"mvc/dataset/states",
"mvc/history/hdca-li",
- "jq-plugins/ui/fa-icon-button",
+ "ui/fa-icon-button",
"utils/localization"
], function( STATES, HDCA_LI, faIconButton, _l ){
//==============================================================================
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/history/history-panel-edit.js
--- a/client/galaxy/scripts/mvc/history/history-panel-edit.js
+++ b/client/galaxy/scripts/mvc/history/history-panel-edit.js
@@ -7,7 +7,7 @@
"mvc/history/hdca-li-edit",
"mvc/tags",
"mvc/annotations",
- "jq-plugins/ui/fa-icon-button",
+ "ui/fa-icon-button",
"mvc/ui/popup-menu",
"utils/localization"
], function(
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/history/history-panel.js
--- a/client/galaxy/scripts/mvc/history/history-panel.js
+++ b/client/galaxy/scripts/mvc/history/history-panel.js
@@ -6,10 +6,10 @@
"mvc/history/hdca-li",
"mvc/collection/collection-panel",
"mvc/user/user-model",
- "jq-plugins/ui/fa-icon-button",
+ "ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization",
- "jq-plugins/ui/search-input"
+ "ui/search-input"
], function(
LIST_PANEL,
HISTORY_MODEL,
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/history/multi-panel.js
--- a/client/galaxy/scripts/mvc/history/multi-panel.js
+++ b/client/galaxy/scripts/mvc/history/multi-panel.js
@@ -3,8 +3,8 @@
"mvc/history/history-panel-edit",
"mvc/base-mvc",
"utils/ajax-queue",
- "jq-plugins/ui/mode-button",
- "jq-plugins/ui/search-input"
+ "ui/mode-button",
+ "ui/search-input"
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
window.HISTORY_MODEL = HISTORY_MODEL;
//==============================================================================
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/list/list-panel.js
--- a/client/galaxy/scripts/mvc/list/list-panel.js
+++ b/client/galaxy/scripts/mvc/list/list-panel.js
@@ -1,9 +1,9 @@
define([
"mvc/list/list-item",
- "jq-plugins/ui/loading-indicator",
+ "ui/loading-indicator",
"mvc/base-mvc",
"utils/localization",
- "jq-plugins/ui/search-input"
+ "ui/search-input"
], function( LIST_ITEM, LoadingIndicator, BASE_MVC, _l ){
/* ============================================================================
TODO:
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/mvc/upload/upload-view.js
--- a/client/galaxy/scripts/mvc/upload/upload-view.js
+++ b/client/galaxy/scripts/mvc/upload/upload-view.js
@@ -6,7 +6,6 @@
"mvc/upload/upload-ftp",
"mvc/ui/ui-popover",
"mvc/ui/ui-modal",
- "mvc/ui",
"utils/uploadbox"],
function( Utils,
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/ui/fa-icon-button.js
--- /dev/null
+++ b/client/galaxy/scripts/ui/fa-icon-button.js
@@ -0,0 +1,48 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define([], factory);
+ } else {
+ root.faIconButton = factory();
+ }
+
+}(this, function () {
+//============================================================================
+ /** Returns a jQuery object containing a clickable font-awesome button.
+ * options:
+ * tooltipConfig : option map for bootstrap tool tip
+ * classes : array of class names (will always be classed as icon-btn)
+ * disabled : T/F - add the 'disabled' class?
+ * title : tooltip/title string
+ * target : optional href target
+ * href : optional href
+ * faIcon : which font awesome icon to use
+ * onclick : function to call when the button is clicked
+ */
+ var faIconButton = function( options ){
+ options = options || {};
+ options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' };
+
+ options.classes = [ 'icon-btn' ].concat( options.classes || [] );
+ if( options.disabled ){
+ options.classes.push( 'disabled' );
+ }
+
+ var html = [
+ '<a class="', options.classes.join( ' ' ), '"',
+ (( options.title )?( ' title="' + options.title + '"' ):( '' )),
+ (( !options.disabled && options.target )? ( ' target="' + options.target + '"' ):( '' )),
+ ' href="', (( !options.disabled && options.href )?( options.href ):( 'javascript:void(0);' )), '">',
+ // could go with something less specific here - like 'html'
+ '<span class="fa ', options.faIcon, '"></span>',
+ '</a>'
+ ].join( '' );
+ var $button = $( html ).tooltip( options.tooltipConfig );
+ if( _.isFunction( options.onclick ) ){
+ $button.click( options.onclick );
+ }
+ return $button;
+ };
+
+//============================================================================
+ return faIconButton;
+}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/ui/filter-control.js
--- /dev/null
+++ b/client/galaxy/scripts/ui/filter-control.js
@@ -0,0 +1,204 @@
+// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
+// Uses AMD or browser globals to create a jQuery plugin.
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery'], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+
+}(function ($) {
+ //==============================================================================
+ /**
+ * Template function that produces a bootstrap dropdown to replace the
+ * vanilla HTML select input. Pass in an array of options and an initial selection:
+ * $( '.my-div' ).append( dropDownSelect( [ 'option1', 'option2' ], 'option2' );
+ *
+ * When the user changes the selected option a 'change.dropdown-select' event will
+ * fire with both the jq event and the new selection text as arguments.
+ *
+ * Get the currently selected choice using:
+ * var userChoice = $( '.my-div .dropdown-select .dropdown-select-selected' ).text();
+ *
+ */
+ function dropDownSelect( options, selected ){
+ // replacement for vanilla select element using bootstrap dropdowns instead
+ selected = selected || (( !_.isEmpty( options ) )?( options[0] ):( '' ));
+ var $select = $([
+ '<div class="dropdown-select btn-group">',
+ '<button type="button" class="btn btn-default">',
+ '<span class="dropdown-select-selected">' + selected + '</span>',
+ '</button>',
+ '</div>'
+ ].join( '\n' ));
+
+ // if there's only one option, do not style/create as buttons, dropdown - use simple span
+ // otherwise, a dropdown displaying the current selection
+ if( options && options.length > 1 ){
+ $select.find( 'button' )
+ .addClass( 'dropdown-toggle' ).attr( 'data-toggle', 'dropdown' )
+ .append( ' <span class="caret"></span>' );
+ $select.append([
+ '<ul class="dropdown-menu" role="menu">',
+ _.map( options, function( option ){
+ return [
+ '<li><a href="javascript:void(0)">', option, '</a></li>'
+ ].join( '' );
+ }).join( '\n' ),
+ '</ul>'
+ ].join( '\n' ));
+ }
+
+ // trigger 'change.dropdown-select' when a new selection is made using the dropdown
+ function selectThis( event ){
+ var $this = $( this ),
+ $select = $this.parents( '.dropdown-select' ),
+ newSelection = $this.text();
+ $select.find( '.dropdown-select-selected' ).text( newSelection );
+ $select.trigger( 'change.dropdown-select', newSelection );
+ }
+
+ $select.find( 'a' ).click( selectThis );
+ return $select;
+ }
+
+ //==============================================================================
+ /**
+ * Creates a three part bootstrap button group (key, op, value) meant to
+ * allow the user control of filters (e.g. { key: 'name', op: 'contains', value: 'my_history' })
+ *
+ * Each field uses a dropDownSelect (from ui.js) to allow selection
+ * (with the 'value' field appearing as an input when set to do so).
+ *
+ * Any change or update in any of the fields will trigger a 'change.filter-control'
+ * event which will be passed an object containing those fields (as the example above).
+ *
+ * Pass in an array of possible filter objects to control what the user can select.
+ * Each filter object should have:
+ * key : generally the attribute name on which to filter something
+ * ops : an array of 1 or more filter operations (e.g. [ 'is', '<', 'contains', '!=' ])
+ * values (optional) : an array of possible values for the filter (e.g. [ 'true', 'false' ])
+ * @example:
+ * $( '.my-div' ).filterControl({
+ * filters : [
+ * { key: 'name', ops: [ 'is exactly', 'contains' ] }
+ * { key: 'deleted', ops: [ 'is' ], values: [ 'true', 'false' ] }
+ * ]
+ * });
+ * // after initialization, you can prog. get the current value using:
+ * $( '.my-div' ).filterControl( 'val' )
+ *
+ */
+ function FilterControl( element, options ){
+ return this.init( element, options );
+ }
+ /** the data key that this object will be stored under in the DOM element */
+ FilterControl.prototype.DATA_KEY = 'filter-control';
+
+ /** parses options, sets up instance vars, and does initial render */
+ FilterControl.prototype.init = function _init( element, options ){
+ options = options || { filters: [] };
+ this.$element = $( element ).addClass( 'filter-control btn-group' );
+ this.options = jQuery.extend( true, {}, this.defaults, options );
+
+ this.currFilter = this.options.filters[0];
+ return this.render();
+ };
+
+ /** render (or re-render) the controls on the element */
+ FilterControl.prototype.render = function _render(){
+ this.$element.empty()
+ .append([ this._renderKeySelect(), this._renderOpSelect(), this._renderValueInput() ]);
+ return this;
+ };
+
+ /** render the key dropDownSelect, bind a change event to it, and return it */
+ FilterControl.prototype._renderKeySelect = function __renderKeySelect(){
+ var filterControl = this;
+ var keys = this.options.filters.map( function( filter ){
+ return filter.key;
+ });
+ this.$keySelect = dropDownSelect( keys, this.currFilter.key )
+ .addClass( 'filter-control-key' )
+ .on( 'change.dropdown-select', function( event, selection ){
+ filterControl.currFilter = _.findWhere( filterControl.options.filters, { key: selection });
+ // when the filter/key changes, re-render the control entirely
+ filterControl.render()._triggerChange();
+ });
+ return this.$keySelect;
+ };
+
+ /** render the op dropDownSelect, bind a change event to it, and return it */
+ FilterControl.prototype._renderOpSelect = function __renderOpSelect(){
+ var filterControl = this,
+ ops = this.currFilter.ops;
+ //TODO: search for currOp in avail. ops: use that for selected if there; otherwise: first op
+ this.$opSelect = dropDownSelect( ops, ops[0] )
+ .addClass( 'filter-control-op' )
+ .on( 'change.dropdown-select', function( event, selection ){
+ filterControl._triggerChange();
+ });
+ return this.$opSelect;
+ };
+
+ /** render the value control, bind a change event to it, and return it */
+ FilterControl.prototype._renderValueInput = function __renderValueInput(){
+ var filterControl = this;
+ // if a values attribute is prov. on the filter - make this a dropdown; otherwise, use an input
+ if( this.currFilter.values ){
+ this.$valueSelect = dropDownSelect( this.currFilter.values, this.currFilter.values[0] )
+ .on( 'change.dropdown-select', function( event, selection ){
+ filterControl._triggerChange();
+ });
+ } else {
+ //TODO: allow setting a value type (mainly for which html5 input to use: range, number, etc.)
+ this.$valueSelect = $( '<input/>' ).addClass( 'form-control' )
+ .on( 'change', function( event, value ){
+ filterControl._triggerChange();
+ });
+ }
+ this.$valueSelect.addClass( 'filter-control-value' );
+ return this.$valueSelect;
+ };
+
+ /** return the current state/setting for the filter as a three key object: key, op, value */
+ FilterControl.prototype.val = function _val(){
+ var key = this.$element.find( '.filter-control-key .dropdown-select-selected' ).text(),
+ op = this.$element.find( '.filter-control-op .dropdown-select-selected' ).text(),
+ // handle either a dropdown or plain input
+ $value = this.$element.find( '.filter-control-value' ),
+ value = ( $value.hasClass( 'dropdown-select' ) )?( $value.find( '.dropdown-select-selected' ).text() )
+ :( $value.val() );
+ return { key: key, op: op, value: value };
+ };
+
+ // single point of change for change event
+ FilterControl.prototype._triggerChange = function __triggerChange(){
+ this.$element.trigger( 'change.filter-control', this.val() );
+ };
+
+ // as jq plugin
+ jQuery.fn.extend({
+ filterControl : function $filterControl( options ){
+ var nonOptionsArgs = jQuery.makeArray( arguments ).slice( 1 );
+ return this.map( function(){
+ var $this = $( this ),
+ data = $this.data( FilterControl.prototype.DATA_KEY );
+
+ if( jQuery.type( options ) === 'object' ){
+ data = new FilterControl( $this, options );
+ $this.data( FilterControl.prototype.DATA_KEY, data );
+ }
+ if( data && jQuery.type( options ) === 'string' ){
+ var fn = data[ options ];
+ if( jQuery.type( fn ) === 'function' ){
+ return fn.apply( data, nonOptionsArgs );
+ }
+ }
+ return this;
+ });
+ }
+ });
+}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/ui/loading-indicator.js
--- /dev/null
+++ b/client/galaxy/scripts/ui/loading-indicator.js
@@ -0,0 +1,98 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([], factory);
+ } else {
+ // Browser globals
+ root.LoadingIndicator = factory();
+ }
+
+//============================================================================
+}(this, function () {
+ //TODO: too specific to history panel
+ function LoadingIndicator( $where, options ){
+
+ var self = this;
+ // defaults
+ options = jQuery.extend({
+ cover : false
+ }, options || {} );
+
+ function render(){
+ var html = [
+ '<div class="loading-indicator">',
+ '<div class="loading-indicator-text">',
+ '<span class="fa fa-spinner fa-spin fa-lg"></span>',
+ '<span class="loading-indicator-message">loading...</span>',
+ '</div>',
+ '</div>'
+ ].join( '\n' );
+
+ var $indicator = $( html ).hide().css( options.css || {
+ position : 'fixed'
+ }),
+ $text = $indicator.children( '.loading-indicator-text' );
+
+ if( options.cover ){
+ $indicator.css({
+ 'z-index' : 2,
+ top : $where.css( 'top' ),
+ bottom : $where.css( 'bottom' ),
+ left : $where.css( 'left' ),
+ right : $where.css( 'right' ),
+ opacity : 0.5,
+ 'background-color': 'white',
+ 'text-align': 'center'
+ });
+ $text = $indicator.children( '.loading-indicator-text' ).css({
+ 'margin-top' : '20px'
+ });
+
+ } else {
+ $text = $indicator.children( '.loading-indicator-text' ).css({
+ margin : '12px 0px 0px 10px',
+ opacity : '0.85',
+ color : 'grey'
+ });
+ $text.children( '.loading-indicator-message' ).css({
+ margin : '0px 8px 0px 0px',
+ 'font-style' : 'italic'
+ });
+ }
+ return $indicator;
+ }
+
+ self.show = function( msg, speed, callback ){
+ msg = msg || 'loading...';
+ speed = speed || 'fast';
+ // remove previous
+ $where.parent().find( '.loading-indicator' ).remove();
+ // since position is fixed - we insert as sibling
+ self.$indicator = render().insertBefore( $where );
+ self.message( msg );
+ self.$indicator.fadeIn( speed, callback );
+ return self;
+ };
+
+ self.message = function( msg ){
+ self.$indicator.find( 'i' ).text( msg );
+ };
+
+ self.hide = function( speed, callback ){
+ speed = speed || 'fast';
+ if( self.$indicator && self.$indicator.size() ){
+ self.$indicator.fadeOut( speed, function(){
+ self.$indicator.remove();
+ if( callback ){ callback(); }
+ });
+ } else {
+ if( callback ){ callback(); }
+ }
+ return self;
+ };
+ return self;
+ }
+
+//============================================================================
+ return LoadingIndicator;
+}));
diff -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf -r 336a1e96bf5196955ec9f1b45d0446c42d4bc9ae client/galaxy/scripts/ui/mode-button.js
--- /dev/null
+++ b/client/galaxy/scripts/ui/mode-button.js
@@ -0,0 +1,191 @@
+// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
+// Uses AMD or browser globals to create a jQuery plugin.
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
+ // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
+ // relying on jquery being loaded globally* in order to preserve plugins.
+ define([], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+
+}(function () {
+
+ /** Multi 'mode' button (or any element really) that changes the html
+ * contents of itself when clicked. Pass in an ordered list of
+ * objects with 'html' and (optional) onclick functions.
+ *
+ * When clicked in a particular node, the onclick function will
+ * be called (with the element as this) and the element will
+ * switch to the next mode, replacing its html content with
+ * that mode's html.
+ *
+ * If there is no next mode, the element will switch back to
+ * the first mode.
+ * @example:
+ * $( '.myElement' ).modeButton({
+ * modes : [
+ * {
+ * mode: 'bler',
+ * html: '<h5>Bler</h5>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'red' );
+ * }
+ * },
+ * {
+ * mode: 'bloo',
+ * html: '<h4>Bloo</h4>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'blue' );
+ * }
+ * },
+ * {
+ * mode: 'blah',
+ * html: '<h3>Blah</h3>',
+ * onclick : function(){
+ * $( 'body' ).css( 'background-color', 'grey' );
+ * }
+ * },
+ * ]
+ * });
+ * $( '.myElement' ).modeButton( 'callModeFn', 'bler' );
+ */
+ /** constructor */
+ function ModeButton( element, options ){
+ this.currModeIndex = 0;
+ return this._init( element, options );
+ }
+
+ /** html5 data key to store this object inside an element */
+ ModeButton.prototype.DATA_KEY = 'mode-button';
+ /** default options */
+ ModeButton.prototype.defaults = {
+ switchModesOnClick : true
+ };
+
+ // ---- private interface
+ /** set up options, intial mode, and the click handler */
+ ModeButton.prototype._init = function _init( element, options ){
+ //console.debug( 'ModeButton._init:', element, options );
+ options = options || {};
+ this.$element = $( element );
+ this.options = $.extend( true, {}, this.defaults, options );
+ if( !options.modes ){
+ throw new Error( 'ModeButton requires a "modes" array' );
+ }
+
+ var modeButton = this;
+ this.$element.click( function _ModeButtonClick( event ){
+ // call the curr mode fn
+ modeButton.callModeFn();
+ // inc the curr mode index
+ if( modeButton.options.switchModesOnClick ){ modeButton._incModeIndex(); }
+ // set the element html
+ $( this ).html( modeButton.options.modes[ modeButton.currModeIndex ].html );
+ });
+ return this.reset();
+ };
+ /** increment the mode index to the next in the array, looping back to zero if at the last */
+ ModeButton.prototype._incModeIndex = function _incModeIndex(){
+ this.currModeIndex += 1;
+ if( this.currModeIndex >= this.options.modes.length ){
+ this.currModeIndex = 0;
+ }
+ return this;
+ };
+ /** get the mode index in the modes array for the given key (mode name) */
+ ModeButton.prototype._getModeIndex = function _getModeIndex( modeKey ){
+ for( var i=0; i<this.options.modes.length; i+=1 ){
+ if( this.options.modes[ i ].mode === modeKey ){ return i; }
+ }
+ throw new Error( 'mode not found: ' + modeKey );
+ };
+ /** set the current mode to the one with the given index and set button html */
+ ModeButton.prototype._setModeByIndex = function _setModeByIndex( index ){
+ var newMode = this.options.modes[ index ];
+ if( !newMode ){
+ throw new Error( 'mode index not found: ' + index );
+ }
+ this.currModeIndex = index;
+ if( newMode.html ){
+ this.$element.html( newMode.html );
+ }
+ return this;
+ };
+
+ // ---- public interface
+ /** get the current mode object (not just the mode name) */
+ ModeButton.prototype.currentMode = function currentMode(){
+ return this.options.modes[ this.currModeIndex ];
+ };
+ /** return the mode key of the current mode */
+ ModeButton.prototype.current = function current(){
+ // sugar for returning mode name
+ return this.currentMode().mode;
+ };
+ /** get the mode with the given modeKey or the current mode if modeKey is undefined */
+ ModeButton.prototype.getMode = function getMode( modeKey ){
+ if( !modeKey ){ return this.currentMode(); }
+ return this.options.modes[( this._getModeIndex( modeKey ) )];
+ };
+ /** T/F if the button has the given mode */
+ ModeButton.prototype.hasMode = function hasMode( modeKey ){
+ try {
+ return !!this.getMode( modeKey );
+ } catch( err ){}
+ return false;
+ };
+ /** set the current mode to the mode with the given name */
+ ModeButton.prototype.setMode = function setMode( modeKey ){
+ return this._setModeByIndex( this._getModeIndex( modeKey ) );
+ };
+ /** reset to the initial mode */
+ ModeButton.prototype.reset = function reset(){
+ this.currModeIndex = 0;
+ if( this.options.initialMode ){
+ this.currModeIndex = this._getModeIndex( this.options.initialMode );
+ }
+ return this._setModeByIndex( this.currModeIndex );
+ };
+ /** manually call the click handler of the given mode */
+ ModeButton.prototype.callModeFn = function callModeFn( modeKey ){
+ var modeFn = this.getMode( modeKey ).onclick;
+ if( modeFn && $.type( modeFn === 'function' ) ){
+ // call with the element as context (std jquery pattern)
+ return modeFn.call( this.$element.get(0) );
+ }
+ return undefined;
+ };
+
+ // as jq plugin
+ $.fn.modeButton = function $modeButton( options ){
+ if( !this.size() ){ return this; }
+
+ //TODO: does map still work with jq multi selection (i.e. $( '.class-for-many-btns' ).modeButton)?
+ if( $.type( options ) === 'object' ){
+ return this.map( function(){
+ var $this = $( this );
+ $this.data( 'mode-button', new ModeButton( $this, options ) );
+ return this;
+ });
+ }
+
+ var $first = $( this[0] ),
+ button = $first.data( 'mode-button' );
+
+ if( !button ){
+ throw new Error( 'modeButton needs an options object or string name of a function' );
+ }
+
+ if( button && $.type( options ) === 'string' ){
+ var fnName = options;
+ if( button && $.type( button[ fnName ] ) === 'function' ){
+ return button[ fnName ].apply( button, $.makeArray( arguments ).slice( 1 ) );
+ }
+ }
+ return button;
+ };
+
+}));
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: insert empty string instead of None for requirement.version
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6f73d9d8de65/
Changeset: 6f73d9d8de65
User: martenson
Date: 2014-12-09 18:40:39+00:00
Summary: insert empty string instead of None for requirement.version
Affected #: 1 file
diff -r 31c50ee295791a8797ff8391986a469778091ee9 -r 6f73d9d8de65e81d16049f4507777ca5df7dc1bf templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -362,7 +362,7 @@
<a href="#" class="icon-btn" title="Underlying versions" tabindex="0" data-toggle="popover" data-placement="bottom" data-content=
"
%for i, requirement in enumerate( tool.requirements ):
- ${ requirement.name } v ${ requirement.version } ${ '' if i + 1 == len( tool.requirements ) else ' | ' }
+ ${ requirement.name } ${ ('v ' + requirement.version ) if requirement.version else ' ' } ${ '' if i + 1 == len( tool.requirements ) else ' | ' }
%endfor
"
onclick="$(function () {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: remove ui.js; modularize icon button from ui.js
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/31c50ee29579/
Changeset: 31c50ee29579
User: carlfeberhard
Date: 2014-12-09 18:28:57+00:00
Summary: Client build: remove ui.js; modularize icon button from ui.js
Affected #: 21 files
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/mvc/data.js
--- a/client/galaxy/scripts/mvc/data.js
+++ b/client/galaxy/scripts/mvc/data.js
@@ -1,5 +1,5 @@
// Additional dependencies: jQuery, underscore.
-define(['mvc/ui/ui-modal', 'mvc/ui/ui-frames'], function(Modal, Frames) {
+define(['mvc/ui/ui-modal', 'mvc/ui/ui-frames', 'mvc/ui/icon-button'], function(Modal, Frames, mod_icon_btn) {
/**
* Dataset metedata.
@@ -447,8 +447,8 @@
}
// create the icon
- var btn_viz = new IconButtonView({
- model : new IconButton({
+ var btn_viz = new mod_icon_btn.IconButtonView({
+ model : new mod_icon_btn.IconButton({
title : 'Visualize',
icon_class : 'chart_curve',
id : 'btn_viz'
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/mvc/ui.js
--- a/client/galaxy/scripts/mvc/ui.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * functions for creating major ui elements
- */
-
-/**
- * backbone model for icon buttons
- */
-var IconButton = Backbone.Model.extend({
- defaults: {
- title : "",
- icon_class : "",
- on_click : null,
- menu_options : null,
- is_menu_button : true,
- id : null,
- href : null,
- target : null,
- enabled : true,
- visible : true,
- tooltip_config : {}
- }
-});
-
-/**
- * backbone view for icon buttons
- */
-var IconButtonView = Backbone.View.extend({
-
- initialize : function(){
- // better rendering this way
- this.model.attributes.tooltip_config = { placement : 'bottom' };
- this.model.bind( 'change', this.render, this );
- },
-
- render : function( ){
- // hide tooltip
- this.$el.tooltip( 'hide' );
-
- var new_elem = this.template( this.model.toJSON() );
- // configure tooltip
- new_elem.tooltip( this.model.get( 'tooltip_config' ));
- this.$el.replaceWith( new_elem );
- this.setElement( new_elem );
- return this;
- },
-
- events : {
- 'click' : 'click'
- },
-
- click : function( event ){
- // if on_click pass to that function
- if( _.isFunction( this.model.get( 'on_click' ) ) ){
- this.model.get( 'on_click' )( event );
- return false;
- }
- // otherwise, bubble up ( to href or whatever )
- return true;
- },
-
- // generate html element
- template: function( options ){
- var buffer = 'title="' + options.title + '" class="icon-button';
-
- if( options.is_menu_button ){
- buffer += ' menu-button';
- }
-
- buffer += ' ' + options.icon_class;
-
- if( !options.enabled ){
- buffer += '_disabled';
- }
-
- // close class tag
- buffer += '"';
-
- if( options.id ){
- buffer += ' id="' + options.id + '"';
- }
-
- buffer += ' href="' + options.href + '"';
- // add target for href
- if( options.target ){
- buffer += ' target="' + options.target + '"';
- }
- // set visibility
- if( !options.visible ){
- buffer += ' style="display: none;"';
- }
-
- // enabled/disabled
- if ( options.enabled ){
- buffer = '<a ' + buffer + '/>';
- } else {
- buffer = '<span ' + buffer + '/>';
- }
-
- // return element
- return $( buffer );
- }
-} );
-
-// define collection
-var IconButtonCollection = Backbone.Collection.extend({
- model: IconButton
-});
-
-/**
- * menu with multiple icon buttons
- * views are not needed nor used for individual buttons
- */
-var IconButtonMenuView = Backbone.View.extend({
-
- tagName: 'div',
-
- initialize: function(){
- this.render();
- },
-
- render: function(){
- // initialize icon buttons
- var self = this;
- this.collection.each(function(button){
- // create and add icon button to menu
- var elt = $('<a/>')
- .attr('href', 'javascript:void(0)')
- .attr('title', button.attributes.title)
- .addClass('icon-button menu-button')
- .addClass(button.attributes.icon_class)
- .appendTo(self.$el)
- .click(button.attributes.on_click);
-
- // configure tooltip
- if (button.attributes.tooltip_config){
- elt.tooltip(button.attributes.tooltip_config);
- }
-
- // add popup menu to icon
- var menu_options = button.get('options');
- if (menu_options){
- make_popupmenu(elt, menu_options);
- }
- });
-
- // return
- return this;
- }
-});
-
-/**
- * Returns an IconButtonMenuView for the provided configuration.
- * Configuration is a list of dictionaries where each dictionary
- * defines an icon button. Each dictionary must have the following
- * elements: icon_class, title, and on_click.
- */
-var create_icon_buttons_menu = function(config, global_config)
-{
- // initialize global configuration
- if (!global_config) global_config = {};
-
- // create and initialize menu
- var buttons = new IconButtonCollection(
- _.map(config, function(button_config){
- return new IconButton(_.extend(button_config, global_config));
- })
- );
-
- // return menu
- return new IconButtonMenuView( {collection: buttons} );
-};
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/mvc/ui/icon-button.js
--- /dev/null
+++ b/client/galaxy/scripts/mvc/ui/icon-button.js
@@ -0,0 +1,183 @@
+define([
+ //jquery
+ //backbone
+], function(){
+//=============================================================================
+/**
+ * backbone model for icon buttons
+ */
+var IconButton = Backbone.Model.extend({
+ defaults: {
+ title : "",
+ icon_class : "",
+ on_click : null,
+ menu_options : null,
+ is_menu_button : true,
+ id : null,
+ href : null,
+ target : null,
+ enabled : true,
+ visible : true,
+ tooltip_config : {}
+ }
+});
+
+/**
+ * backbone view for icon buttons
+ */
+var IconButtonView = Backbone.View.extend({
+
+ initialize : function(){
+ // better rendering this way
+ this.model.attributes.tooltip_config = { placement : 'bottom' };
+ this.model.bind( 'change', this.render, this );
+ },
+
+ render : function( ){
+ // hide tooltip
+ this.$el.tooltip( 'hide' );
+
+ var new_elem = this.template( this.model.toJSON() );
+ // configure tooltip
+ new_elem.tooltip( this.model.get( 'tooltip_config' ));
+ this.$el.replaceWith( new_elem );
+ this.setElement( new_elem );
+ return this;
+ },
+
+ events : {
+ 'click' : 'click'
+ },
+
+ click : function( event ){
+ // if on_click pass to that function
+ if( _.isFunction( this.model.get( 'on_click' ) ) ){
+ this.model.get( 'on_click' )( event );
+ return false;
+ }
+ // otherwise, bubble up ( to href or whatever )
+ return true;
+ },
+
+ // generate html element
+ template: function( options ){
+ var buffer = 'title="' + options.title + '" class="icon-button';
+
+ if( options.is_menu_button ){
+ buffer += ' menu-button';
+ }
+
+ buffer += ' ' + options.icon_class;
+
+ if( !options.enabled ){
+ buffer += '_disabled';
+ }
+
+ // close class tag
+ buffer += '"';
+
+ if( options.id ){
+ buffer += ' id="' + options.id + '"';
+ }
+
+ buffer += ' href="' + options.href + '"';
+ // add target for href
+ if( options.target ){
+ buffer += ' target="' + options.target + '"';
+ }
+ // set visibility
+ if( !options.visible ){
+ buffer += ' style="display: none;"';
+ }
+
+ // enabled/disabled
+ if ( options.enabled ){
+ buffer = '<a ' + buffer + '/>';
+ } else {
+ buffer = '<span ' + buffer + '/>';
+ }
+
+ // return element
+ return $( buffer );
+ }
+} );
+
+// define collection
+var IconButtonCollection = Backbone.Collection.extend({
+ model: IconButton
+});
+
+/**
+ * menu with multiple icon buttons
+ * views are not needed nor used for individual buttons
+ */
+var IconButtonMenuView = Backbone.View.extend({
+
+ tagName: 'div',
+
+ initialize: function(){
+ this.render();
+ },
+
+ render: function(){
+ // initialize icon buttons
+ var self = this;
+ this.collection.each(function(button){
+ // create and add icon button to menu
+ var elt = $('<a/>')
+ .attr('href', 'javascript:void(0)')
+ .attr('title', button.attributes.title)
+ .addClass('icon-button menu-button')
+ .addClass(button.attributes.icon_class)
+ .appendTo(self.$el)
+ .click(button.attributes.on_click);
+
+ // configure tooltip
+ if (button.attributes.tooltip_config){
+ elt.tooltip(button.attributes.tooltip_config);
+ }
+
+ // add popup menu to icon
+ var menu_options = button.get('options');
+ if (menu_options){
+ make_popupmenu(elt, menu_options);
+ }
+ });
+
+ // return
+ return this;
+ }
+});
+
+/**
+ * Returns an IconButtonMenuView for the provided configuration.
+ * Configuration is a list of dictionaries where each dictionary
+ * defines an icon button. Each dictionary must have the following
+ * elements: icon_class, title, and on_click.
+ */
+var create_icon_buttons_menu = function(config, global_config)
+{
+ // initialize global configuration
+ if (!global_config) global_config = {};
+
+ // create and initialize menu
+ var buttons = new IconButtonCollection(
+ _.map(config, function(button_config){
+ return new IconButton(_.extend(button_config, global_config));
+ })
+ );
+
+ // return menu
+ return new IconButtonMenuView( {collection: buttons} );
+};
+
+
+//=============================================================================
+ return {
+ IconButton : IconButton,
+ IconButtonView : IconButtonView,
+ IconButtonCollection : IconButtonCollection,
+ IconButtonMenuView : IconButtonMenuView,
+ create_icon_buttons_menu: create_icon_buttons_menu
+ };
+})
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/viz/circster.js
--- a/client/galaxy/scripts/viz/circster.js
+++ b/client/galaxy/scripts/viz/circster.js
@@ -2,8 +2,9 @@
require(
[
'utils/utils',
+ 'mvc/ui/icon-button',
'libs/farbtastic',
-], function(mod_utils)
+], function(mod_utils, mod_icon_btn)
{
// load css
mod_utils.cssLoadFile("static/style/circster.css");
@@ -1075,7 +1076,7 @@
$('#center .unified-panel-header-inner').append(galaxy_config.app.viz_config.title + " " + galaxy_config.app.viz_config.dbkey);
// setup menu
- var menu = create_icon_buttons_menu([
+ var menu = mod_icon_btn.create_icon_buttons_menu([
{
icon_class: 'plus-button', title: 'Add tracks', on_click: function()
{
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/viz/phyloviz.js
--- a/client/galaxy/scripts/viz/phyloviz.js
+++ b/client/galaxy/scripts/viz/phyloviz.js
@@ -1,4 +1,9 @@
-define(['libs/d3', 'viz/visualization', 'mvc/data'], function(d3, visualization_mod, data_mod) {
+define([
+ 'libs/d3',
+ 'viz/visualization',
+ 'mvc/data',
+ 'mvc/ui/icon-button'
+], function(d3, visualization_mod, data_mod, mod_icon_btn) {
/**
* Base class of any menus that takes in user interaction. Contains checking methods.
@@ -720,7 +725,7 @@
initRightHeaderBtns : function(){
var self = this;
- rightMenu = create_icon_buttons_menu([
+ rightMenu = mod_icon_btn.create_icon_buttons_menu([
{ icon_class: 'gear', title: 'PhyloViz Settings', on_click: function(){
$("#SettingsMenu").show();
self.settingsMenu.updateUI();
@@ -748,7 +753,7 @@
initNavBtns: function() {
var self = this,
- navMenu = create_icon_buttons_menu([
+ navMenu = mod_icon_btn.create_icon_buttons_menu([
{ icon_class: 'zoom-in', title: 'Zoom in', on_click: function() {
self.phylovizView.zoomAndPan({ zoom : "+"});
} },
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/viz/sweepster.js
--- a/client/galaxy/scripts/viz/sweepster.js
+++ b/client/galaxy/scripts/viz/sweepster.js
@@ -3,8 +3,8 @@
* genomic visualization.
*/
-define(["libs/underscore", "libs/d3", "viz/trackster/util", "viz/visualization", "viz/trackster/tracks", "mvc/tools", "mvc/data", "utils/config"],
- function(_, d3, util, visualization, tracks, tools, data, config) {
+define(["libs/underscore", "libs/d3", "viz/trackster/util", "viz/visualization", "viz/trackster/tracks", "mvc/tools", "mvc/data", "utils/config", "mvc/ui/icon-button"],
+ function(_, d3, util, visualization, tracks, tools, data, config, mod_icon_btn) {
/**
* A collection of tool input settings. Object is useful for keeping a list of settings
@@ -375,7 +375,7 @@
settings_div.toggle();
self.trigger('run_on_dataset', settings);
});
- var icon_menu = create_icon_buttons_menu([
+ var icon_menu = mod_icon_btn.create_icon_buttons_menu([
{
title: 'Settings',
icon_class: 'gear track-settings',
@@ -486,7 +486,7 @@
// Add buttons for adding/removing parameter.
var self = this,
- menu = create_icon_buttons_menu([
+ menu = mod_icon_btn.create_icon_buttons_menu([
{
title: 'Add parameter to tree',
icon_class: 'plus-button',
@@ -723,7 +723,7 @@
// Help includes text and a close button.
var help_div = $(this.helpText).addClass('help'),
- close_button = create_icon_buttons_menu([
+ close_button = mod_icon_btn.create_icon_buttons_menu([
{
title: 'Close',
icon_class: 'cross-circle',
@@ -745,7 +745,7 @@
this.handle_node_clicks();
// Set up visualization menu.
- var menu = create_icon_buttons_menu(
+ var menu = mod_icon_btn.create_icon_buttons_menu(
[
// Save.
/*
@@ -939,4 +939,4 @@
SweepsterVisualizationView: SweepsterVisualizationView
};
-});
\ No newline at end of file
+});
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 client/galaxy/scripts/viz/trackster.js
--- a/client/galaxy/scripts/viz/trackster.js
+++ b/client/galaxy/scripts/viz/trackster.js
@@ -12,6 +12,7 @@
[
// load js libraries
'utils/utils',
+ 'mvc/ui/icon-button',
'libs/jquery/jquery.event.drag',
'libs/jquery/jquery.event.hover',
'libs/jquery/jquery.mousewheel',
@@ -21,7 +22,7 @@
'libs/jquery/jquery.form',
'libs/jquery/jquery.rating',
'mvc/ui'
-], function(mod_utils)
+], function(mod_utils, mod_icon_btn)
{
// load css
mod_utils.cssLoadFile("static/style/jquery.rating.css");
@@ -101,7 +102,7 @@
*/
createButtonMenu: function() {
var self = this,
- menu = create_icon_buttons_menu([
+ menu = mod_icon_btn.create_icon_buttons_menu([
{ icon_class: 'plus-button', title: 'Add tracks', on_click: function() {
visualization.select_datasets(galaxy_config.root + "visualization/list_current_history_datasets", galaxy_config.root + "api/datasets", { 'f-dbkey': view.dbkey },
function(new_tracks) {
@@ -571,4 +572,4 @@
GalaxyApp : TracksterView
};
-});
\ No newline at end of file
+});
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/mvc/data.js
--- a/static/scripts/mvc/data.js
+++ b/static/scripts/mvc/data.js
@@ -1,5 +1,5 @@
// Additional dependencies: jQuery, underscore.
-define(['mvc/ui/ui-modal', 'mvc/ui/ui-frames'], function(Modal, Frames) {
+define(['mvc/ui/ui-modal', 'mvc/ui/ui-frames', 'mvc/ui/icon-button'], function(Modal, Frames, mod_icon_btn) {
/**
* Dataset metedata.
@@ -447,8 +447,8 @@
}
// create the icon
- var btn_viz = new IconButtonView({
- model : new IconButton({
+ var btn_viz = new mod_icon_btn.IconButtonView({
+ model : new mod_icon_btn.IconButton({
title : 'Visualize',
icon_class : 'chart_curve',
id : 'btn_viz'
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * functions for creating major ui elements
- */
-
-/**
- * backbone model for icon buttons
- */
-var IconButton = Backbone.Model.extend({
- defaults: {
- title : "",
- icon_class : "",
- on_click : null,
- menu_options : null,
- is_menu_button : true,
- id : null,
- href : null,
- target : null,
- enabled : true,
- visible : true,
- tooltip_config : {}
- }
-});
-
-/**
- * backbone view for icon buttons
- */
-var IconButtonView = Backbone.View.extend({
-
- initialize : function(){
- // better rendering this way
- this.model.attributes.tooltip_config = { placement : 'bottom' };
- this.model.bind( 'change', this.render, this );
- },
-
- render : function( ){
- // hide tooltip
- this.$el.tooltip( 'hide' );
-
- var new_elem = this.template( this.model.toJSON() );
- // configure tooltip
- new_elem.tooltip( this.model.get( 'tooltip_config' ));
- this.$el.replaceWith( new_elem );
- this.setElement( new_elem );
- return this;
- },
-
- events : {
- 'click' : 'click'
- },
-
- click : function( event ){
- // if on_click pass to that function
- if( _.isFunction( this.model.get( 'on_click' ) ) ){
- this.model.get( 'on_click' )( event );
- return false;
- }
- // otherwise, bubble up ( to href or whatever )
- return true;
- },
-
- // generate html element
- template: function( options ){
- var buffer = 'title="' + options.title + '" class="icon-button';
-
- if( options.is_menu_button ){
- buffer += ' menu-button';
- }
-
- buffer += ' ' + options.icon_class;
-
- if( !options.enabled ){
- buffer += '_disabled';
- }
-
- // close class tag
- buffer += '"';
-
- if( options.id ){
- buffer += ' id="' + options.id + '"';
- }
-
- buffer += ' href="' + options.href + '"';
- // add target for href
- if( options.target ){
- buffer += ' target="' + options.target + '"';
- }
- // set visibility
- if( !options.visible ){
- buffer += ' style="display: none;"';
- }
-
- // enabled/disabled
- if ( options.enabled ){
- buffer = '<a ' + buffer + '/>';
- } else {
- buffer = '<span ' + buffer + '/>';
- }
-
- // return element
- return $( buffer );
- }
-} );
-
-// define collection
-var IconButtonCollection = Backbone.Collection.extend({
- model: IconButton
-});
-
-/**
- * menu with multiple icon buttons
- * views are not needed nor used for individual buttons
- */
-var IconButtonMenuView = Backbone.View.extend({
-
- tagName: 'div',
-
- initialize: function(){
- this.render();
- },
-
- render: function(){
- // initialize icon buttons
- var self = this;
- this.collection.each(function(button){
- // create and add icon button to menu
- var elt = $('<a/>')
- .attr('href', 'javascript:void(0)')
- .attr('title', button.attributes.title)
- .addClass('icon-button menu-button')
- .addClass(button.attributes.icon_class)
- .appendTo(self.$el)
- .click(button.attributes.on_click);
-
- // configure tooltip
- if (button.attributes.tooltip_config){
- elt.tooltip(button.attributes.tooltip_config);
- }
-
- // add popup menu to icon
- var menu_options = button.get('options');
- if (menu_options){
- make_popupmenu(elt, menu_options);
- }
- });
-
- // return
- return this;
- }
-});
-
-/**
- * Returns an IconButtonMenuView for the provided configuration.
- * Configuration is a list of dictionaries where each dictionary
- * defines an icon button. Each dictionary must have the following
- * elements: icon_class, title, and on_click.
- */
-var create_icon_buttons_menu = function(config, global_config)
-{
- // initialize global configuration
- if (!global_config) global_config = {};
-
- // create and initialize menu
- var buttons = new IconButtonCollection(
- _.map(config, function(button_config){
- return new IconButton(_.extend(button_config, global_config));
- })
- );
-
- // return menu
- return new IconButtonMenuView( {collection: buttons} );
-};
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/mvc/ui/icon-button.js
--- /dev/null
+++ b/static/scripts/mvc/ui/icon-button.js
@@ -0,0 +1,183 @@
+define([
+ //jquery
+ //backbone
+], function(){
+//=============================================================================
+/**
+ * backbone model for icon buttons
+ */
+var IconButton = Backbone.Model.extend({
+ defaults: {
+ title : "",
+ icon_class : "",
+ on_click : null,
+ menu_options : null,
+ is_menu_button : true,
+ id : null,
+ href : null,
+ target : null,
+ enabled : true,
+ visible : true,
+ tooltip_config : {}
+ }
+});
+
+/**
+ * backbone view for icon buttons
+ */
+var IconButtonView = Backbone.View.extend({
+
+ initialize : function(){
+ // better rendering this way
+ this.model.attributes.tooltip_config = { placement : 'bottom' };
+ this.model.bind( 'change', this.render, this );
+ },
+
+ render : function( ){
+ // hide tooltip
+ this.$el.tooltip( 'hide' );
+
+ var new_elem = this.template( this.model.toJSON() );
+ // configure tooltip
+ new_elem.tooltip( this.model.get( 'tooltip_config' ));
+ this.$el.replaceWith( new_elem );
+ this.setElement( new_elem );
+ return this;
+ },
+
+ events : {
+ 'click' : 'click'
+ },
+
+ click : function( event ){
+ // if on_click pass to that function
+ if( _.isFunction( this.model.get( 'on_click' ) ) ){
+ this.model.get( 'on_click' )( event );
+ return false;
+ }
+ // otherwise, bubble up ( to href or whatever )
+ return true;
+ },
+
+ // generate html element
+ template: function( options ){
+ var buffer = 'title="' + options.title + '" class="icon-button';
+
+ if( options.is_menu_button ){
+ buffer += ' menu-button';
+ }
+
+ buffer += ' ' + options.icon_class;
+
+ if( !options.enabled ){
+ buffer += '_disabled';
+ }
+
+ // close class tag
+ buffer += '"';
+
+ if( options.id ){
+ buffer += ' id="' + options.id + '"';
+ }
+
+ buffer += ' href="' + options.href + '"';
+ // add target for href
+ if( options.target ){
+ buffer += ' target="' + options.target + '"';
+ }
+ // set visibility
+ if( !options.visible ){
+ buffer += ' style="display: none;"';
+ }
+
+ // enabled/disabled
+ if ( options.enabled ){
+ buffer = '<a ' + buffer + '/>';
+ } else {
+ buffer = '<span ' + buffer + '/>';
+ }
+
+ // return element
+ return $( buffer );
+ }
+} );
+
+// define collection
+var IconButtonCollection = Backbone.Collection.extend({
+ model: IconButton
+});
+
+/**
+ * menu with multiple icon buttons
+ * views are not needed nor used for individual buttons
+ */
+var IconButtonMenuView = Backbone.View.extend({
+
+ tagName: 'div',
+
+ initialize: function(){
+ this.render();
+ },
+
+ render: function(){
+ // initialize icon buttons
+ var self = this;
+ this.collection.each(function(button){
+ // create and add icon button to menu
+ var elt = $('<a/>')
+ .attr('href', 'javascript:void(0)')
+ .attr('title', button.attributes.title)
+ .addClass('icon-button menu-button')
+ .addClass(button.attributes.icon_class)
+ .appendTo(self.$el)
+ .click(button.attributes.on_click);
+
+ // configure tooltip
+ if (button.attributes.tooltip_config){
+ elt.tooltip(button.attributes.tooltip_config);
+ }
+
+ // add popup menu to icon
+ var menu_options = button.get('options');
+ if (menu_options){
+ make_popupmenu(elt, menu_options);
+ }
+ });
+
+ // return
+ return this;
+ }
+});
+
+/**
+ * Returns an IconButtonMenuView for the provided configuration.
+ * Configuration is a list of dictionaries where each dictionary
+ * defines an icon button. Each dictionary must have the following
+ * elements: icon_class, title, and on_click.
+ */
+var create_icon_buttons_menu = function(config, global_config)
+{
+ // initialize global configuration
+ if (!global_config) global_config = {};
+
+ // create and initialize menu
+ var buttons = new IconButtonCollection(
+ _.map(config, function(button_config){
+ return new IconButton(_.extend(button_config, global_config));
+ })
+ );
+
+ // return menu
+ return new IconButtonMenuView( {collection: buttons} );
+};
+
+
+//=============================================================================
+ return {
+ IconButton : IconButton,
+ IconButtonView : IconButtonView,
+ IconButtonCollection : IconButtonCollection,
+ IconButtonMenuView : IconButtonMenuView,
+ create_icon_buttons_menu: create_icon_buttons_menu
+ };
+})
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/mvc/data.js
--- a/static/scripts/packed/mvc/data.js
+++ b/static/scripts/packed/mvc/data.js
@@ -1,1 +1,1 @@
-define(["mvc/ui/ui-modal","mvc/ui/ui-frames"],function(j,i){var g=Backbone.Model.extend({});var b=Backbone.Model.extend({defaults:{id:"",type:"",name:"",hda_ldda:"hda",metadata:null},initialize:function(){if(!this.get("metadata")){this._set_metadata()}this.on("change",this._set_metadata,this)},_set_metadata:function(){var m=new g();_.each(_.keys(this.attributes),function(n){if(n.indexOf("metadata_")===0){var o=n.split("metadata_")[1];m.set(o,this.attributes[n]);delete this.attributes[n]}},this);this.set("metadata",m,{silent:true})},get_metadata:function(m){return this.attributes.metadata.get(m)},urlRoot:galaxy_config.root+"api/datasets"});var h=b.extend({defaults:_.extend({},b.prototype.defaults,{chunk_url:null,first_data_chunk:null,chunk_index:-1,at_eof:false}),initialize:function(m){b.prototype.initialize.call(this);this.attributes.chunk_index=(this.attributes.first_data_chunk?1:0);this.attributes.chunk_url=galaxy_config.root+"dataset/display?dataset_id="+this.id;this.attributes.url_viz=galaxy_config.root+"visualization"},get_next_chunk:function(){if(this.attributes.at_eof){return null}var m=this,n=$.Deferred();$.getJSON(this.attributes.chunk_url,{chunk:m.attributes.chunk_index++}).success(function(o){var p;if(o.ck_data!==""){p=o}else{m.attributes.at_eof=true;p=null}n.resolve(p)});return n}});var e=Backbone.Collection.extend({model:b});var a=Backbone.View.extend({initialize:function(m){this.row_count=0;this.loading_chunk=false;this.header_color="#AAA";this.dark_row_color="#DDD";new d({model:m.model,$el:this.$el})},expand_to_container:function(){if(this.$el.height()<this.scroll_elt.height()){this.attempt_to_fetch()}},attempt_to_fetch:function(n){var m=this;if(!this.loading_chunk&&this.scrolled_to_bottom()){this.loading_chunk=true;this.loading_indicator.show();$.when(m.model.get_next_chunk()).then(function(o){if(o){m._renderChunk(o);m.loading_chunk=false}m.loading_indicator.hide();m.expand_to_container()})}},render:function(){this.loading_indicator=$("<div/>").attr("id","loading_indicator");this.$el.append(this.loading_indicator);var p=$("<table/>").attr({id:"content_table",cellpadding:0});this.$el.append(p);var m=this.model.get_metadata("column_names"),q=$("<tr/>").css("background-color",this.header_color).appendTo(p);if(m){q.append("<th>"+m.join("</th><th>")+"</th>")}var o=this,n=this.model.get("first_data_chunk");if(n){this._renderChunk(n)}else{$.when(o.model.get_next_chunk()).then(function(r){o._renderChunk(r)})}this.scroll_elt.scroll(function(){o.attempt_to_fetch()})},scrolled_to_bottom:function(){return false},_renderCell:function(p,m,q){var n=$("<td>").text(p);var o=this.model.get_metadata("column_types");if(q!==undefined){n.attr("colspan",q).addClass("stringalign")}else{if(o){if(m<o.length){if(o[m]==="str"||o[m]==="list"){n.addClass("stringalign")}}}}return n},_renderRow:function(m){var n=m.split("\t"),p=$("<tr>"),o=this.model.get_metadata("columns");if(this.row_count%2!==0){p.css("background-color",this.dark_row_color)}if(n.length===o){_.each(n,function(r,q){p.append(this._renderCell(r,q))},this)}else{if(n.length>o){_.each(n.slice(0,o-1),function(r,q){p.append(this._renderCell(r,q))},this);p.append(this._renderCell(n.slice(o-1).join("\t"),o-1))}else{if(o>5&&n.length===o-1){_.each(n,function(r,q){p.append(this._renderCell(r,q))},this);p.append($("<td>"))}else{p.append(this._renderCell(m,0,o))}}}this.row_count++;return p},_renderChunk:function(m){var n=this.$el.find("table");_.each(m.ck_data.split("\n"),function(o,p){if(o!==""){n.append(this._renderRow(o))}},this)}});var f=a.extend({initialize:function(m){a.prototype.initialize.call(this,m);scroll_elt=_.find(this.$el.parents(),function(n){return $(n).css("overflow")==="auto"});if(!scroll_elt){scroll_elt=window}this.scroll_elt=$(scroll_elt)},scrolled_to_bottom:function(){return(this.$el.height()-this.scroll_elt.scrollTop()-this.scroll_elt.height()<=0)}});var l=a.extend({initialize:function(m){a.prototype.initialize.call(this,m);this.scroll_elt=this.$el.css({position:"relative",overflow:"scroll",height:this.options.height||"500px"})},scrolled_to_bottom:function(){return this.$el.scrollTop()+this.$el.innerHeight()>=this.el.scrollHeight}});var d=Backbone.View.extend({col:{chrom:null,start:null,end:null},url_viz:null,dataset_id:null,genome_build:null,file_ext:null,initialize:function(o){var r=parent.Galaxy;if(r&&r.modal){this.modal=r.modal}if(r&&r.frame){this.frame=r.frame}if(!this.modal||!this.frame){return}var n=o.model;var q=n.get("metadata");if(!n.get("file_ext")){return}this.file_ext=n.get("file_ext");if(this.file_ext=="bed"){if(q.get("chromCol")&&q.get("startCol")&&q.get("endCol")){this.col.chrom=q.get("chromCol")-1;this.col.start=q.get("startCol")-1;this.col.end=q.get("endCol")-1}else{console.log("TabularButtonTrackster : Bed-file metadata incomplete.");return}}if(this.file_ext=="vcf"){function p(t,u){for(var s=0;s<u.length;s++){if(u[s].match(t)){return s}}return -1}this.col.chrom=p("Chrom",q.get("column_names"));this.col.start=p("Pos",q.get("column_names"));this.col.end=null;if(this.col.chrom==-1||this.col.start==-1){console.log("TabularButtonTrackster : VCF-file metadata incomplete.");return}}if(this.col.chrom===undefined){return}if(n.id){this.dataset_id=n.id}else{console.log("TabularButtonTrackster : Dataset identification is missing.");return}if(n.get("url_viz")){this.url_viz=n.get("url_viz")}else{console.log("TabularButtonTrackster : Url for visualization controller is missing.");return}if(n.get("genome_build")){this.genome_build=n.get("genome_build")}var m=new IconButtonView({model:new IconButton({title:"Visualize",icon_class:"chart_curve",id:"btn_viz"})});this.setElement(o.$el);this.$el.append(m.render().$el);this.hide()},events:{"mouseover tr":"show",mouseleave:"hide"},show:function(r){function q(w){return !isNaN(parseFloat(w))&&isFinite(w)}if(this.col.chrom===null){return}var v=$(r.target).parent();var s=v.children().eq(this.col.chrom).html();var m=v.children().eq(this.col.start).html();var o=this.col.end?v.children().eq(this.col.end).html():m;if(!s.match("^#")&&s!==""&&q(m)){var u={dataset_id:this.dataset_id,gene_region:s+":"+m+"-"+o};var p=v.offset();var n=p.left-10;var t=p.top-$(window).scrollTop()+3;$("#btn_viz").css({position:"fixed",top:t+"px",left:n+"px"});$("#btn_viz").off("click");$("#btn_viz").click(this.create_trackster_action(this.url_viz,u,this.genome_build));$("#btn_viz").show()}else{$("#btn_viz").hide()}},hide:function(){this.$el.find("#btn_viz").hide()},create_trackster_action:function(m,p,o){var n=this;return function(){var q={};if(o){q["f-dbkey"]=o}$.ajax({url:m+"/list_tracks?"+$.param(q),dataType:"html",error:function(){n.modal.show({title:"Something went wrong!",body:"Unfortunately we could not add this dataset to the track browser. Please try again or contact us.",buttons:{Cancel:function(){n.modal.hide()}}})},success:function(r){n.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){n.modal.hide()},"View in saved visualization":function(){n.modal.show({title:"Add Data to Saved Visualization",body:r,buttons:{Cancel:function(){n.modal.hide()},"Add to visualization":function(){n.modal.hide();n.modal.$el.find("input[name=id]:checked").each(function(){var s=$(this).val();p.id=s;n.frame.add({title:"Trackster",type:"url",content:m+"/trackster?"+$.param(p)})})}}})},"View in new visualization":function(){n.modal.hide();n.frame.add({title:"Trackster",type:"url",content:m+"/trackster?"+$.param(p)})}}})}});return false}}});var k=function(p,n,q,m){var o=new n({model:new p(q)});o.render();if(m){m.append(o.$el)}return o};var c=function(o){if(!o.model){o.model=new h(o.dataset_config)}var n=o.parent_elt;var p=o.embedded;delete o.embedded;delete o.parent_elt;delete o.dataset_config;var m=(p?new l(o):new f(o));m.render();if(n){n.append(m.$el);m.expand_to_container()}return m};return{Dataset:b,TabularDataset:h,DatasetCollection:e,TabularDatasetChunkedView:a,createTabularDatasetChunkedView:c}});
\ No newline at end of file
+define(["mvc/ui/ui-modal","mvc/ui/ui-frames","mvc/ui/icon-button"],function(k,j,f){var h=Backbone.Model.extend({});var b=Backbone.Model.extend({defaults:{id:"",type:"",name:"",hda_ldda:"hda",metadata:null},initialize:function(){if(!this.get("metadata")){this._set_metadata()}this.on("change",this._set_metadata,this)},_set_metadata:function(){var n=new h();_.each(_.keys(this.attributes),function(o){if(o.indexOf("metadata_")===0){var p=o.split("metadata_")[1];n.set(p,this.attributes[o]);delete this.attributes[o]}},this);this.set("metadata",n,{silent:true})},get_metadata:function(n){return this.attributes.metadata.get(n)},urlRoot:galaxy_config.root+"api/datasets"});var i=b.extend({defaults:_.extend({},b.prototype.defaults,{chunk_url:null,first_data_chunk:null,chunk_index:-1,at_eof:false}),initialize:function(n){b.prototype.initialize.call(this);this.attributes.chunk_index=(this.attributes.first_data_chunk?1:0);this.attributes.chunk_url=galaxy_config.root+"dataset/display?dataset_id="+this.id;this.attributes.url_viz=galaxy_config.root+"visualization"},get_next_chunk:function(){if(this.attributes.at_eof){return null}var n=this,o=$.Deferred();$.getJSON(this.attributes.chunk_url,{chunk:n.attributes.chunk_index++}).success(function(p){var q;if(p.ck_data!==""){q=p}else{n.attributes.at_eof=true;q=null}o.resolve(q)});return o}});var e=Backbone.Collection.extend({model:b});var a=Backbone.View.extend({initialize:function(n){this.row_count=0;this.loading_chunk=false;this.header_color="#AAA";this.dark_row_color="#DDD";new d({model:n.model,$el:this.$el})},expand_to_container:function(){if(this.$el.height()<this.scroll_elt.height()){this.attempt_to_fetch()}},attempt_to_fetch:function(o){var n=this;if(!this.loading_chunk&&this.scrolled_to_bottom()){this.loading_chunk=true;this.loading_indicator.show();$.when(n.model.get_next_chunk()).then(function(p){if(p){n._renderChunk(p);n.loading_chunk=false}n.loading_indicator.hide();n.expand_to_container()})}},render:function(){this.loading_indicator=$("<div/>").attr("id","loading_indicator");this.$el.append(this.loading_indicator);var q=$("<table/>").attr({id:"content_table",cellpadding:0});this.$el.append(q);var n=this.model.get_metadata("column_names"),r=$("<tr/>").css("background-color",this.header_color).appendTo(q);if(n){r.append("<th>"+n.join("</th><th>")+"</th>")}var p=this,o=this.model.get("first_data_chunk");if(o){this._renderChunk(o)}else{$.when(p.model.get_next_chunk()).then(function(s){p._renderChunk(s)})}this.scroll_elt.scroll(function(){p.attempt_to_fetch()})},scrolled_to_bottom:function(){return false},_renderCell:function(q,n,r){var o=$("<td>").text(q);var p=this.model.get_metadata("column_types");if(r!==undefined){o.attr("colspan",r).addClass("stringalign")}else{if(p){if(n<p.length){if(p[n]==="str"||p[n]==="list"){o.addClass("stringalign")}}}}return o},_renderRow:function(n){var o=n.split("\t"),q=$("<tr>"),p=this.model.get_metadata("columns");if(this.row_count%2!==0){q.css("background-color",this.dark_row_color)}if(o.length===p){_.each(o,function(s,r){q.append(this._renderCell(s,r))},this)}else{if(o.length>p){_.each(o.slice(0,p-1),function(s,r){q.append(this._renderCell(s,r))},this);q.append(this._renderCell(o.slice(p-1).join("\t"),p-1))}else{if(p>5&&o.length===p-1){_.each(o,function(s,r){q.append(this._renderCell(s,r))},this);q.append($("<td>"))}else{q.append(this._renderCell(n,0,p))}}}this.row_count++;return q},_renderChunk:function(n){var o=this.$el.find("table");_.each(n.ck_data.split("\n"),function(p,q){if(p!==""){o.append(this._renderRow(p))}},this)}});var g=a.extend({initialize:function(n){a.prototype.initialize.call(this,n);scroll_elt=_.find(this.$el.parents(),function(o){return $(o).css("overflow")==="auto"});if(!scroll_elt){scroll_elt=window}this.scroll_elt=$(scroll_elt)},scrolled_to_bottom:function(){return(this.$el.height()-this.scroll_elt.scrollTop()-this.scroll_elt.height()<=0)}});var m=a.extend({initialize:function(n){a.prototype.initialize.call(this,n);this.scroll_elt=this.$el.css({position:"relative",overflow:"scroll",height:this.options.height||"500px"})},scrolled_to_bottom:function(){return this.$el.scrollTop()+this.$el.innerHeight()>=this.el.scrollHeight}});var d=Backbone.View.extend({col:{chrom:null,start:null,end:null},url_viz:null,dataset_id:null,genome_build:null,file_ext:null,initialize:function(p){var s=parent.Galaxy;if(s&&s.modal){this.modal=s.modal}if(s&&s.frame){this.frame=s.frame}if(!this.modal||!this.frame){return}var o=p.model;var r=o.get("metadata");if(!o.get("file_ext")){return}this.file_ext=o.get("file_ext");if(this.file_ext=="bed"){if(r.get("chromCol")&&r.get("startCol")&&r.get("endCol")){this.col.chrom=r.get("chromCol")-1;this.col.start=r.get("startCol")-1;this.col.end=r.get("endCol")-1}else{console.log("TabularButtonTrackster : Bed-file metadata incomplete.");return}}if(this.file_ext=="vcf"){function q(u,v){for(var t=0;t<v.length;t++){if(v[t].match(u)){return t}}return -1}this.col.chrom=q("Chrom",r.get("column_names"));this.col.start=q("Pos",r.get("column_names"));this.col.end=null;if(this.col.chrom==-1||this.col.start==-1){console.log("TabularButtonTrackster : VCF-file metadata incomplete.");return}}if(this.col.chrom===undefined){return}if(o.id){this.dataset_id=o.id}else{console.log("TabularButtonTrackster : Dataset identification is missing.");return}if(o.get("url_viz")){this.url_viz=o.get("url_viz")}else{console.log("TabularButtonTrackster : Url for visualization controller is missing.");return}if(o.get("genome_build")){this.genome_build=o.get("genome_build")}var n=new f.IconButtonView({model:new f.IconButton({title:"Visualize",icon_class:"chart_curve",id:"btn_viz"})});this.setElement(p.$el);this.$el.append(n.render().$el);this.hide()},events:{"mouseover tr":"show",mouseleave:"hide"},show:function(s){function r(x){return !isNaN(parseFloat(x))&&isFinite(x)}if(this.col.chrom===null){return}var w=$(s.target).parent();var t=w.children().eq(this.col.chrom).html();var n=w.children().eq(this.col.start).html();var p=this.col.end?w.children().eq(this.col.end).html():n;if(!t.match("^#")&&t!==""&&r(n)){var v={dataset_id:this.dataset_id,gene_region:t+":"+n+"-"+p};var q=w.offset();var o=q.left-10;var u=q.top-$(window).scrollTop()+3;$("#btn_viz").css({position:"fixed",top:u+"px",left:o+"px"});$("#btn_viz").off("click");$("#btn_viz").click(this.create_trackster_action(this.url_viz,v,this.genome_build));$("#btn_viz").show()}else{$("#btn_viz").hide()}},hide:function(){this.$el.find("#btn_viz").hide()},create_trackster_action:function(n,q,p){var o=this;return function(){var r={};if(p){r["f-dbkey"]=p}$.ajax({url:n+"/list_tracks?"+$.param(r),dataType:"html",error:function(){o.modal.show({title:"Something went wrong!",body:"Unfortunately we could not add this dataset to the track browser. Please try again or contact us.",buttons:{Cancel:function(){o.modal.hide()}}})},success:function(s){o.modal.show({title:"View Data in a New or Saved Visualization",buttons:{Cancel:function(){o.modal.hide()},"View in saved visualization":function(){o.modal.show({title:"Add Data to Saved Visualization",body:s,buttons:{Cancel:function(){o.modal.hide()},"Add to visualization":function(){o.modal.hide();o.modal.$el.find("input[name=id]:checked").each(function(){var t=$(this).val();q.id=t;o.frame.add({title:"Trackster",type:"url",content:n+"/trackster?"+$.param(q)})})}}})},"View in new visualization":function(){o.modal.hide();o.frame.add({title:"Trackster",type:"url",content:n+"/trackster?"+$.param(q)})}}})}});return false}}});var l=function(q,o,r,n){var p=new o({model:new q(r)});p.render();if(n){n.append(p.$el)}return p};var c=function(p){if(!p.model){p.model=new i(p.dataset_config)}var o=p.parent_elt;var q=p.embedded;delete p.embedded;delete p.parent_elt;delete p.dataset_config;var n=(q?new m(p):new g(p));n.render();if(o){o.append(n.$el);n.expand_to_container()}return n};return{Dataset:b,TabularDataset:i,DatasetCollection:e,TabularDatasetChunkedView:a,createTabularDatasetChunkedView:c}});
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ /dev/null
@@ -1,1 +0,0 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/mvc/ui/icon-button.js
--- /dev/null
+++ b/static/scripts/packed/mvc/ui/icon-button.js
@@ -0,0 +1,1 @@
+define([],function(){var e=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var d=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var f=this.template(this.model.toJSON());f.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(f);this.setElement(f);return this},events:{click:"click"},click:function(f){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(f);return false}return true},template:function(g){var f='title="'+g.title+'" class="icon-button';if(g.is_menu_button){f+=" menu-button"}f+=" "+g.icon_class;if(!g.enabled){f+="_disabled"}f+='"';if(g.id){f+=' id="'+g.id+'"'}f+=' href="'+g.href+'"';if(g.target){f+=' target="'+g.target+'"'}if(!g.visible){f+=' style="display: none;"'}if(g.enabled){f="<a "+f+"/>"}else{f="<span "+f+"/>"}return $(f)}});var a=Backbone.Collection.extend({model:e});var b=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var f=this;this.collection.each(function(i){var g=$("<a/>").attr("href","javascript:void(0)").attr("title",i.attributes.title).addClass("icon-button menu-button").addClass(i.attributes.icon_class).appendTo(f.$el).click(i.attributes.on_click);if(i.attributes.tooltip_config){g.tooltip(i.attributes.tooltip_config)}var h=i.get("options");if(h){make_popupmenu(g,h)}});return this}});var c=function(g,f){if(!f){f={}}var h=new a(_.map(g,function(i){return new e(_.extend(i,f))}));return new b({collection:h})};return{IconButton:e,IconButtonView:d,IconButtonCollection:a,IconButtonMenuView:b,create_icon_buttons_menu:c}});
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/viz/circster.js
--- a/static/scripts/packed/viz/circster.js
+++ b/static/scripts/packed/viz/circster.js
@@ -1,1 +1,1 @@
-require(["utils/utils","libs/farbtastic",],function(a){a.cssLoadFile("static/style/circster.css")});define(["libs/underscore","libs/d3","viz/visualization","utils/config"],function(h,m,j,c){var n=Backbone.Model.extend({is_visible:function(r,o){var p=r.getBoundingClientRect(),q=$("svg")[0].getBoundingClientRect();if(p.right<0||p.left>q.right||p.bottom<0||p.top>q.bottom){return false}return true}});var i={drawTicks:function(s,r,w,q,o){var v=s.append("g").selectAll("g").data(r).enter().append("g").selectAll("g").data(w).enter().append("g").attr("class","tick").attr("transform",function(x){return"rotate("+(x.angle*180/Math.PI-90)+")translate("+x.radius+",0)"});var u=[],t=[],p=function(x){return x.angle>Math.PI?"end":null};if(o){u=[0,0,0,-4];t=[4,0,"",".35em"];p=null}else{u=[1,0,4,0];t=[0,4,".35em",""]}v.append("line").attr("x1",u[0]).attr("y1",u[1]).attr("x2",u[2]).attr("y1",u[3]).style("stroke","#000");return v.append("text").attr("x",t[0]).attr("y",t[1]).attr("dx",t[2]).attr("dy",t[3]).attr("text-anchor",p).attr("transform",q).text(function(x){return x.label})},formatNum:function(p,o){if(o===undefined){o=2}if(p===null){return null}var r=null;if(Math.abs(p)<1){r=p.toPrecision(o)}else{var q=Math.round(p.toPrecision(o));p=Math.abs(p);if(p<1000){r=q}else{if(p<1000000){r=Math.round((q/1000).toPrecision(3)).toFixed(0)+"K"}else{if(p<1000000000){r=Math.round((q/1000000).toPrecision(3)).toFixed(0)+"M"}}}}return r}};var d=Backbone.Model.extend({});var a=Backbone.View.extend({className:"circster",initialize:function(o){this.genome=o.genome;this.label_arc_height=50;this.scale=1;this.circular_views=null;this.chords_views=null;this.model.get("drawables").on("add",this.add_track,this);this.model.get("drawables").on("remove",this.remove_track,this);var p=this.model.get("config");p.get("arc_dataset_height").on("change:value",this.update_track_bounds,this);p.get("track_gap").on("change:value",this.update_track_bounds,this)},get_circular_tracks:function(){return this.model.get("drawables").filter(function(o){return o.get("track_type")!=="DiagonalHeatmapTrack"})},get_chord_tracks:function(){return this.model.get("drawables").filter(function(o){return o.get("track_type")==="DiagonalHeatmapTrack"})},get_tracks_bounds:function(){var q=this.get_circular_tracks(),s=this.model.get("config").get_value("arc_dataset_height"),r=this.model.get("config").get_value("track_gap"),o=Math.min(this.$el.width(),this.$el.height())-20,u=o/2-q.length*(s+r)+r-this.label_arc_height,t=m.range(u,o/2,s+r);var p=this;return h.map(t,function(v){return[v,v+s]})},render:function(){var x=this,o=x.$el.width(),w=x.$el.height(),t=this.get_circular_tracks(),r=this.get_chord_tracks(),q=x.model.get("config").get_value("total_gap"),s=this.get_tracks_bounds(),p=m.select(x.$el[0]).append("svg").attr("width",o).attr("height",w).attr("pointer-events","all").append("svg:g").call(m.behavior.zoom().on("zoom",function(){var y=m.event.scale;p.attr("transform","translate("+m.event.translate+") scale("+y+")");if(x.scale!==y){if(x.zoom_drag_timeout){clearTimeout(x.zoom_drag_timeout)}x.zoom_drag_timeout=setTimeout(function(){},400)}})).attr("transform","translate("+o/2+","+w/2+")").append("svg:g").attr("class","tracks");this.circular_views=t.map(function(z,A){var y=new e({el:p.append("g")[0],track:z,radius_bounds:s[A],genome:x.genome,total_gap:q});y.render();return y});this.chords_views=r.map(function(z){var y=new k({el:p.append("g")[0],track:z,radius_bounds:s[0],genome:x.genome,total_gap:q});y.render();return y});var v=this.circular_views[this.circular_views.length-1].radius_bounds[1],u=[v,v+this.label_arc_height];this.label_track_view=new b({el:p.append("g")[0],track:new d(),radius_bounds:u,genome:x.genome,total_gap:q});this.label_track_view.render()},add_track:function(u){var p=this.model.get("config").get_value("total_gap");if(u.get("track_type")==="DiagonalHeatmapTrack"){var q=this.circular_views[0].radius_bounds,t=new k({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:q,genome:this.genome,total_gap:p});t.render();this.chords_views.push(t)}else{var s=this.get_tracks_bounds();h.each(this.circular_views,function(v,w){v.update_radius_bounds(s[w])});h.each(this.chords_views,function(v){v.update_radius_bounds(s[0])});var r=this.circular_views.length,o=new e({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:s[r],genome:this.genome,total_gap:p});o.render();this.circular_views.push(o)}},remove_track:function(p,r,q){var o=this.circular_views[q.index];this.circular_views.splice(q.index,1);o.$el.remove();var s=this.get_tracks_bounds();h.each(this.circular_views,function(t,u){t.update_radius_bounds(s[u])})},update_track_bounds:function(){var o=this.get_tracks_bounds();h.each(this.circular_views,function(p,q){p.update_radius_bounds(o[q])});h.each(this.chords_views,function(p){p.update_radius_bounds(o[0])})}});var l=Backbone.View.extend({tagName:"g",initialize:function(o){this.bg_stroke="#ddd";this.loading_bg_fill="#ffc";this.bg_fill="#ddd";this.total_gap=o.total_gap;this.track=o.track;this.radius_bounds=o.radius_bounds;this.genome=o.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=m.select(this.$el[0])},get_fill_color:function(){var o=this.track.get("config").get_value("block_color");if(!o){o=this.track.get("config").get_value("color")}return o},render:function(){var s=this.parent_elt;var r=this.chroms_layout,u=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),o=s.selectAll("g").data(r).enter().append("svg:g"),q=o.append("path").attr("d",u).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);q.append("title").text(function(w){return w.data.chrom});var p=this,t=p.track.get("data_manager"),v=(t?t.data_is_ready():true);$.when(v).then(function(){$.when(p._render_data(s)).then(function(){q.style("fill",p.bg_fill);p.render_labels()})})},render_labels:function(){},update_radius_bounds:function(p){this.radius_bounds=p;var o=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",o);this._transition_chrom_data();this._transition_labels()},update_scale:function(r){var q=this.scale;this.scale=r;if(r<=q){return}var p=this,o=new n();this.parent_elt.selectAll("path.chrom-data").filter(function(t,s){return o.is_visible(this)}).each(function(y,u){var x=m.select(this),t=x.attr("chrom"),w=p.genome.get_chrom_region(t),v=p.track.get("data_manager"),s;if(!v.can_get_more_detailed_data(w)){return}s=p.track.get("data_manager").get_more_detailed_data(w,"Coverage",0,r);$.when(s).then(function(B){x.remove();p._update_data_bounds();var A=h.find(p.chroms_layout,function(C){return C.data.chrom===t});var z=p.get_fill_color();p._render_chrom_data(p.parent_elt,A,B).style("stroke",z).style("fill",z)})});return p},_transition_chrom_data:function(){var p=this.track,r=this.chroms_layout,o=this.parent_elt.selectAll("g>path.chrom-data"),s=o[0].length;if(s>0){var q=this;$.when(p.get("data_manager").get_genome_wide_data(this.genome)).then(function(v){var u=h.reject(h.map(v,function(w,x){var y=null,z=q._get_path_function(r[x],w);if(z){y=z(w.data)}return y}),function(w){return w===null});var t=p.get("config").get_value("color");o.each(function(x,w){m.select(this).transition().duration(1000).style("stroke",t).style("fill",t).attr("d",u[w])})})}},_transition_labels:function(){},_update_data_bounds:function(p){var o=this.data_bounds;this.data_bounds=p||this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));this._transition_chrom_data()},_render_data:function(r){var q=this,p=this.chroms_layout,o=this.track,s=$.Deferred();$.when(o.get("data_manager").get_genome_wide_data(this.genome)).then(function(u){q.data_bounds=q.get_data_bounds(u);o.get("config").set_value("min_value",q.data_bounds[0],{silent:true});o.get("config").set_value("max_value",q.data_bounds[1],{silent:true});layout_and_data=h.zip(p,u),chroms_data_layout=h.map(layout_and_data,function(v){var w=v[0],x=v[1];return q._render_chrom_data(r,w,x)});var t=q.get_fill_color();q.parent_elt.selectAll("path.chrom-data").style("stroke",t).style("fill",t);s.resolve(r)});return s},_render_chrom_data:function(o,p,q){},_get_path_function:function(p,o){},_chroms_layout:function(){var p=this.genome.get_chroms_info(),r=m.layout.pie().value(function(t){return t.len}).sort(null),s=r(p),o=2*Math.PI*this.total_gap/p.length,q=h.map(s,function(v,u){var t=v.endAngle-o;v.endAngle=(t>v.startAngle?t:v.startAngle);return v});return q}});var b=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);this.innerRadius=this.radius_bounds[0];this.radius_bounds[0]=this.radius_bounds[1];this.bg_stroke="#fff";this.bg_fill="#fff";this.min_arc_len=0.05},_render_data:function(q){var p=this,o=q.selectAll("g");o.selectAll("path").attr("id",function(u){return"label-"+u.data.chrom});o.append("svg:text").filter(function(u){return u.endAngle-u.startAngle>p.min_arc_len}).attr("text-anchor","middle").append("svg:textPath").attr("class","chrom-label").attr("xlink:href",function(u){return"#label-"+u.data.chrom}).attr("startOffset","25%").text(function(u){return u.data.chrom});var r=function(w){var u=(w.endAngle-w.startAngle)/w.value,v=m.range(0,w.value,25000000).map(function(x,y){return{radius:p.innerRadius,angle:x*u+w.startAngle,label:y===0?0:(y%3?null:p.formatNum(x))}});if(v.length<4){v[v.length-1].label=p.formatNum(Math.round((v[v.length-1].angle-w.startAngle)/u))}return v};var t=function(u){return u.angle>Math.PI?"rotate(180)translate(-16)":null};var s=h.filter(this.chroms_layout,function(u){return u.endAngle-u.startAngle>p.min_arc_len});this.drawTicks(this.parent_elt,s,r,t)}});h.extend(b.prototype,i);var g=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);var p=this.track.get("config");p.get("min_value").on("change:value",this._update_min_max,this);p.get("max_value").on("change:value",this._update_min_max,this);p.get("color").on("change:value",this._transition_chrom_data,this)},_update_min_max:function(){var p=this.track.get("config"),o=[p.get_value("min_value"),p.get_value("max_value")];this._update_data_bounds(o);this.parent_elt.selectAll(".min_max").text(function(r,q){return o[q]})},_quantile:function(p,o){p.sort(m.ascending);return m.quantile(p,o)},_render_chrom_data:function(o,r,p){var s=this._get_path_function(r,p);if(!s){return null}var q=o.datum(p.data),t=q.append("path").attr("class","chrom-data").attr("chrom",r.data.chrom).attr("d",s);return t},_get_path_function:function(r,q){if(typeof q==="string"||!q.data||q.data.length===0){return null}var o=m.scale.linear().domain(this.data_bounds).range(this.radius_bounds).clamp(true);var s=m.scale.linear().domain([0,q.data.length]).range([r.startAngle,r.endAngle]);var p=m.svg.line.radial().interpolate("linear").radius(function(t){return o(t[1])}).angle(function(u,t){return s(t)});return m.svg.area.radial().interpolate(p.interpolate()).innerRadius(o(0)).outerRadius(p.radius()).angle(p.angle())},render_labels:function(){var o=this,q=function(){return"rotate(90)"};var p=this.drawTicks(this.parent_elt,[this.chroms_layout[0]],this._data_bounds_ticks_fn(),q,true).classed("min_max",true);h.each(p,function(r){$(r).click(function(){var s=new c.ConfigSettingCollectionView({collection:o.track.get("config")});s.render_in_modal("Configure Track")})})},_transition_labels:function(){if(this.data_bounds.length===0){return}var p=this,r=h.filter(this.chroms_layout,function(s){return s.endAngle-s.startAngle>0.08}),q=h.filter(r,function(t,s){return s%3===0}),o=h.flatten(h.map(q,function(s){return p._data_bounds_ticks_fn()(s)}));this.parent_elt.selectAll("g.tick").data(o).transition().attr("transform",function(s){return"rotate("+(s.angle*180/Math.PI-90)+")translate("+s.radius+",0)"})},_data_bounds_ticks_fn:function(){var o=this;visibleChroms=0;return function(p){return[{radius:o.radius_bounds[0],angle:p.startAngle,label:o.formatNum(o.data_bounds[0])},{radius:o.radius_bounds[1],angle:p.startAngle,label:o.formatNum(o.data_bounds[1])}]}},get_data_bounds:function(o){}});h.extend(g.prototype,i);var e=g.extend({get_data_bounds:function(p){var o=h.flatten(h.map(p,function(q){if(q){return h.map(q.data,function(r){return parseInt(r[1],10)||0})}else{return 0}}));return[h.min(o),this._quantile(o,0.98)||h.max(o)]}});var k=l.extend({render:function(){var o=this;$.when(o.track.get("data_manager").data_is_ready()).then(function(){$.when(o.track.get("data_manager").get_genome_wide_data(o.genome)).then(function(r){var q=[],p=o.genome.get_chroms_info();h.each(r,function(v,u){var s=p[u].chrom;var t=h.map(v.data,function(x){var w=o._get_region_angle(s,x[1]),y=o._get_region_angle(x[3],x[4]);return{source:{startAngle:w,endAngle:w+0.01},target:{startAngle:y,endAngle:y+0.01}}});q=q.concat(t)});o.parent_elt.append("g").attr("class","chord").selectAll("path").data(q).enter().append("path").style("fill",o.get_fill_color()).attr("d",m.svg.chord().radius(o.radius_bounds[0])).style("opacity",1)})})},update_radius_bounds:function(o){this.radius_bounds=o;this.parent_elt.selectAll("path").transition().attr("d",m.svg.chord().radius(this.radius_bounds[0]))},_get_region_angle:function(q,o){var p=h.find(this.chroms_layout,function(r){return r.data.chrom===q});return p.endAngle-((p.endAngle-p.startAngle)*(p.data.len-o)/p.data.len)}});var f=Backbone.View.extend({initialize:function(){var o=new j.Genome(galaxy_config.app.genome),p=new j.GenomeVisualization(galaxy_config.app.viz_config);p.get("config").add([{key:"arc_dataset_height",label:"Arc Dataset Height",type:"int",value:25,view:"circster"},{key:"track_gap",label:"Gap Between Tracks",type:"int",value:5,view:"circster"},{key:"total_gap",label:"Gap [0-1]",type:"float",value:0.4,view:"circster",hidden:true}]);var r=new a({el:$("#center .unified-panel-body"),genome:o,model:p});r.render();$("#center .unified-panel-header-inner").append(galaxy_config.app.viz_config.title+" "+galaxy_config.app.viz_config.dbkey);var q=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){j.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",p.get("dbkey"),function(s){p.add_tracks(s)})}},{icon_class:"gear",title:"Settings",on_click:function(){var s=new c.ConfigSettingCollectionView({collection:p.get("config")});s.render_in_modal("Configure Visualization")}},{icon_class:"disk--arrow",title:"Save",on_click:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});$.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:p.get("vis_id"),title:p.get("title"),dbkey:p.get("dbkey"),type:"trackster",vis_json:JSON.stringify(p)}}).success(function(s){Galaxy.modal.hide();p.set("vis_id",s.vis_id)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=galaxy_config.root+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});q.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(q.$el);$(".menu-button").tooltip({placement:"bottom"})}});return{GalaxyApp:f}});
\ No newline at end of file
+require(["utils/utils","mvc/ui/icon-button","libs/farbtastic",],function(b,a){b.cssLoadFile("static/style/circster.css")});define(["libs/underscore","libs/d3","viz/visualization","utils/config"],function(h,m,j,c){var n=Backbone.Model.extend({is_visible:function(r,o){var p=r.getBoundingClientRect(),q=$("svg")[0].getBoundingClientRect();if(p.right<0||p.left>q.right||p.bottom<0||p.top>q.bottom){return false}return true}});var i={drawTicks:function(s,r,w,q,o){var v=s.append("g").selectAll("g").data(r).enter().append("g").selectAll("g").data(w).enter().append("g").attr("class","tick").attr("transform",function(x){return"rotate("+(x.angle*180/Math.PI-90)+")translate("+x.radius+",0)"});var u=[],t=[],p=function(x){return x.angle>Math.PI?"end":null};if(o){u=[0,0,0,-4];t=[4,0,"",".35em"];p=null}else{u=[1,0,4,0];t=[0,4,".35em",""]}v.append("line").attr("x1",u[0]).attr("y1",u[1]).attr("x2",u[2]).attr("y1",u[3]).style("stroke","#000");return v.append("text").attr("x",t[0]).attr("y",t[1]).attr("dx",t[2]).attr("dy",t[3]).attr("text-anchor",p).attr("transform",q).text(function(x){return x.label})},formatNum:function(p,o){if(o===undefined){o=2}if(p===null){return null}var r=null;if(Math.abs(p)<1){r=p.toPrecision(o)}else{var q=Math.round(p.toPrecision(o));p=Math.abs(p);if(p<1000){r=q}else{if(p<1000000){r=Math.round((q/1000).toPrecision(3)).toFixed(0)+"K"}else{if(p<1000000000){r=Math.round((q/1000000).toPrecision(3)).toFixed(0)+"M"}}}}return r}};var d=Backbone.Model.extend({});var a=Backbone.View.extend({className:"circster",initialize:function(o){this.genome=o.genome;this.label_arc_height=50;this.scale=1;this.circular_views=null;this.chords_views=null;this.model.get("drawables").on("add",this.add_track,this);this.model.get("drawables").on("remove",this.remove_track,this);var p=this.model.get("config");p.get("arc_dataset_height").on("change:value",this.update_track_bounds,this);p.get("track_gap").on("change:value",this.update_track_bounds,this)},get_circular_tracks:function(){return this.model.get("drawables").filter(function(o){return o.get("track_type")!=="DiagonalHeatmapTrack"})},get_chord_tracks:function(){return this.model.get("drawables").filter(function(o){return o.get("track_type")==="DiagonalHeatmapTrack"})},get_tracks_bounds:function(){var q=this.get_circular_tracks(),s=this.model.get("config").get_value("arc_dataset_height"),r=this.model.get("config").get_value("track_gap"),o=Math.min(this.$el.width(),this.$el.height())-20,u=o/2-q.length*(s+r)+r-this.label_arc_height,t=m.range(u,o/2,s+r);var p=this;return h.map(t,function(v){return[v,v+s]})},render:function(){var x=this,o=x.$el.width(),w=x.$el.height(),t=this.get_circular_tracks(),r=this.get_chord_tracks(),q=x.model.get("config").get_value("total_gap"),s=this.get_tracks_bounds(),p=m.select(x.$el[0]).append("svg").attr("width",o).attr("height",w).attr("pointer-events","all").append("svg:g").call(m.behavior.zoom().on("zoom",function(){var y=m.event.scale;p.attr("transform","translate("+m.event.translate+") scale("+y+")");if(x.scale!==y){if(x.zoom_drag_timeout){clearTimeout(x.zoom_drag_timeout)}x.zoom_drag_timeout=setTimeout(function(){},400)}})).attr("transform","translate("+o/2+","+w/2+")").append("svg:g").attr("class","tracks");this.circular_views=t.map(function(z,A){var y=new e({el:p.append("g")[0],track:z,radius_bounds:s[A],genome:x.genome,total_gap:q});y.render();return y});this.chords_views=r.map(function(z){var y=new k({el:p.append("g")[0],track:z,radius_bounds:s[0],genome:x.genome,total_gap:q});y.render();return y});var v=this.circular_views[this.circular_views.length-1].radius_bounds[1],u=[v,v+this.label_arc_height];this.label_track_view=new b({el:p.append("g")[0],track:new d(),radius_bounds:u,genome:x.genome,total_gap:q});this.label_track_view.render()},add_track:function(u){var p=this.model.get("config").get_value("total_gap");if(u.get("track_type")==="DiagonalHeatmapTrack"){var q=this.circular_views[0].radius_bounds,t=new k({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:q,genome:this.genome,total_gap:p});t.render();this.chords_views.push(t)}else{var s=this.get_tracks_bounds();h.each(this.circular_views,function(v,w){v.update_radius_bounds(s[w])});h.each(this.chords_views,function(v){v.update_radius_bounds(s[0])});var r=this.circular_views.length,o=new e({el:m.select("g.tracks").append("g")[0],track:u,radius_bounds:s[r],genome:this.genome,total_gap:p});o.render();this.circular_views.push(o)}},remove_track:function(p,r,q){var o=this.circular_views[q.index];this.circular_views.splice(q.index,1);o.$el.remove();var s=this.get_tracks_bounds();h.each(this.circular_views,function(t,u){t.update_radius_bounds(s[u])})},update_track_bounds:function(){var o=this.get_tracks_bounds();h.each(this.circular_views,function(p,q){p.update_radius_bounds(o[q])});h.each(this.chords_views,function(p){p.update_radius_bounds(o[0])})}});var l=Backbone.View.extend({tagName:"g",initialize:function(o){this.bg_stroke="#ddd";this.loading_bg_fill="#ffc";this.bg_fill="#ddd";this.total_gap=o.total_gap;this.track=o.track;this.radius_bounds=o.radius_bounds;this.genome=o.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=m.select(this.$el[0])},get_fill_color:function(){var o=this.track.get("config").get_value("block_color");if(!o){o=this.track.get("config").get_value("color")}return o},render:function(){var s=this.parent_elt;var r=this.chroms_layout,u=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),o=s.selectAll("g").data(r).enter().append("svg:g"),q=o.append("path").attr("d",u).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);q.append("title").text(function(w){return w.data.chrom});var p=this,t=p.track.get("data_manager"),v=(t?t.data_is_ready():true);$.when(v).then(function(){$.when(p._render_data(s)).then(function(){q.style("fill",p.bg_fill);p.render_labels()})})},render_labels:function(){},update_radius_bounds:function(p){this.radius_bounds=p;var o=m.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",o);this._transition_chrom_data();this._transition_labels()},update_scale:function(r){var q=this.scale;this.scale=r;if(r<=q){return}var p=this,o=new n();this.parent_elt.selectAll("path.chrom-data").filter(function(t,s){return o.is_visible(this)}).each(function(y,u){var x=m.select(this),t=x.attr("chrom"),w=p.genome.get_chrom_region(t),v=p.track.get("data_manager"),s;if(!v.can_get_more_detailed_data(w)){return}s=p.track.get("data_manager").get_more_detailed_data(w,"Coverage",0,r);$.when(s).then(function(B){x.remove();p._update_data_bounds();var A=h.find(p.chroms_layout,function(C){return C.data.chrom===t});var z=p.get_fill_color();p._render_chrom_data(p.parent_elt,A,B).style("stroke",z).style("fill",z)})});return p},_transition_chrom_data:function(){var p=this.track,r=this.chroms_layout,o=this.parent_elt.selectAll("g>path.chrom-data"),s=o[0].length;if(s>0){var q=this;$.when(p.get("data_manager").get_genome_wide_data(this.genome)).then(function(v){var u=h.reject(h.map(v,function(w,x){var y=null,z=q._get_path_function(r[x],w);if(z){y=z(w.data)}return y}),function(w){return w===null});var t=p.get("config").get_value("color");o.each(function(x,w){m.select(this).transition().duration(1000).style("stroke",t).style("fill",t).attr("d",u[w])})})}},_transition_labels:function(){},_update_data_bounds:function(p){var o=this.data_bounds;this.data_bounds=p||this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));this._transition_chrom_data()},_render_data:function(r){var q=this,p=this.chroms_layout,o=this.track,s=$.Deferred();$.when(o.get("data_manager").get_genome_wide_data(this.genome)).then(function(u){q.data_bounds=q.get_data_bounds(u);o.get("config").set_value("min_value",q.data_bounds[0],{silent:true});o.get("config").set_value("max_value",q.data_bounds[1],{silent:true});layout_and_data=h.zip(p,u),chroms_data_layout=h.map(layout_and_data,function(v){var w=v[0],x=v[1];return q._render_chrom_data(r,w,x)});var t=q.get_fill_color();q.parent_elt.selectAll("path.chrom-data").style("stroke",t).style("fill",t);s.resolve(r)});return s},_render_chrom_data:function(o,p,q){},_get_path_function:function(p,o){},_chroms_layout:function(){var p=this.genome.get_chroms_info(),r=m.layout.pie().value(function(t){return t.len}).sort(null),s=r(p),o=2*Math.PI*this.total_gap/p.length,q=h.map(s,function(v,u){var t=v.endAngle-o;v.endAngle=(t>v.startAngle?t:v.startAngle);return v});return q}});var b=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);this.innerRadius=this.radius_bounds[0];this.radius_bounds[0]=this.radius_bounds[1];this.bg_stroke="#fff";this.bg_fill="#fff";this.min_arc_len=0.05},_render_data:function(q){var p=this,o=q.selectAll("g");o.selectAll("path").attr("id",function(u){return"label-"+u.data.chrom});o.append("svg:text").filter(function(u){return u.endAngle-u.startAngle>p.min_arc_len}).attr("text-anchor","middle").append("svg:textPath").attr("class","chrom-label").attr("xlink:href",function(u){return"#label-"+u.data.chrom}).attr("startOffset","25%").text(function(u){return u.data.chrom});var r=function(w){var u=(w.endAngle-w.startAngle)/w.value,v=m.range(0,w.value,25000000).map(function(x,y){return{radius:p.innerRadius,angle:x*u+w.startAngle,label:y===0?0:(y%3?null:p.formatNum(x))}});if(v.length<4){v[v.length-1].label=p.formatNum(Math.round((v[v.length-1].angle-w.startAngle)/u))}return v};var t=function(u){return u.angle>Math.PI?"rotate(180)translate(-16)":null};var s=h.filter(this.chroms_layout,function(u){return u.endAngle-u.startAngle>p.min_arc_len});this.drawTicks(this.parent_elt,s,r,t)}});h.extend(b.prototype,i);var g=l.extend({initialize:function(o){l.prototype.initialize.call(this,o);var p=this.track.get("config");p.get("min_value").on("change:value",this._update_min_max,this);p.get("max_value").on("change:value",this._update_min_max,this);p.get("color").on("change:value",this._transition_chrom_data,this)},_update_min_max:function(){var p=this.track.get("config"),o=[p.get_value("min_value"),p.get_value("max_value")];this._update_data_bounds(o);this.parent_elt.selectAll(".min_max").text(function(r,q){return o[q]})},_quantile:function(p,o){p.sort(m.ascending);return m.quantile(p,o)},_render_chrom_data:function(o,r,p){var s=this._get_path_function(r,p);if(!s){return null}var q=o.datum(p.data),t=q.append("path").attr("class","chrom-data").attr("chrom",r.data.chrom).attr("d",s);return t},_get_path_function:function(r,q){if(typeof q==="string"||!q.data||q.data.length===0){return null}var o=m.scale.linear().domain(this.data_bounds).range(this.radius_bounds).clamp(true);var s=m.scale.linear().domain([0,q.data.length]).range([r.startAngle,r.endAngle]);var p=m.svg.line.radial().interpolate("linear").radius(function(t){return o(t[1])}).angle(function(u,t){return s(t)});return m.svg.area.radial().interpolate(p.interpolate()).innerRadius(o(0)).outerRadius(p.radius()).angle(p.angle())},render_labels:function(){var o=this,q=function(){return"rotate(90)"};var p=this.drawTicks(this.parent_elt,[this.chroms_layout[0]],this._data_bounds_ticks_fn(),q,true).classed("min_max",true);h.each(p,function(r){$(r).click(function(){var s=new c.ConfigSettingCollectionView({collection:o.track.get("config")});s.render_in_modal("Configure Track")})})},_transition_labels:function(){if(this.data_bounds.length===0){return}var p=this,r=h.filter(this.chroms_layout,function(s){return s.endAngle-s.startAngle>0.08}),q=h.filter(r,function(t,s){return s%3===0}),o=h.flatten(h.map(q,function(s){return p._data_bounds_ticks_fn()(s)}));this.parent_elt.selectAll("g.tick").data(o).transition().attr("transform",function(s){return"rotate("+(s.angle*180/Math.PI-90)+")translate("+s.radius+",0)"})},_data_bounds_ticks_fn:function(){var o=this;visibleChroms=0;return function(p){return[{radius:o.radius_bounds[0],angle:p.startAngle,label:o.formatNum(o.data_bounds[0])},{radius:o.radius_bounds[1],angle:p.startAngle,label:o.formatNum(o.data_bounds[1])}]}},get_data_bounds:function(o){}});h.extend(g.prototype,i);var e=g.extend({get_data_bounds:function(p){var o=h.flatten(h.map(p,function(q){if(q){return h.map(q.data,function(r){return parseInt(r[1],10)||0})}else{return 0}}));return[h.min(o),this._quantile(o,0.98)||h.max(o)]}});var k=l.extend({render:function(){var o=this;$.when(o.track.get("data_manager").data_is_ready()).then(function(){$.when(o.track.get("data_manager").get_genome_wide_data(o.genome)).then(function(r){var q=[],p=o.genome.get_chroms_info();h.each(r,function(v,u){var s=p[u].chrom;var t=h.map(v.data,function(x){var w=o._get_region_angle(s,x[1]),y=o._get_region_angle(x[3],x[4]);return{source:{startAngle:w,endAngle:w+0.01},target:{startAngle:y,endAngle:y+0.01}}});q=q.concat(t)});o.parent_elt.append("g").attr("class","chord").selectAll("path").data(q).enter().append("path").style("fill",o.get_fill_color()).attr("d",m.svg.chord().radius(o.radius_bounds[0])).style("opacity",1)})})},update_radius_bounds:function(o){this.radius_bounds=o;this.parent_elt.selectAll("path").transition().attr("d",m.svg.chord().radius(this.radius_bounds[0]))},_get_region_angle:function(q,o){var p=h.find(this.chroms_layout,function(r){return r.data.chrom===q});return p.endAngle-((p.endAngle-p.startAngle)*(p.data.len-o)/p.data.len)}});var f=Backbone.View.extend({initialize:function(){var o=new j.Genome(galaxy_config.app.genome),p=new j.GenomeVisualization(galaxy_config.app.viz_config);p.get("config").add([{key:"arc_dataset_height",label:"Arc Dataset Height",type:"int",value:25,view:"circster"},{key:"track_gap",label:"Gap Between Tracks",type:"int",value:5,view:"circster"},{key:"total_gap",label:"Gap [0-1]",type:"float",value:0.4,view:"circster",hidden:true}]);var r=new a({el:$("#center .unified-panel-body"),genome:o,model:p});r.render();$("#center .unified-panel-header-inner").append(galaxy_config.app.viz_config.title+" "+galaxy_config.app.viz_config.dbkey);var q=mod_icon_btn.create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){j.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",p.get("dbkey"),function(s){p.add_tracks(s)})}},{icon_class:"gear",title:"Settings",on_click:function(){var s=new c.ConfigSettingCollectionView({collection:p.get("config")});s.render_in_modal("Configure Visualization")}},{icon_class:"disk--arrow",title:"Save",on_click:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});$.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:p.get("vis_id"),title:p.get("title"),dbkey:p.get("dbkey"),type:"trackster",vis_json:JSON.stringify(p)}}).success(function(s){Galaxy.modal.hide();p.set("vis_id",s.vis_id)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=galaxy_config.root+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});q.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(q.$el);$(".menu-button").tooltip({placement:"bottom"})}});return{GalaxyApp:f}});
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/viz/phyloviz.js
--- a/static/scripts/packed/viz/phyloviz.js
+++ b/static/scripts/packed/viz/phyloviz.js
@@ -1,1 +1,1 @@
-define(["libs/d3","viz/visualization","mvc/data"],function(m,f,g){var l=Backbone.View.extend({className:"UserMenuBase",isAcceptableValue:function(q,o,n){var r=q.val(),s=q.attr("displayLabel")||q.attr("id").replace("phyloViz","");function p(t){return !isNaN(parseFloat(t))&&isFinite(t)}if(!p(r)){alert(s+" is not a number!");return false}if(r>n){alert(s+" is too large.");return false}else{if(r<o){alert(s+" is too small.");return false}}return true},hasIllegalJsonCharacters:function(n){if(n.val().search(/"|'|\\/)!==-1){alert("Named fields cannot contain these illegal characters: double quote(\"), single guote('), or back slash(\\). ");return true}return false}});function h(){var w=this,r=m.layout.hierarchy().sort(null).value(null),v=360,q="Linear",u=18,s=200,t=0,p=0.5,n=50;w.leafHeight=function(x){if(typeof x==="undefined"){return u}else{u=x;return w}};w.layoutMode=function(x){if(typeof x==="undefined"){return q}else{q=x;return w}};w.layoutAngle=function(x){if(typeof x==="undefined"){return v}if(isNaN(x)||x<0||x>360){return w}else{v=x;return w}};w.separation=function(x){if(typeof x==="undefined"){return s}else{s=x;return w}};w.links=function(x){return m.layout.tree().links(x)};w.nodes=function(A,y){if(toString.call(A)==="[object Array]"){A=A[0]}var z=r.call(w,A,y),x=[],C=0,B=0;window._d=A;window._nodes=z;z.forEach(function(D){C=D.depth>C?D.depth:C;x.push(D)});x.forEach(function(D){if(!D.children){B+=1;D.depth=C}});u=q==="Circular"?v/B:u;t=0;o(x[0],C,u,null);return x};function o(B,D,A,z){var y=B.children,x=0;var C=B.dist||p;C=C>1?1:C;B.dist=C;if(z!==null){B.y0=z.y0+C*s}else{B.y0=n}if(!y){B.x0=t*A;t+=1}else{y.forEach(function(E){E.parent=B;x+=o(E,D,A,B)});B.x0=x/y.length}B.x=B.x0;B.y=B.y0;return B.x0}return w}var b=f.Visualization.extend({defaults:{layout:"Linear",separation:250,leafHeight:18,type:"phyloviz",title:"Title",scaleFactor:1,translate:[0,0],fontSize:12,selectedNode:null,nodeAttrChangedTime:0},initialize:function(n){this.set("dataset",new g.Dataset({id:n.dataset_id}))},root:{},toggle:function(n){if(typeof n==="undefined"){return}if(n.children){n._children=n.children;n.children=null}else{n.children=n._children;n._children=null}},toggleAll:function(n){if(n.children&&n.children.length!==0){n.children.forEach(this.toggleAll);toggle(n)}},getData:function(){return this.root},save:function(){var n=this.root;o(n);function o(q){delete q.parent;if(q._selected){delete q._selected}if(q.children){q.children.forEach(o)}if(q._children){q._children.forEach(o)}}var p=jQuery.extend(true,{},this.attributes);p.selectedNode=null;show_message("Saving to Galaxy","progress");return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{config:JSON.stringify(p),type:"phyloviz"},success:function(q){hide_modal()}})}});var d=Backbone.View.extend({defaults:{nodeRadius:4.5},stdInit:function(o){var n=this;n.model.on("change:separation change:leafHeight change:fontSize change:nodeAttrChangedTime",n.updateAndRender,n);n.vis=o.vis;n.i=0;n.maxDepth=-1;n.width=o.width;n.height=o.height},updateAndRender:function(p){var o=m.select(".vis"),n=this;p=p||n.model.root;n.renderNodes(p);n.renderLinks(p);n.addTooltips()},renderLinks:function(n){var w=this;var o=w.diagonal;var p=w.duration;var r=w.layoutMode;var t=w.vis.selectAll("g.completeLink").data(w.tree.links(w.nodes),function(x){return x.target.id});var v=function(x){x.pos0=x.source.y0+" "+x.source.x0;x.pos1=x.source.y0+" "+x.target.x0;x.pos2=x.target.y0+" "+x.target.x0};var u=t.enter().insert("svg:g","g.node").attr("class","completeLink");u.append("svg:path").attr("class","link").attr("d",function(x){v(x);return"M "+x.pos0+" L "+x.pos1});var s=t.transition().duration(500);s.select("path.link").attr("d",function(x){v(x);return"M "+x.pos0+" L "+x.pos1+" L "+x.pos2});var q=t.exit().remove()},selectNode:function(o){var n=this;m.selectAll("g.node").classed("selectedHighlight",function(p){if(o.id===p.id){if(o._selected){delete o._selected;return false}else{o._selected=true;return true}}return false});n.model.set("selectedNode",o);$("#phyloVizSelectedNodeName").val(o.name);$("#phyloVizSelectedNodeDist").val(o.dist);$("#phyloVizSelectedNodeAnnotation").val(o.annotation||"")},addTooltips:function(){$(".tooltip").remove();$(".node").attr("data-original-title",function(){var o=this.__data__,n=o.annotation||"None";return o?(o.name?o.name+"<br/>":"")+"Dist: "+o.dist+" <br/>Annotation: "+n:""}).tooltip({placement:"top",trigger:"hover"})}});var a=d.extend({initialize:function(o){var n=this;n.margins=o.margins;n.layoutMode="Linear";n.stdInit(o);n.layout();n.updateAndRender(n.model.root)},layout:function(){var n=this;n.tree=new h().layoutMode("Linear");n.diagonal=m.svg.diagonal().projection(function(o){return[o.y,o.x]})},renderNodes:function(n){var u=this,v=u.model.get("fontSize")+"px";u.tree.separation(u.model.get("separation")).leafHeight(u.model.get("leafHeight"));var q=500,o=u.tree.separation(u.model.get("separation")).nodes(u.model.root);var p=u.vis.selectAll("g.node").data(o,function(w){return w.name+w.id||(w.id=++u.i)});u.nodes=o;u.duration=q;var r=p.enter().append("svg:g").attr("class","node").on("dblclick",function(){m.event.stopPropagation()}).on("click",function(w){if(m.event.altKey){u.selectNode(w)}else{if(w.children&&w.children.length===0){return}u.model.toggle(w);u.updateAndRender(w)}});if(toString.call(n)==="[object Array]"){n=n[0]}r.attr("transform",function(w){return"translate("+n.y0+","+n.x0+")"});r.append("svg:circle").attr("r",0.000001).style("fill",function(w){return w._children?"lightsteelblue":"#fff"});r.append("svg:text").attr("class","nodeLabel").attr("x",function(w){return w.children||w._children?-10:10}).attr("dy",".35em").attr("text-anchor",function(w){return w.children||w._children?"end":"start"}).style("fill-opacity",0.000001);var s=p.transition().duration(q);s.attr("transform",function(w){return"translate("+w.y+","+w.x+")"});s.select("circle").attr("r",u.defaults.nodeRadius).style("fill",function(w){return w._children?"lightsteelblue":"#fff"});s.select("text").style("fill-opacity",1).style("font-size",v).text(function(w){return w.name});var t=p.exit().transition().duration(q).remove();t.select("circle").attr("r",0.000001);t.select("text").style("fill-opacity",0.000001);o.forEach(function(w){w.x0=w.x;w.y0=w.y})}});var j=Backbone.View.extend({className:"phyloviz",initialize:function(o){var n=this;n.MIN_SCALE=0.05;n.MAX_SCALE=5;n.MAX_DISPLACEMENT=500;n.margins=[10,60,10,80];n.width=$("#PhyloViz").width();n.height=$("#PhyloViz").height();n.radius=n.width;n.data=o.data;$(window).resize(function(){n.width=$("#PhyloViz").width();n.height=$("#PhyloViz").height();n.render()});n.phyloTree=new b(o.config);n.phyloTree.root=n.data;n.zoomFunc=m.behavior.zoom().scaleExtent([n.MIN_SCALE,n.MAX_SCALE]);n.zoomFunc.translate(n.phyloTree.get("translate"));n.zoomFunc.scale(n.phyloTree.get("scaleFactor"));n.navMenu=new c(n);n.settingsMenu=new i({phyloTree:n.phyloTree});n.nodeSelectionView=new e({phyloTree:n.phyloTree});n.search=new k();setTimeout(function(){n.zoomAndPan()},1000)},render:function(){var o=this;$("#PhyloViz").empty();o.mainSVG=m.select("#PhyloViz").append("svg:svg").attr("width",o.width).attr("height",o.height).attr("pointer-events","all").call(o.zoomFunc.on("zoom",function(){o.zoomAndPan()}));o.boundingRect=o.mainSVG.append("svg:rect").attr("class","boundingRect").attr("width",o.width).attr("height",o.height).attr("stroke","black").attr("fill","white");o.vis=o.mainSVG.append("svg:g").attr("class","vis");o.layoutOptions={model:o.phyloTree,width:o.width,height:o.height,vis:o.vis,margins:o.margins};$("#title").text("Phylogenetic Tree from "+o.phyloTree.get("title")+":");var n=new a(o.layoutOptions)},zoomAndPan:function(n){var t,p;if(typeof n!=="undefined"){t=n.zoom;p=n.translate}var w=this,r=w.zoomFunc.scale(),v=w.zoomFunc.translate(),s="",u="";switch(t){case"reset":r=1;v=[0,0];break;case"+":r*=1.1;break;case"-":r*=0.9;break;default:if(typeof t==="number"){r=t}else{if(m.event!==null){r=m.event.scale}}}if(r<w.MIN_SCALE||r>w.MAX_SCALE){return}w.zoomFunc.scale(r);s="translate("+w.margins[3]+","+w.margins[0]+") scale("+r+")";if(m.event!==null){u="translate("+m.event.translate+")"}else{if(typeof p!=="undefined"){var q=p.split(",")[0];var o=p.split(",")[1];if(!isNaN(q)&&!isNaN(o)){v=[v[0]+parseFloat(q),v[1]+parseFloat(o)]}}w.zoomFunc.translate(v);u="translate("+v+")"}w.phyloTree.set("scaleFactor",r);w.phyloTree.set("translate",v);w.vis.attr("transform",u+s)},reloadViz:function(){var n=this,o=$("#phylovizNexSelector :selected").val();$.getJSON(n.phyloTree.get("dataset").url(),{tree_index:o,data_type:"raw_data"},function(p){n.data=p.data;n.config=p;n.render()})}});var c=Backbone.View.extend({initialize:function(o){var n=this;n.phylovizView=o;$("#panelHeaderRightBtns").empty();$("#phyloVizNavBtns").empty();$("#phylovizNexSelector").off();n.initNavBtns();n.initRightHeaderBtns();$("#phylovizNexSelector").off().on("change",function(){n.phylovizView.reloadViz()})},initRightHeaderBtns:function(){var n=this;rightMenu=create_icon_buttons_menu([{icon_class:"gear",title:"PhyloViz Settings",on_click:function(){$("#SettingsMenu").show();n.settingsMenu.updateUI()}},{icon_class:"disk",title:"Save visualization",on_click:function(){var o=$("#phylovizNexSelector option:selected").text();if(o){n.phylovizView.phyloTree.set("title",o)}n.phylovizView.phyloTree.save()}},{icon_class:"chevron-expand",title:"Search / Edit Nodes",on_click:function(){$("#nodeSelectionView").show()}},{icon_class:"information",title:"Phyloviz Help",on_click:function(){window.open("https://wiki.galaxyproject.org/Learn/Visualization/PhylogeneticTree")}}],{tooltip_config:{placement:"bottom"}});$("#panelHeaderRightBtns").append(rightMenu.$el)},initNavBtns:function(){var n=this,o=create_icon_buttons_menu([{icon_class:"zoom-in",title:"Zoom in",on_click:function(){n.phylovizView.zoomAndPan({zoom:"+"})}},{icon_class:"zoom-out",title:"Zoom out",on_click:function(){n.phylovizView.zoomAndPan({zoom:"-"})}},{icon_class:"arrow-circle",title:"Reset Zoom/Pan",on_click:function(){n.phylovizView.zoomAndPan({zoom:"reset"})}}],{tooltip_config:{placement:"bottom"}});$("#phyloVizNavBtns").append(o.$el)}});var i=l.extend({className:"Settings",initialize:function(o){var n=this;n.phyloTree=o.phyloTree;n.el=$("#SettingsMenu");n.inputs={separation:$("#phyloVizTreeSeparation"),leafHeight:$("#phyloVizTreeLeafHeight"),fontSize:$("#phyloVizTreeFontSize")};$("#settingsCloseBtn").off().on("click",function(){n.el.hide()});$("#phylovizResetSettingsBtn").off().on("click",function(){n.resetToDefaults()});$("#phylovizApplySettingsBtn").off().on("click",function(){n.apply()})},apply:function(){var n=this;if(!n.isAcceptableValue(n.inputs.separation,50,2500)||!n.isAcceptableValue(n.inputs.leafHeight,5,30)||!n.isAcceptableValue(n.inputs.fontSize,5,20)){return}$.each(n.inputs,function(o,p){n.phyloTree.set(o,p.val())})},updateUI:function(){var n=this;$.each(n.inputs,function(o,p){p.val(n.phyloTree.get(o))})},resetToDefaults:function(){$(".tooltip").remove();var n=this;$.each(n.phyloTree.defaults,function(o,p){n.phyloTree.set(o,p)});n.updateUI()},render:function(){}});var e=l.extend({className:"Settings",initialize:function(o){var n=this;n.el=$("#nodeSelectionView");n.phyloTree=o.phyloTree;n.UI={enableEdit:$("#phylovizEditNodesCheck"),saveChanges:$("#phylovizNodeSaveChanges"),cancelChanges:$("#phylovizNodeCancelChanges"),name:$("#phyloVizSelectedNodeName"),dist:$("#phyloVizSelectedNodeDist"),annotation:$("#phyloVizSelectedNodeAnnotation")};n.valuesOfConcern={name:null,dist:null,annotation:null};$("#nodeSelCloseBtn").off().on("click",function(){n.el.hide()});n.UI.saveChanges.off().on("click",function(){n.updateNodes()});n.UI.cancelChanges.off().on("click",function(){n.cancelChanges()});(function(p){p.fn.enable=function(q){return p(this).each(function(){if(q){p(this).removeAttr("disabled")}else{p(this).attr("disabled","disabled")}})}})(jQuery);n.UI.enableEdit.off().on("click",function(){n.toggleUI()})},toggleUI:function(){var n=this,o=n.UI.enableEdit.is(":checked");if(!o){n.cancelChanges()}$.each(n.valuesOfConcern,function(p,q){n.UI[p].enable(o)});if(o){n.UI.saveChanges.show();n.UI.cancelChanges.show()}else{n.UI.saveChanges.hide();n.UI.cancelChanges.hide()}},cancelChanges:function(){var n=this,o=n.phyloTree.get("selectedNode");if(o){$.each(n.valuesOfConcern,function(p,q){n.UI[p].val(o[p])})}},updateNodes:function(){var n=this,o=n.phyloTree.get("selectedNode");if(o){if(!n.isAcceptableValue(n.UI.dist,0,1)||n.hasIllegalJsonCharacters(n.UI.name)||n.hasIllegalJsonCharacters(n.UI.annotation)){return}$.each(n.valuesOfConcern,function(p,q){(o[p])=n.UI[p].val()});n.phyloTree.set("nodeAttrChangedTime",new Date())}else{alert("No node selected")}}});var k=l.extend({initialize:function(){var n=this;$("#phyloVizSearchBtn").on("click",function(){var p=$("#phyloVizSearchTerm"),q=$("#phyloVizSearchCondition").val().split("-"),o=q[0],r=q[1];n.hasIllegalJsonCharacters(p);if(o==="dist"){n.isAcceptableValue(p,0,1)}n.searchTree(o,r,p.val())})},searchTree:function(n,p,o){m.selectAll("g.node").classed("searchHighlight",function(r){var q=r[n];if(typeof q!=="undefined"&&q!==null){if(n==="dist"){switch(p){case"greaterEqual":return q>=+o;case"lesserEqual":return q<=+o;default:return}}else{if(n==="name"||n==="annotation"){return q.toLowerCase().indexOf(o.toLowerCase())!==-1}}}})}});return{PhylovizView:j}});
\ No newline at end of file
+define(["libs/d3","viz/visualization","mvc/data","mvc/ui/icon-button"],function(n,g,h,c){var m=Backbone.View.extend({className:"UserMenuBase",isAcceptableValue:function(r,p,o){var s=r.val(),t=r.attr("displayLabel")||r.attr("id").replace("phyloViz","");function q(u){return !isNaN(parseFloat(u))&&isFinite(u)}if(!q(s)){alert(t+" is not a number!");return false}if(s>o){alert(t+" is too large.");return false}else{if(s<p){alert(t+" is too small.");return false}}return true},hasIllegalJsonCharacters:function(o){if(o.val().search(/"|'|\\/)!==-1){alert("Named fields cannot contain these illegal characters: double quote(\"), single guote('), or back slash(\\). ");return true}return false}});function i(){var x=this,s=n.layout.hierarchy().sort(null).value(null),w=360,r="Linear",v=18,t=200,u=0,q=0.5,o=50;x.leafHeight=function(y){if(typeof y==="undefined"){return v}else{v=y;return x}};x.layoutMode=function(y){if(typeof y==="undefined"){return r}else{r=y;return x}};x.layoutAngle=function(y){if(typeof y==="undefined"){return w}if(isNaN(y)||y<0||y>360){return x}else{w=y;return x}};x.separation=function(y){if(typeof y==="undefined"){return t}else{t=y;return x}};x.links=function(y){return n.layout.tree().links(y)};x.nodes=function(B,z){if(toString.call(B)==="[object Array]"){B=B[0]}var A=s.call(x,B,z),y=[],D=0,C=0;window._d=B;window._nodes=A;A.forEach(function(E){D=E.depth>D?E.depth:D;y.push(E)});y.forEach(function(E){if(!E.children){C+=1;E.depth=D}});v=r==="Circular"?w/C:v;u=0;p(y[0],D,v,null);return y};function p(C,E,B,A){var z=C.children,y=0;var D=C.dist||q;D=D>1?1:D;C.dist=D;if(A!==null){C.y0=A.y0+D*t}else{C.y0=o}if(!z){C.x0=u*B;u+=1}else{z.forEach(function(F){F.parent=C;y+=p(F,E,B,C)});C.x0=y/z.length}C.x=C.x0;C.y=C.y0;return C.x0}return x}var b=g.Visualization.extend({defaults:{layout:"Linear",separation:250,leafHeight:18,type:"phyloviz",title:"Title",scaleFactor:1,translate:[0,0],fontSize:12,selectedNode:null,nodeAttrChangedTime:0},initialize:function(o){this.set("dataset",new h.Dataset({id:o.dataset_id}))},root:{},toggle:function(o){if(typeof o==="undefined"){return}if(o.children){o._children=o.children;o.children=null}else{o.children=o._children;o._children=null}},toggleAll:function(o){if(o.children&&o.children.length!==0){o.children.forEach(this.toggleAll);toggle(o)}},getData:function(){return this.root},save:function(){var o=this.root;p(o);function p(r){delete r.parent;if(r._selected){delete r._selected}if(r.children){r.children.forEach(p)}if(r._children){r._children.forEach(p)}}var q=jQuery.extend(true,{},this.attributes);q.selectedNode=null;show_message("Saving to Galaxy","progress");return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{config:JSON.stringify(q),type:"phyloviz"},success:function(r){hide_modal()}})}});var e=Backbone.View.extend({defaults:{nodeRadius:4.5},stdInit:function(p){var o=this;o.model.on("change:separation change:leafHeight change:fontSize change:nodeAttrChangedTime",o.updateAndRender,o);o.vis=p.vis;o.i=0;o.maxDepth=-1;o.width=p.width;o.height=p.height},updateAndRender:function(q){var p=n.select(".vis"),o=this;q=q||o.model.root;o.renderNodes(q);o.renderLinks(q);o.addTooltips()},renderLinks:function(o){var x=this;var p=x.diagonal;var q=x.duration;var s=x.layoutMode;var u=x.vis.selectAll("g.completeLink").data(x.tree.links(x.nodes),function(y){return y.target.id});var w=function(y){y.pos0=y.source.y0+" "+y.source.x0;y.pos1=y.source.y0+" "+y.target.x0;y.pos2=y.target.y0+" "+y.target.x0};var v=u.enter().insert("svg:g","g.node").attr("class","completeLink");v.append("svg:path").attr("class","link").attr("d",function(y){w(y);return"M "+y.pos0+" L "+y.pos1});var t=u.transition().duration(500);t.select("path.link").attr("d",function(y){w(y);return"M "+y.pos0+" L "+y.pos1+" L "+y.pos2});var r=u.exit().remove()},selectNode:function(p){var o=this;n.selectAll("g.node").classed("selectedHighlight",function(q){if(p.id===q.id){if(p._selected){delete p._selected;return false}else{p._selected=true;return true}}return false});o.model.set("selectedNode",p);$("#phyloVizSelectedNodeName").val(p.name);$("#phyloVizSelectedNodeDist").val(p.dist);$("#phyloVizSelectedNodeAnnotation").val(p.annotation||"")},addTooltips:function(){$(".tooltip").remove();$(".node").attr("data-original-title",function(){var p=this.__data__,o=p.annotation||"None";return p?(p.name?p.name+"<br/>":"")+"Dist: "+p.dist+" <br/>Annotation: "+o:""}).tooltip({placement:"top",trigger:"hover"})}});var a=e.extend({initialize:function(p){var o=this;o.margins=p.margins;o.layoutMode="Linear";o.stdInit(p);o.layout();o.updateAndRender(o.model.root)},layout:function(){var o=this;o.tree=new i().layoutMode("Linear");o.diagonal=n.svg.diagonal().projection(function(p){return[p.y,p.x]})},renderNodes:function(o){var v=this,w=v.model.get("fontSize")+"px";v.tree.separation(v.model.get("separation")).leafHeight(v.model.get("leafHeight"));var r=500,p=v.tree.separation(v.model.get("separation")).nodes(v.model.root);var q=v.vis.selectAll("g.node").data(p,function(x){return x.name+x.id||(x.id=++v.i)});v.nodes=p;v.duration=r;var s=q.enter().append("svg:g").attr("class","node").on("dblclick",function(){n.event.stopPropagation()}).on("click",function(x){if(n.event.altKey){v.selectNode(x)}else{if(x.children&&x.children.length===0){return}v.model.toggle(x);v.updateAndRender(x)}});if(toString.call(o)==="[object Array]"){o=o[0]}s.attr("transform",function(x){return"translate("+o.y0+","+o.x0+")"});s.append("svg:circle").attr("r",0.000001).style("fill",function(x){return x._children?"lightsteelblue":"#fff"});s.append("svg:text").attr("class","nodeLabel").attr("x",function(x){return x.children||x._children?-10:10}).attr("dy",".35em").attr("text-anchor",function(x){return x.children||x._children?"end":"start"}).style("fill-opacity",0.000001);var t=q.transition().duration(r);t.attr("transform",function(x){return"translate("+x.y+","+x.x+")"});t.select("circle").attr("r",v.defaults.nodeRadius).style("fill",function(x){return x._children?"lightsteelblue":"#fff"});t.select("text").style("fill-opacity",1).style("font-size",w).text(function(x){return x.name});var u=q.exit().transition().duration(r).remove();u.select("circle").attr("r",0.000001);u.select("text").style("fill-opacity",0.000001);p.forEach(function(x){x.x0=x.x;x.y0=x.y})}});var k=Backbone.View.extend({className:"phyloviz",initialize:function(p){var o=this;o.MIN_SCALE=0.05;o.MAX_SCALE=5;o.MAX_DISPLACEMENT=500;o.margins=[10,60,10,80];o.width=$("#PhyloViz").width();o.height=$("#PhyloViz").height();o.radius=o.width;o.data=p.data;$(window).resize(function(){o.width=$("#PhyloViz").width();o.height=$("#PhyloViz").height();o.render()});o.phyloTree=new b(p.config);o.phyloTree.root=o.data;o.zoomFunc=n.behavior.zoom().scaleExtent([o.MIN_SCALE,o.MAX_SCALE]);o.zoomFunc.translate(o.phyloTree.get("translate"));o.zoomFunc.scale(o.phyloTree.get("scaleFactor"));o.navMenu=new d(o);o.settingsMenu=new j({phyloTree:o.phyloTree});o.nodeSelectionView=new f({phyloTree:o.phyloTree});o.search=new l();setTimeout(function(){o.zoomAndPan()},1000)},render:function(){var p=this;$("#PhyloViz").empty();p.mainSVG=n.select("#PhyloViz").append("svg:svg").attr("width",p.width).attr("height",p.height).attr("pointer-events","all").call(p.zoomFunc.on("zoom",function(){p.zoomAndPan()}));p.boundingRect=p.mainSVG.append("svg:rect").attr("class","boundingRect").attr("width",p.width).attr("height",p.height).attr("stroke","black").attr("fill","white");p.vis=p.mainSVG.append("svg:g").attr("class","vis");p.layoutOptions={model:p.phyloTree,width:p.width,height:p.height,vis:p.vis,margins:p.margins};$("#title").text("Phylogenetic Tree from "+p.phyloTree.get("title")+":");var o=new a(p.layoutOptions)},zoomAndPan:function(o){var u,q;if(typeof o!=="undefined"){u=o.zoom;q=o.translate}var z=this,s=z.zoomFunc.scale(),w=z.zoomFunc.translate(),t="",v="";switch(u){case"reset":s=1;w=[0,0];break;case"+":s*=1.1;break;case"-":s*=0.9;break;default:if(typeof u==="number"){s=u}else{if(n.event!==null){s=n.event.scale}}}if(s<z.MIN_SCALE||s>z.MAX_SCALE){return}z.zoomFunc.scale(s);t="translate("+z.margins[3]+","+z.margins[0]+") scale("+s+")";if(n.event!==null){v="translate("+n.event.translate+")"}else{if(typeof q!=="undefined"){var r=q.split(",")[0];var p=q.split(",")[1];if(!isNaN(r)&&!isNaN(p)){w=[w[0]+parseFloat(r),w[1]+parseFloat(p)]}}z.zoomFunc.translate(w);v="translate("+w+")"}z.phyloTree.set("scaleFactor",s);z.phyloTree.set("translate",w);z.vis.attr("transform",v+t)},reloadViz:function(){var o=this,p=$("#phylovizNexSelector :selected").val();$.getJSON(o.phyloTree.get("dataset").url(),{tree_index:p,data_type:"raw_data"},function(q){o.data=q.data;o.config=q;o.render()})}});var d=Backbone.View.extend({initialize:function(p){var o=this;o.phylovizView=p;$("#panelHeaderRightBtns").empty();$("#phyloVizNavBtns").empty();$("#phylovizNexSelector").off();o.initNavBtns();o.initRightHeaderBtns();$("#phylovizNexSelector").off().on("change",function(){o.phylovizView.reloadViz()})},initRightHeaderBtns:function(){var o=this;rightMenu=c.create_icon_buttons_menu([{icon_class:"gear",title:"PhyloViz Settings",on_click:function(){$("#SettingsMenu").show();o.settingsMenu.updateUI()}},{icon_class:"disk",title:"Save visualization",on_click:function(){var p=$("#phylovizNexSelector option:selected").text();if(p){o.phylovizView.phyloTree.set("title",p)}o.phylovizView.phyloTree.save()}},{icon_class:"chevron-expand",title:"Search / Edit Nodes",on_click:function(){$("#nodeSelectionView").show()}},{icon_class:"information",title:"Phyloviz Help",on_click:function(){window.open("https://wiki.galaxyproject.org/Learn/Visualization/PhylogeneticTree")}}],{tooltip_config:{placement:"bottom"}});$("#panelHeaderRightBtns").append(rightMenu.$el)},initNavBtns:function(){var o=this,p=c.create_icon_buttons_menu([{icon_class:"zoom-in",title:"Zoom in",on_click:function(){o.phylovizView.zoomAndPan({zoom:"+"})}},{icon_class:"zoom-out",title:"Zoom out",on_click:function(){o.phylovizView.zoomAndPan({zoom:"-"})}},{icon_class:"arrow-circle",title:"Reset Zoom/Pan",on_click:function(){o.phylovizView.zoomAndPan({zoom:"reset"})}}],{tooltip_config:{placement:"bottom"}});$("#phyloVizNavBtns").append(p.$el)}});var j=m.extend({className:"Settings",initialize:function(p){var o=this;o.phyloTree=p.phyloTree;o.el=$("#SettingsMenu");o.inputs={separation:$("#phyloVizTreeSeparation"),leafHeight:$("#phyloVizTreeLeafHeight"),fontSize:$("#phyloVizTreeFontSize")};$("#settingsCloseBtn").off().on("click",function(){o.el.hide()});$("#phylovizResetSettingsBtn").off().on("click",function(){o.resetToDefaults()});$("#phylovizApplySettingsBtn").off().on("click",function(){o.apply()})},apply:function(){var o=this;if(!o.isAcceptableValue(o.inputs.separation,50,2500)||!o.isAcceptableValue(o.inputs.leafHeight,5,30)||!o.isAcceptableValue(o.inputs.fontSize,5,20)){return}$.each(o.inputs,function(p,q){o.phyloTree.set(p,q.val())})},updateUI:function(){var o=this;$.each(o.inputs,function(p,q){q.val(o.phyloTree.get(p))})},resetToDefaults:function(){$(".tooltip").remove();var o=this;$.each(o.phyloTree.defaults,function(p,q){o.phyloTree.set(p,q)});o.updateUI()},render:function(){}});var f=m.extend({className:"Settings",initialize:function(p){var o=this;o.el=$("#nodeSelectionView");o.phyloTree=p.phyloTree;o.UI={enableEdit:$("#phylovizEditNodesCheck"),saveChanges:$("#phylovizNodeSaveChanges"),cancelChanges:$("#phylovizNodeCancelChanges"),name:$("#phyloVizSelectedNodeName"),dist:$("#phyloVizSelectedNodeDist"),annotation:$("#phyloVizSelectedNodeAnnotation")};o.valuesOfConcern={name:null,dist:null,annotation:null};$("#nodeSelCloseBtn").off().on("click",function(){o.el.hide()});o.UI.saveChanges.off().on("click",function(){o.updateNodes()});o.UI.cancelChanges.off().on("click",function(){o.cancelChanges()});(function(q){q.fn.enable=function(r){return q(this).each(function(){if(r){q(this).removeAttr("disabled")}else{q(this).attr("disabled","disabled")}})}})(jQuery);o.UI.enableEdit.off().on("click",function(){o.toggleUI()})},toggleUI:function(){var o=this,p=o.UI.enableEdit.is(":checked");if(!p){o.cancelChanges()}$.each(o.valuesOfConcern,function(q,r){o.UI[q].enable(p)});if(p){o.UI.saveChanges.show();o.UI.cancelChanges.show()}else{o.UI.saveChanges.hide();o.UI.cancelChanges.hide()}},cancelChanges:function(){var o=this,p=o.phyloTree.get("selectedNode");if(p){$.each(o.valuesOfConcern,function(q,r){o.UI[q].val(p[q])})}},updateNodes:function(){var o=this,p=o.phyloTree.get("selectedNode");if(p){if(!o.isAcceptableValue(o.UI.dist,0,1)||o.hasIllegalJsonCharacters(o.UI.name)||o.hasIllegalJsonCharacters(o.UI.annotation)){return}$.each(o.valuesOfConcern,function(q,r){(p[q])=o.UI[q].val()});o.phyloTree.set("nodeAttrChangedTime",new Date())}else{alert("No node selected")}}});var l=m.extend({initialize:function(){var o=this;$("#phyloVizSearchBtn").on("click",function(){var q=$("#phyloVizSearchTerm"),r=$("#phyloVizSearchCondition").val().split("-"),p=r[0],s=r[1];o.hasIllegalJsonCharacters(q);if(p==="dist"){o.isAcceptableValue(q,0,1)}o.searchTree(p,s,q.val())})},searchTree:function(o,q,p){n.selectAll("g.node").classed("searchHighlight",function(s){var r=s[o];if(typeof r!=="undefined"&&r!==null){if(o==="dist"){switch(q){case"greaterEqual":return r>=+p;case"lesserEqual":return r<=+p;default:return}}else{if(o==="name"||o==="annotation"){return r.toLowerCase().indexOf(p.toLowerCase())!==-1}}}})}});return{PhylovizView:k}});
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/viz/sweepster.js
--- a/static/scripts/packed/viz/sweepster.js
+++ b/static/scripts/packed/viz/sweepster.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","libs/d3","viz/trackster/util","viz/visualization","viz/trackster/tracks","mvc/tools","mvc/data","utils/config"],function(q,p,e,j,m,n,r,o){var k=Backbone.Model.extend({defaults:{inputs:null,values:null}});var a=Backbone.Model.extend({defaults:{tool:null,tree_data:null},initialize:function(t){var s=this;this.get("tool").get("inputs").each(function(u){u.on("change:min change:max change:num_samples",function(v){if(v.get("in_ptree")){s.set_tree_data()}},s);u.on("change:in_ptree",function(v){if(v.get("in_ptree")){s.add_param(v)}else{s.remove_param(v)}s.set_tree_data()},s)});if(t.config){q.each(t.config,function(v){var u=s.get("tool").get("inputs").find(function(w){return w.get("name")===v.name});s.add_param(u);u.set(v)})}},add_param:function(s){if(s.get("ptree_index")){return}s.set("in_ptree",true);s.set("ptree_index",this.get_tree_params().length)},remove_param:function(s){s.set("in_ptree",false);s.set("ptree_index",null);q(this.get_tree_params()).each(function(t,u){t.set("ptree_index",u+1)})},set_tree_data:function(){var t=q.map(this.get_tree_params(),function(v){return{param:v,samples:v.get_samples()}});var s=0,u=function(y,v){var A=y[v],z=A.param,x=z.get("label"),w=A.samples;if(y.length-1===v){return q.map(w,function(B){return{id:s++,name:B,param:z,value:B}})}return q.map(w,function(B){return{id:s++,name:B,param:z,value:B,children:u(y,v+1)}})};this.set("tree_data",{name:"Root",id:s++,children:(t.length!==0?u(t,0):null)})},get_tree_params:function(){return q(this.get("tool").get("inputs").where({in_ptree:true})).sortBy(function(s){return s.get("ptree_index")})},get_num_leaves:function(){return this.get_tree_params().reduce(function(s,t){return s*t.get_samples().length},1)},get_node_settings:function(w){var u=this.get("tool").get_inputs_dict();var x=w.parent;if(x){while(x.depth!==0){u[x.param.get("name")]=x.value;x=x.parent}}var s=this,t=function(z,y){if(z.param){y[z.param.get("name")]=z.value}if(!z.children){return new k({inputs:s.get("tool").get("inputs"),values:y})}else{return q.flatten(q.map(z.children,function(A){return t(A,q.clone(y))}))}},v=t(w,u);if(!q.isArray(v)){v=[v]}return v},get_connected_nodes:function(u){var v=function(w){if(!w.children){return w}else{return q.flatten([w,q.map(w.children,function(x){return v(x)})])}};var t=[],s=u.parent;while(s){t.push(s);s=s.parent}return q.flatten([t,v(u)])},get_leaf:function(t){var u=this.get("tree_data"),s=function(v){return q.find(v,function(w){return t[w.param.get("name")]===w.value})};while(u.children){u=s(u.children)}return u},toJSON:function(){return this.get_tree_params().map(function(s){return{name:s.get("name"),min:s.get("min"),max:s.get("max"),num_samples:s.get("num_samples")}})}});var d=Backbone.Model.extend({defaults:{track:null,mode:"Pack",settings:null,regions:null},initialize:function(s){this.set("regions",s.regions);if(s.track){var t=q.extend({data_url:galaxy_config.root+"dummy1",converted_datasets_state_url:galaxy_config.root+"dummy2"},s.track);this.set("track",m.object_from_template(t,{},null))}},same_settings:function(s){var t=this.get("settings"),u=s.get("settings");for(var v in t){if(!u[v]||t[v]!==u[v]){return false}}return true},toJSON:function(){return{track:this.get("track").to_dict(),settings:this.get("settings"),regions:this.get("regions")}}});var l=Backbone.Collection.extend({model:d});var c=j.Visualization.extend({defaults:q.extend({},j.Visualization.prototype.defaults,{dataset:null,tool:null,parameter_tree:null,regions:null,tracks:null,default_mode:"Pack"}),initialize:function(s){this.set("dataset",new r.Dataset(s.dataset));this.set("tool",new n.Tool(s.tool));this.set("regions",new j.GenomeRegionCollection(s.regions));this.set("tracks",new l(s.tracks));var t=this.get("tool");this.set("tool_with_samplable_inputs",t);t.remove_inputs(["data","hidden_data","conditional","text"]);this.set("parameter_tree",new a({tool:t,config:s.tree_config}))},add_track:function(s){this.get("tracks").add(s)},toJSON:function(){return{id:this.get("id"),title:"Parameter exploration for dataset '"+this.get("dataset").get("name")+"'",type:"sweepster",dataset_id:this.get("dataset").id,tool_id:this.get("tool").id,regions:this.get("regions").toJSON(),tree_config:this.get("parameter_tree").toJSON(),tracks:this.get("tracks").toJSON()}}});var h=Backbone.View.extend({tagName:"tr",TILE_LEN:250,initialize:function(s){this.canvas_manager=s.canvas_manager;this.render();this.model.on("change:track change:mode",this.draw_tiles,this)},render:function(){var x=this.model.get("settings"),t=x.get("values"),v=$("<td/>").addClass("settings").appendTo(this.$el),u=$("<div/>").addClass("track-info").hide().appendTo(v);u.append($("<div/>").css("font-weight","bold").text("Track Settings"));x.get("inputs").each(function(z){u.append(z.get("label")+": "+t[z.get("name")]+"<br/>")});var s=this,y=$("<button/>").appendTo(u).text("Run on complete dataset").click(function(){u.toggle();s.trigger("run_on_dataset",x)});var w=create_icon_buttons_menu([{title:"Settings",icon_class:"gear track-settings",on_click:function(){u.toggle()}},{title:"Remove",icon_class:"cross-circle",on_click:function(){s.$el.remove();$(".tooltip").remove()}}]);v.prepend(w.$el);this.model.get("regions").each(function(){s.$el.append($("<td/>").addClass("tile").html($("<img/>").attr("src",galaxy_config.root+"images/loading_large_white_bg.gif")))});if(this.model.get("track")){this.draw_tiles()}},draw_tiles:function(){var t=this,s=this.model.get("track"),v=this.model.get("regions"),u=this.$el.find("td.tile");if(!s){return}$.when(s.data_manager.data_is_ready()).then(function(w){v.each(function(z,y){var x=z.length()/t.TILE_LEN,B=1/x,A=t.model.get("mode");$.when(s.data_manager.get_data(z,A,x,{})).then(function(D){var C=t.canvas_manager.new_canvas();C.width=t.TILE_LEN;C.height=s.get_canvas_height(D,A,B,C.width);s.draw_tile(D,C.getContext("2d"),A,z,B);$(u[y]).empty().append(C)})})})}});var g=Backbone.View.extend({number_input_template:'<div class="form-row-input sweep"><input class="min" type="text" size="6" value="<%= min %>"> - <input class="max" type="text" size="6" value="<%= max %>"> samples: <input class="num_samples" type="text" size="1" value="<%= num_samples %>"></div>',select_input_template:'<div class="form-row-input sweep"><%= options %></div>',initialize:function(s){this.$el=s.tool_row;this.render()},render:function(){var t=this.model,x=t.get("type"),z=this.$el.find(".form-row-input"),v=null;z.find(":input").change(function(){t.set("value",$(this).val())});if(t instanceof n.IntegerToolParameter){v=$(q.template(this.number_input_template,this.model.toJSON()))}else{if(t instanceof n.SelectToolParameter){var u=q.map(this.$el.find("select option"),function(A){return $(A).val()}),w=u.join(", ");v=$(q.template(this.select_input_template,{options:w}))}}v.insertAfter(z);var s=this,y=create_icon_buttons_menu([{title:"Add parameter to tree",icon_class:"plus-button",on_click:function(){t.set("in_ptree",true);z.hide();v.show();$(this).hide();s.$el.find(".icon-button.toggle").show()}},{title:"Remove parameter from tree",icon_class:"toggle",on_click:function(){t.set("in_ptree",false);v.hide();z.show();$(this).hide();s.$el.find(".icon-button.plus-button").show()}}],{});this.$el.prepend(y.$el);if(t.get("in_ptree")){z.hide();s.$el.find(".icon-button.plus-button").hide()}else{s.$el.find(".icon-button.toggle").hide();v.hide()}q.each(["min","max","num_samples"],function(A){v.find("."+A).change(function(){t.set(A,parseFloat($(this).val()))})})}});var i=Backbone.View.extend({className:"tree-design",initialize:function(s){this.render()},render:function(){var u=new n.ToolFormView({model:this.model.get("tool")});u.render();this.$el.append(u.$el);var t=this,s=t.model.get("tool").get("inputs");this.$el.find(".form-row").not(".form-actions").each(function(v){var w=new g({model:s.at(v),tool_row:$(this)})})}});var b=Backbone.View.extend({className:"tool-parameter-tree",initialize:function(s){this.model.on("change:tree_data",this.render,this)},render:function(){this.$el.children().remove();var A=this.model.get_tree_params();if(!A.length){return}this.width=100*(2+A.length);this.height=15*this.model.get_num_leaves();var z=this;var y=p.layout.cluster().size([this.height,this.width-160]);var u=p.svg.diagonal().projection(function(B){return[B.y,B.x]});var s=y.nodes(this.model.get("tree_data"));var v=q.uniq(q.pluck(s,"y"));q.each(A,function(D,C){var B=v[C+1],E=$("#center").position().left;z.$el.append($("<div>").addClass("label").text(D.get("label")).css("left",B+E))});var t=p.select(this.$el[0]).append("svg").attr("width",this.width).attr("height",this.height+30).append("g").attr("transform","translate(40, 20)");var x=t.selectAll("path.link").data(y.links(s)).enter().append("path").attr("class","link").attr("d",u);var w=t.selectAll("g.node").data(s).enter().append("g").attr("class","node").attr("transform",function(B){return"translate("+B.y+","+B.x+")"}).on("mouseover",function(C){var B=q.pluck(z.model.get_connected_nodes(C),"id");w.filter(function(D){return q.find(B,function(E){return E===D.id})!==undefined}).style("fill","#f00")}).on("mouseout",function(){w.style("fill","#000")});w.append("circle").attr("r",9);w.append("text").attr("dx",function(B){return B.children?-12:12}).attr("dy",3).attr("text-anchor",function(B){return B.children?"end":"start"}).text(function(B){return B.name})}});var f=Backbone.View.extend({className:"Sweepster",helpText:"<div><h4>Getting Started</h4><ol><li>Create a parameter tree by using the icons next to the tool's parameter names to add or remove parameters.<li>Adjust the tree by using parameter inputs to select min, max, and number of samples<li>Run the tool with different settings by clicking on tree nodes</ol></div>",initialize:function(t){this.canvas_manager=new j.CanvasManager(this.$el.parents("body"));this.tool_param_tree_view=new b({model:this.model.get("parameter_tree")});this.track_collection_container=$("<table/>").addClass("tracks");this.model.get("parameter_tree").on("change:tree_data",this.handle_node_clicks,this);var s=this;this.model.get("tracks").each(function(u){u.get("track").view=s});this.config=o.ConfigSettingCollection.from_models_and_saved_values([{key:"name",label:"Name",type:"text",default_value:""},{key:"a_color",label:"A Color",type:"color",default_value:"#FF0000"},{key:"c_color",label:"C Color",type:"color",default_value:"#00FF00"},{key:"g_color",label:"G Color",type:"color",default_value:"#0000FF"},{key:"t_color",label:"T Color",type:"color",default_value:"#FF00FF"},{key:"n_color",label:"N Color",type:"color",default_value:"#AAAAAA"},{key:"block_color",label:"Block color",type:"color"},{key:"reverse_strand_color",label:"Antisense strand color",type:"color"},],{})},render:function(){var y=new i({model:this.model.get("parameter_tree")});$("#left").append(y.$el);var B=this,v=B.model.get("regions"),z=$("<tr/>").appendTo(this.track_collection_container);v.each(function(C){z.append($("<th>").text(C.toString()))});z.children().first().attr("colspan",2);var w=$("<div>").addClass("tiles");$("#right").append(w.append(this.track_collection_container));B.model.get("tracks").each(function(C){B.add_track(C)});var A=$(this.helpText).addClass("help"),x=create_icon_buttons_menu([{title:"Close",icon_class:"cross-circle",on_click:function(){$(".tooltip").remove();A.remove()}}]);A.prepend(x.$el.css("float","right"));$("#center").append(A);this.tool_param_tree_view.render();$("#center").append(this.tool_param_tree_view.$el);this.handle_node_clicks();var u=create_icon_buttons_menu([{icon_class:"chevron-expand",title:"Set display mode"},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location="${h.url_for( controller='visualization', action='list' )}"}}],{tooltip_config:{placement:"bottom"}});var t=["Squish","Pack"],s={};q.each(t,function(C){s[C]=function(){B.model.set("default_mode",C);B.model.get("tracks").each(function(D){D.set("mode",C)})}});make_popupmenu(u.$el.find(".chevron-expand"),s);u.$el.attr("style","float: right");$("#right .unified-panel-header-inner").append(u.$el)},get_base_color:function(s){return this.config.get_value(s.toLowerCase()+"_color")||this.config.get_value("n_color")},run_tool_on_dataset:function(t){var s=this.model.get("tool"),v=s.get("name"),u=this.model.get("dataset");s.set_input_values(t.get("values"));$.when(s.rerun(u)).then(function(w){});show_modal("Running "+v+" on complete dataset",v+" is running on dataset '"+u.get("name")+"'. Outputs are in the dataset's history.",{Ok:function(){hide_modal()}})},add_track:function(v){var t=this,u=this.model.get("parameter_tree");t.model.add_track(v);var s=new h({model:v,canvas_manager:t.canvas_manager});s.on("run_on_dataset",t.run_tool_on_dataset,t);t.track_collection_container.append(s.$el);s.$el.hover(function(){var x=u.get_leaf(v.get("settings").get("values"));var w=q.pluck(u.get_connected_nodes(x),"id");p.select(t.tool_param_tree_view.$el[0]).selectAll("g.node").filter(function(y){return q.find(w,function(z){return z===y.id})!==undefined}).style("fill","#f00")},function(){p.select(t.tool_param_tree_view.$el[0]).selectAll("g.node").style("fill","#000")});return v},handle_node_clicks:function(){var s=this,t=this.model.get("parameter_tree"),v=this.model.get("regions"),u=p.select(this.tool_param_tree_view.$el[0]).selectAll("g.node");u.on("click",function(B,y){var x=s.model.get("tool"),A=s.model.get("dataset"),z=t.get_node_settings(B),w=$.Deferred();if(z.length>=10){show_modal("Whoa there cowboy!","You clicked on a node to try "+s.model.get("tool").get("name")+" with "+z.length+" different combinations of settings. You can only run 10 jobs at a time.",{Ok:function(){hide_modal();w.resolve(false)}})}else{w.resolve(true)}$.when(w).then(function(C){if(!C){return}var D=q.map(z,function(E){var F=new d({settings:E,regions:v,mode:s.model.get("default_mode")});s.add_track(F);return F});q.each(D,function(F,E){setTimeout(function(){x.set_input_values(F.get("settings").get("values"));$.when(x.rerun(A,v)).then(function(H){var I=H.first(),J=I.get("track_config");J.dataset=I;J.tool=null;J.prefs=s.config.to_key_value_dict();var G=m.object_from_template(J,s,null);G.init_for_tool_data();F.set("track",G)})},E*10000)})})})}});return{SweepsterVisualization:c,SweepsterVisualizationView:f}});
\ No newline at end of file
+define(["libs/underscore","libs/d3","viz/trackster/util","viz/visualization","viz/trackster/tracks","mvc/tools","mvc/data","utils/config","mvc/ui/icon-button"],function(r,q,e,k,n,o,s,p,i){var l=Backbone.Model.extend({defaults:{inputs:null,values:null}});var b=Backbone.Model.extend({defaults:{tool:null,tree_data:null},initialize:function(u){var t=this;this.get("tool").get("inputs").each(function(v){v.on("change:min change:max change:num_samples",function(w){if(w.get("in_ptree")){t.set_tree_data()}},t);v.on("change:in_ptree",function(w){if(w.get("in_ptree")){t.add_param(w)}else{t.remove_param(w)}t.set_tree_data()},t)});if(u.config){r.each(u.config,function(w){var v=t.get("tool").get("inputs").find(function(x){return x.get("name")===w.name});t.add_param(v);v.set(w)})}},add_param:function(t){if(t.get("ptree_index")){return}t.set("in_ptree",true);t.set("ptree_index",this.get_tree_params().length)},remove_param:function(t){t.set("in_ptree",false);t.set("ptree_index",null);r(this.get_tree_params()).each(function(u,v){u.set("ptree_index",v+1)})},set_tree_data:function(){var u=r.map(this.get_tree_params(),function(w){return{param:w,samples:w.get_samples()}});var t=0,v=function(z,w){var B=z[w],A=B.param,y=A.get("label"),x=B.samples;if(z.length-1===w){return r.map(x,function(C){return{id:t++,name:C,param:A,value:C}})}return r.map(x,function(C){return{id:t++,name:C,param:A,value:C,children:v(z,w+1)}})};this.set("tree_data",{name:"Root",id:t++,children:(u.length!==0?v(u,0):null)})},get_tree_params:function(){return r(this.get("tool").get("inputs").where({in_ptree:true})).sortBy(function(t){return t.get("ptree_index")})},get_num_leaves:function(){return this.get_tree_params().reduce(function(t,u){return t*u.get_samples().length},1)},get_node_settings:function(x){var v=this.get("tool").get_inputs_dict();var y=x.parent;if(y){while(y.depth!==0){v[y.param.get("name")]=y.value;y=y.parent}}var t=this,u=function(A,z){if(A.param){z[A.param.get("name")]=A.value}if(!A.children){return new l({inputs:t.get("tool").get("inputs"),values:z})}else{return r.flatten(r.map(A.children,function(B){return u(B,r.clone(z))}))}},w=u(x,v);if(!r.isArray(w)){w=[w]}return w},get_connected_nodes:function(v){var w=function(x){if(!x.children){return x}else{return r.flatten([x,r.map(x.children,function(y){return w(y)})])}};var u=[],t=v.parent;while(t){u.push(t);t=t.parent}return r.flatten([u,w(v)])},get_leaf:function(u){var v=this.get("tree_data"),t=function(w){return r.find(w,function(x){return u[x.param.get("name")]===x.value})};while(v.children){v=t(v.children)}return v},toJSON:function(){return this.get_tree_params().map(function(t){return{name:t.get("name"),min:t.get("min"),max:t.get("max"),num_samples:t.get("num_samples")}})}});var d=Backbone.Model.extend({defaults:{track:null,mode:"Pack",settings:null,regions:null},initialize:function(t){this.set("regions",t.regions);if(t.track){var u=r.extend({data_url:galaxy_config.root+"dummy1",converted_datasets_state_url:galaxy_config.root+"dummy2"},t.track);this.set("track",n.object_from_template(u,{},null))}},same_settings:function(t){var u=this.get("settings"),v=t.get("settings");for(var w in u){if(!v[w]||u[w]!==v[w]){return false}}return true},toJSON:function(){return{track:this.get("track").to_dict(),settings:this.get("settings"),regions:this.get("regions")}}});var m=Backbone.Collection.extend({model:d});var c=k.Visualization.extend({defaults:r.extend({},k.Visualization.prototype.defaults,{dataset:null,tool:null,parameter_tree:null,regions:null,tracks:null,default_mode:"Pack"}),initialize:function(t){this.set("dataset",new s.Dataset(t.dataset));this.set("tool",new o.Tool(t.tool));this.set("regions",new k.GenomeRegionCollection(t.regions));this.set("tracks",new m(t.tracks));var u=this.get("tool");this.set("tool_with_samplable_inputs",u);u.remove_inputs(["data","hidden_data","conditional","text"]);this.set("parameter_tree",new b({tool:u,config:t.tree_config}))},add_track:function(t){this.get("tracks").add(t)},toJSON:function(){return{id:this.get("id"),title:"Parameter exploration for dataset '"+this.get("dataset").get("name")+"'",type:"sweepster",dataset_id:this.get("dataset").id,tool_id:this.get("tool").id,regions:this.get("regions").toJSON(),tree_config:this.get("parameter_tree").toJSON(),tracks:this.get("tracks").toJSON()}}});var h=Backbone.View.extend({tagName:"tr",TILE_LEN:250,initialize:function(t){this.canvas_manager=t.canvas_manager;this.render();this.model.on("change:track change:mode",this.draw_tiles,this)},render:function(){var y=this.model.get("settings"),u=y.get("values"),w=$("<td/>").addClass("settings").appendTo(this.$el),v=$("<div/>").addClass("track-info").hide().appendTo(w);v.append($("<div/>").css("font-weight","bold").text("Track Settings"));y.get("inputs").each(function(A){v.append(A.get("label")+": "+u[A.get("name")]+"<br/>")});var t=this,z=$("<button/>").appendTo(v).text("Run on complete dataset").click(function(){v.toggle();t.trigger("run_on_dataset",y)});var x=i.create_icon_buttons_menu([{title:"Settings",icon_class:"gear track-settings",on_click:function(){v.toggle()}},{title:"Remove",icon_class:"cross-circle",on_click:function(){t.$el.remove();$(".tooltip").remove()}}]);w.prepend(x.$el);this.model.get("regions").each(function(){t.$el.append($("<td/>").addClass("tile").html($("<img/>").attr("src",galaxy_config.root+"images/loading_large_white_bg.gif")))});if(this.model.get("track")){this.draw_tiles()}},draw_tiles:function(){var u=this,t=this.model.get("track"),w=this.model.get("regions"),v=this.$el.find("td.tile");if(!t){return}$.when(t.data_manager.data_is_ready()).then(function(x){w.each(function(A,z){var y=A.length()/u.TILE_LEN,C=1/y,B=u.model.get("mode");$.when(t.data_manager.get_data(A,B,y,{})).then(function(E){var D=u.canvas_manager.new_canvas();D.width=u.TILE_LEN;D.height=t.get_canvas_height(E,B,C,D.width);t.draw_tile(E,D.getContext("2d"),B,A,C);$(v[z]).empty().append(D)})})})}});var g=Backbone.View.extend({number_input_template:'<div class="form-row-input sweep"><input class="min" type="text" size="6" value="<%= min %>"> - <input class="max" type="text" size="6" value="<%= max %>"> samples: <input class="num_samples" type="text" size="1" value="<%= num_samples %>"></div>',select_input_template:'<div class="form-row-input sweep"><%= options %></div>',initialize:function(t){this.$el=t.tool_row;this.render()},render:function(){var u=this.model,y=u.get("type"),A=this.$el.find(".form-row-input"),w=null;A.find(":input").change(function(){u.set("value",$(this).val())});if(u instanceof o.IntegerToolParameter){w=$(r.template(this.number_input_template,this.model.toJSON()))}else{if(u instanceof o.SelectToolParameter){var v=r.map(this.$el.find("select option"),function(B){return $(B).val()}),x=v.join(", ");w=$(r.template(this.select_input_template,{options:x}))}}w.insertAfter(A);var t=this,z=i.create_icon_buttons_menu([{title:"Add parameter to tree",icon_class:"plus-button",on_click:function(){u.set("in_ptree",true);A.hide();w.show();$(this).hide();t.$el.find(".icon-button.toggle").show()}},{title:"Remove parameter from tree",icon_class:"toggle",on_click:function(){u.set("in_ptree",false);w.hide();A.show();$(this).hide();t.$el.find(".icon-button.plus-button").show()}}],{});this.$el.prepend(z.$el);if(u.get("in_ptree")){A.hide();t.$el.find(".icon-button.plus-button").hide()}else{t.$el.find(".icon-button.toggle").hide();w.hide()}r.each(["min","max","num_samples"],function(B){w.find("."+B).change(function(){u.set(B,parseFloat($(this).val()))})})}});var j=Backbone.View.extend({className:"tree-design",initialize:function(t){this.render()},render:function(){var v=new o.ToolFormView({model:this.model.get("tool")});v.render();this.$el.append(v.$el);var u=this,t=u.model.get("tool").get("inputs");this.$el.find(".form-row").not(".form-actions").each(function(w){var x=new g({model:t.at(w),tool_row:$(this)})})}});var a=Backbone.View.extend({className:"tool-parameter-tree",initialize:function(t){this.model.on("change:tree_data",this.render,this)},render:function(){this.$el.children().remove();var B=this.model.get_tree_params();if(!B.length){return}this.width=100*(2+B.length);this.height=15*this.model.get_num_leaves();var A=this;var z=q.layout.cluster().size([this.height,this.width-160]);var v=q.svg.diagonal().projection(function(C){return[C.y,C.x]});var t=z.nodes(this.model.get("tree_data"));var w=r.uniq(r.pluck(t,"y"));r.each(B,function(E,D){var C=w[D+1],F=$("#center").position().left;A.$el.append($("<div>").addClass("label").text(E.get("label")).css("left",C+F))});var u=q.select(this.$el[0]).append("svg").attr("width",this.width).attr("height",this.height+30).append("g").attr("transform","translate(40, 20)");var y=u.selectAll("path.link").data(z.links(t)).enter().append("path").attr("class","link").attr("d",v);var x=u.selectAll("g.node").data(t).enter().append("g").attr("class","node").attr("transform",function(C){return"translate("+C.y+","+C.x+")"}).on("mouseover",function(D){var C=r.pluck(A.model.get_connected_nodes(D),"id");x.filter(function(E){return r.find(C,function(F){return F===E.id})!==undefined}).style("fill","#f00")}).on("mouseout",function(){x.style("fill","#000")});x.append("circle").attr("r",9);x.append("text").attr("dx",function(C){return C.children?-12:12}).attr("dy",3).attr("text-anchor",function(C){return C.children?"end":"start"}).text(function(C){return C.name})}});var f=Backbone.View.extend({className:"Sweepster",helpText:"<div><h4>Getting Started</h4><ol><li>Create a parameter tree by using the icons next to the tool's parameter names to add or remove parameters.<li>Adjust the tree by using parameter inputs to select min, max, and number of samples<li>Run the tool with different settings by clicking on tree nodes</ol></div>",initialize:function(u){this.canvas_manager=new k.CanvasManager(this.$el.parents("body"));this.tool_param_tree_view=new a({model:this.model.get("parameter_tree")});this.track_collection_container=$("<table/>").addClass("tracks");this.model.get("parameter_tree").on("change:tree_data",this.handle_node_clicks,this);var t=this;this.model.get("tracks").each(function(v){v.get("track").view=t});this.config=p.ConfigSettingCollection.from_models_and_saved_values([{key:"name",label:"Name",type:"text",default_value:""},{key:"a_color",label:"A Color",type:"color",default_value:"#FF0000"},{key:"c_color",label:"C Color",type:"color",default_value:"#00FF00"},{key:"g_color",label:"G Color",type:"color",default_value:"#0000FF"},{key:"t_color",label:"T Color",type:"color",default_value:"#FF00FF"},{key:"n_color",label:"N Color",type:"color",default_value:"#AAAAAA"},{key:"block_color",label:"Block color",type:"color"},{key:"reverse_strand_color",label:"Antisense strand color",type:"color"},],{})},render:function(){var z=new j({model:this.model.get("parameter_tree")});$("#left").append(z.$el);var C=this,w=C.model.get("regions"),A=$("<tr/>").appendTo(this.track_collection_container);w.each(function(D){A.append($("<th>").text(D.toString()))});A.children().first().attr("colspan",2);var x=$("<div>").addClass("tiles");$("#right").append(x.append(this.track_collection_container));C.model.get("tracks").each(function(D){C.add_track(D)});var B=$(this.helpText).addClass("help"),y=i.create_icon_buttons_menu([{title:"Close",icon_class:"cross-circle",on_click:function(){$(".tooltip").remove();B.remove()}}]);B.prepend(y.$el.css("float","right"));$("#center").append(B);this.tool_param_tree_view.render();$("#center").append(this.tool_param_tree_view.$el);this.handle_node_clicks();var v=i.create_icon_buttons_menu([{icon_class:"chevron-expand",title:"Set display mode"},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location="${h.url_for( controller='visualization', action='list' )}"}}],{tooltip_config:{placement:"bottom"}});var u=["Squish","Pack"],t={};r.each(u,function(D){t[D]=function(){C.model.set("default_mode",D);C.model.get("tracks").each(function(E){E.set("mode",D)})}});make_popupmenu(v.$el.find(".chevron-expand"),t);v.$el.attr("style","float: right");$("#right .unified-panel-header-inner").append(v.$el)},get_base_color:function(t){return this.config.get_value(t.toLowerCase()+"_color")||this.config.get_value("n_color")},run_tool_on_dataset:function(u){var t=this.model.get("tool"),w=t.get("name"),v=this.model.get("dataset");t.set_input_values(u.get("values"));$.when(t.rerun(v)).then(function(x){});show_modal("Running "+w+" on complete dataset",w+" is running on dataset '"+v.get("name")+"'. Outputs are in the dataset's history.",{Ok:function(){hide_modal()}})},add_track:function(w){var u=this,v=this.model.get("parameter_tree");u.model.add_track(w);var t=new h({model:w,canvas_manager:u.canvas_manager});t.on("run_on_dataset",u.run_tool_on_dataset,u);u.track_collection_container.append(t.$el);t.$el.hover(function(){var y=v.get_leaf(w.get("settings").get("values"));var x=r.pluck(v.get_connected_nodes(y),"id");q.select(u.tool_param_tree_view.$el[0]).selectAll("g.node").filter(function(z){return r.find(x,function(A){return A===z.id})!==undefined}).style("fill","#f00")},function(){q.select(u.tool_param_tree_view.$el[0]).selectAll("g.node").style("fill","#000")});return w},handle_node_clicks:function(){var t=this,u=this.model.get("parameter_tree"),w=this.model.get("regions"),v=q.select(this.tool_param_tree_view.$el[0]).selectAll("g.node");v.on("click",function(C,z){var y=t.model.get("tool"),B=t.model.get("dataset"),A=u.get_node_settings(C),x=$.Deferred();if(A.length>=10){show_modal("Whoa there cowboy!","You clicked on a node to try "+t.model.get("tool").get("name")+" with "+A.length+" different combinations of settings. You can only run 10 jobs at a time.",{Ok:function(){hide_modal();x.resolve(false)}})}else{x.resolve(true)}$.when(x).then(function(D){if(!D){return}var E=r.map(A,function(F){var G=new d({settings:F,regions:w,mode:t.model.get("default_mode")});t.add_track(G);return G});r.each(E,function(G,F){setTimeout(function(){y.set_input_values(G.get("settings").get("values"));$.when(y.rerun(B,w)).then(function(I){var J=I.first(),K=J.get("track_config");K.dataset=J;K.tool=null;K.prefs=t.config.to_key_value_dict();var H=n.object_from_template(K,t,null);H.init_for_tool_data();G.set("track",H)})},F*10000)})})})}});return{SweepsterVisualization:c,SweepsterVisualizationView:f}});
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/packed/viz/trackster.js
--- a/static/scripts/packed/viz/trackster.js
+++ b/static/scripts/packed/viz/trackster.js
@@ -1,1 +1,1 @@
-var ui=null;var view=null;var browser_router=null;require(["utils/utils","libs/jquery/jquery.event.drag","libs/jquery/jquery.event.hover","libs/jquery/jquery.mousewheel","libs/jquery/jquery-ui","libs/jquery/select2","libs/farbtastic","libs/jquery/jquery.form","libs/jquery/jquery.rating","mvc/ui"],function(a){a.cssLoadFile("static/style/jquery.rating.css");a.cssLoadFile("static/style/autocomplete_tagging.css");a.cssLoadFile("static/style/jquery-ui/smoothness/jquery-ui.css");a.cssLoadFile("static/style/library.css");a.cssLoadFile("static/style/trackster.css")});define(["libs/underscore","base","viz/trackster/tracks","viz/visualization"],function(b,e,a,c){var d=e.Base.extend({initialize:function(g){this.baseURL=g},save_viz:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});var g=[];$(".bookmark").each(function(){g.push({position:$(this).children(".position").text(),annotation:$(this).children(".annotation").text()})});var h=(view.overview_drawable?view.overview_drawable.config.get_value("name"):null),j={view:view.to_dict(),viewport:{chrom:view.chrom,start:view.low,end:view.high,overview:h},bookmarks:g};return $.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:view.vis_id,title:view.config.get_value("name"),dbkey:view.dbkey,type:"trackster",vis_json:JSON.stringify(j)}}).success(function(k){Galaxy.modal.hide();view.vis_id=k.vis_id;view.has_changes=false;window.history.pushState({},"",k.url+window.location.hash)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})},createButtonMenu:function(){var g=this,h=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){c.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",{"f-dbkey":view.dbkey},function(j){b.each(j,function(k){view.add_drawable(a.object_from_template(k,view,view))})})}},{icon_class:"block--plus",title:"Add group",on_click:function(){view.add_drawable(new a.DrawableGroup(view,view,{name:"New Group"}))}},{icon_class:"bookmarks",title:"Bookmarks",on_click:function(){force_right_panel(($("div#right").css("right")=="0px"?"hide":"show"))}},{icon_class:"globe",title:"Circster",on_click:function(){window.location=g.baseURL+"visualization/circster?id="+view.vis_id}},{icon_class:"disk--arrow",title:"Save",on_click:function(){g.save_viz()}},{icon_class:"cross-circle",title:"Close",on_click:function(){g.handle_unsaved_changes(view)}}],{tooltip_config:{placement:"bottom"}});this.buttonMenu=h;return h},add_bookmarks:function(){var g=this,h=this.baseURL;Galaxy.modal.show({title:"Select dataset for new bookmarks",body:"progress"});$.ajax({url:this.baseURL+"/visualization/list_histories",data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(j){Galaxy.modal.show({title:"Select dataset for new bookmarks",body:j,buttons:{Cancel:function(){Galaxy.modal.hide()},Insert:function(){$("input[name=id]:checked,input[name=ldda_ids]:checked").first().each(function(){var k,l=$(this).val();if($(this).attr("name")==="id"){k={hda_id:l}}else{k={ldda_id:l}}$.ajax({url:this.baseURL+"/visualization/bookmarks_from_dataset",data:k,dataType:"json"}).then(function(m){for(i=0;i<m.data.length;i++){var n=m.data[i];g.add_bookmark(n[0],n[1])}})});Galaxy.modal.hide()}}})}})},add_bookmark:function(l,j,g){var n=$("#right .unified-panel-body"),p=$("<div/>").addClass("bookmark").appendTo(n);var q=$("<div/>").addClass("position").appendTo(p),m=$("<a href=''/>").text(l).appendTo(q).click(function(){view.go_to(l);return false}),k=$("<div/>").text(j).appendTo(p);if(g){var o=$("<div/>").addClass("delete-icon-container").prependTo(p).click(function(){p.slideUp("fast");p.remove();view.has_changes=true;return false}),h=$("<a href=''/>").addClass("icon-button delete").appendTo(o);k.make_text_editable({num_rows:3,use_textarea:true,help_text:"Edit bookmark note"}).addClass("annotation")}view.has_changes=true;return p},create_visualization:function(m,g,l,n,k){var j=this,h=new a.TracksterView(b.extend(m,{header:false}));h.editor=true;$.when(h.load_chroms_deferred).then(function(y){if(g){var w=g.chrom,o=g.start,t=g.end,q=g.overview;if(w&&(o!==undefined)&&t){h.change_chrom(w,o,t)}else{h.change_chrom(y[0].chrom)}}else{h.change_chrom(y[0].chrom)}if(l){var r,p,s;for(var u=0;u<l.length;u++){h.add_drawable(a.object_from_template(l[u],h,h))}}var x;for(var u=0;u<h.drawables.length;u++){if(h.drawables[u].config.get_value("name")===q){h.set_overview(h.drawables[u]);break}}if(n){var v;for(var u=0;u<n.length;u++){v=n[u];j.add_bookmark(v.position,v.annotation,k)}}h.has_changes=false});this.set_up_router({view:h});return h},set_up_router:function(g){new c.TrackBrowserRouter(g);Backbone.history.start()},init_keyboard_nav:function(g){$(document).keyup(function(h){if($(h.srcElement).is(":input")){return}switch(h.which){case 37:g.move_fraction(0.25);break;case 38:var j=Math.round(g.viewport_container.height()/15);g.viewport_container.scrollTop(g.viewport_container.scrollTop()-20);break;case 39:g.move_fraction(-0.25);break;case 40:var j=Math.round(g.viewport_container.height()/15);g.viewport_container.scrollTop(g.viewport_container.scrollTop()+20);break}})},handle_unsaved_changes:function(g){if(g.has_changes){var h=this;Galaxy.modal.show({title:"Close visualization",body:"There are unsaved changes to your visualization which will be lost if you do not save them.",buttons:{Cancel:function(){Galaxy.modal.hide()},"Leave without Saving":function(){$(window).off("beforeunload");window.location=galaxy_config.root+"visualization"},Save:function(){$.when(h.save_viz()).then(function(){window.location=galaxy_config.root+"visualization"})}}})}else{window.location=galaxy_config.root+"visualization"}}});var f=e.Backbone.View.extend({initialize:function(){ui=new d(galaxy_config.root);ui.createButtonMenu();ui.buttonMenu.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(ui.buttonMenu.$el);$("#right .unified-panel-title").append("Bookmarks");$("#right .unified-panel-icons").append("<a id='add-bookmark-button' class='icon-button menu-button plus-button' href='javascript:void(0);' title='Add bookmark'></a>");$("#right-border").click(function(){view.resize_window()});force_right_panel("hide");if(galaxy_config.app.id){this.view_existing()}else{this.view_new()}},view_existing:function(){var g=galaxy_config.app.viz_config;view=ui.create_visualization({container:$("#center .unified-panel-body"),name:g.title,vis_id:g.vis_id,dbkey:g.dbkey},g.viewport,g.tracks,g.bookmarks,true);this.init_editor()},view_new:function(){var g=this;$.ajax({url:galaxy_config.root+"api/genomes?chrom_info=True",data:{},error:function(){alert("Couldn't create new browser.")},success:function(h){Galaxy.modal.show({title:"New Visualization",body:g.template_view_new(h),buttons:{Cancel:function(){window.location=galaxy_config.root+"visualization/list"},Create:function(){g.create_browser($("#new-title").val(),$("#new-dbkey").val());Galaxy.modal.hide()}}});if(galaxy_config.app.default_dbkey){$("#new-dbkey").val(galaxy_config.app.default_dbkey)}$("#new-title").focus();$("select[name='dbkey']").select2();$("#overlay").css("overflow","auto")}})},template_view_new:function(g){var j='<form id="new-browser-form" action="javascript:void(0);" method="post" onsubmit="return false;"><div class="form-row"><label for="new-title">Browser name:</label><div class="form-row-input"><input type="text" name="title" id="new-title" value="Unnamed"></input></div><div style="clear: both;"></div></div><div class="form-row"><label for="new-dbkey">Reference genome build (dbkey): </label><div class="form-row-input"><select name="dbkey" id="new-dbkey">';for(var h=0;h<g.length;h++){j+='<option value="'+g[h][1]+'">'+g[h][0]+"</option>"}j+='</select></div><div style="clear: both;"></div></div><div class="form-row">Is the build not listed here? <a href="'+galaxy_config.root+'user/dbkeys?use_panels=True">Add a Custom Build</a></div></form>';return j},create_browser:function(h,g){$(document).trigger("convert_to_values");view=ui.create_visualization({container:$("#center .unified-panel-body"),name:h,dbkey:g},galaxy_config.app.gene_region);this.init_editor();view.editor=true},init_editor:function(){$("#center .unified-panel-title").text(view.config.get_value("name")+" ("+view.dbkey+")");if(galaxy_config.app.add_dataset){$.ajax({url:galaxy_config.root+"api/datasets/"+galaxy_config.app.add_dataset,data:{hda_ldda:"hda",data_type:"track_config"},dataType:"json",success:function(g){view.add_drawable(a.object_from_template(g,view,view))}})}$("#add-bookmark-button").click(function(){var h=view.chrom+":"+view.low+"-"+view.high,g="Bookmark description";return ui.add_bookmark(h,g,true)});ui.init_keyboard_nav(view);$(window).on("beforeunload",function(){if(view.has_changes){return"There are unsaved changes to your visualization that will be lost if you leave this page."}})}});return{TracksterUI:d,GalaxyApp:f}});
\ No newline at end of file
+var ui=null;var view=null;var browser_router=null;require(["utils/utils","mvc/ui/icon-button","libs/jquery/jquery.event.drag","libs/jquery/jquery.event.hover","libs/jquery/jquery.mousewheel","libs/jquery/jquery-ui","libs/jquery/select2","libs/farbtastic","libs/jquery/jquery.form","libs/jquery/jquery.rating","mvc/ui"],function(b,a){b.cssLoadFile("static/style/jquery.rating.css");b.cssLoadFile("static/style/autocomplete_tagging.css");b.cssLoadFile("static/style/jquery-ui/smoothness/jquery-ui.css");b.cssLoadFile("static/style/library.css");b.cssLoadFile("static/style/trackster.css")});define(["libs/underscore","base","viz/trackster/tracks","viz/visualization"],function(b,e,a,c){var d=e.Base.extend({initialize:function(g){this.baseURL=g},save_viz:function(){Galaxy.modal.show({title:"Saving...",body:"progress"});var g=[];$(".bookmark").each(function(){g.push({position:$(this).children(".position").text(),annotation:$(this).children(".annotation").text()})});var h=(view.overview_drawable?view.overview_drawable.config.get_value("name"):null),j={view:view.to_dict(),viewport:{chrom:view.chrom,start:view.low,end:view.high,overview:h},bookmarks:g};return $.ajax({url:galaxy_config.root+"visualization/save",type:"POST",dataType:"json",data:{id:view.vis_id,title:view.config.get_value("name"),dbkey:view.dbkey,type:"trackster",vis_json:JSON.stringify(j)}}).success(function(k){Galaxy.modal.hide();view.vis_id=k.vis_id;view.has_changes=false;window.history.pushState({},"",k.url+window.location.hash)}).error(function(){Galaxy.modal.show({title:"Could Not Save",body:"Could not save visualization. Please try again later.",buttons:{Cancel:function(){Galaxy.modal.hide()}}})})},createButtonMenu:function(){var g=this,h=mod_icon_btn.create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){c.select_datasets(galaxy_config.root+"visualization/list_current_history_datasets",galaxy_config.root+"api/datasets",{"f-dbkey":view.dbkey},function(j){b.each(j,function(k){view.add_drawable(a.object_from_template(k,view,view))})})}},{icon_class:"block--plus",title:"Add group",on_click:function(){view.add_drawable(new a.DrawableGroup(view,view,{name:"New Group"}))}},{icon_class:"bookmarks",title:"Bookmarks",on_click:function(){force_right_panel(($("div#right").css("right")=="0px"?"hide":"show"))}},{icon_class:"globe",title:"Circster",on_click:function(){window.location=g.baseURL+"visualization/circster?id="+view.vis_id}},{icon_class:"disk--arrow",title:"Save",on_click:function(){g.save_viz()}},{icon_class:"cross-circle",title:"Close",on_click:function(){g.handle_unsaved_changes(view)}}],{tooltip_config:{placement:"bottom"}});this.buttonMenu=h;return h},add_bookmarks:function(){var g=this,h=this.baseURL;Galaxy.modal.show({title:"Select dataset for new bookmarks",body:"progress"});$.ajax({url:this.baseURL+"/visualization/list_histories",data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(j){Galaxy.modal.show({title:"Select dataset for new bookmarks",body:j,buttons:{Cancel:function(){Galaxy.modal.hide()},Insert:function(){$("input[name=id]:checked,input[name=ldda_ids]:checked").first().each(function(){var k,l=$(this).val();if($(this).attr("name")==="id"){k={hda_id:l}}else{k={ldda_id:l}}$.ajax({url:this.baseURL+"/visualization/bookmarks_from_dataset",data:k,dataType:"json"}).then(function(m){for(i=0;i<m.data.length;i++){var n=m.data[i];g.add_bookmark(n[0],n[1])}})});Galaxy.modal.hide()}}})}})},add_bookmark:function(l,j,g){var n=$("#right .unified-panel-body"),p=$("<div/>").addClass("bookmark").appendTo(n);var q=$("<div/>").addClass("position").appendTo(p),m=$("<a href=''/>").text(l).appendTo(q).click(function(){view.go_to(l);return false}),k=$("<div/>").text(j).appendTo(p);if(g){var o=$("<div/>").addClass("delete-icon-container").prependTo(p).click(function(){p.slideUp("fast");p.remove();view.has_changes=true;return false}),h=$("<a href=''/>").addClass("icon-button delete").appendTo(o);k.make_text_editable({num_rows:3,use_textarea:true,help_text:"Edit bookmark note"}).addClass("annotation")}view.has_changes=true;return p},create_visualization:function(m,g,l,n,k){var j=this,h=new a.TracksterView(b.extend(m,{header:false}));h.editor=true;$.when(h.load_chroms_deferred).then(function(y){if(g){var w=g.chrom,o=g.start,t=g.end,q=g.overview;if(w&&(o!==undefined)&&t){h.change_chrom(w,o,t)}else{h.change_chrom(y[0].chrom)}}else{h.change_chrom(y[0].chrom)}if(l){var r,p,s;for(var u=0;u<l.length;u++){h.add_drawable(a.object_from_template(l[u],h,h))}}var x;for(var u=0;u<h.drawables.length;u++){if(h.drawables[u].config.get_value("name")===q){h.set_overview(h.drawables[u]);break}}if(n){var v;for(var u=0;u<n.length;u++){v=n[u];j.add_bookmark(v.position,v.annotation,k)}}h.has_changes=false});this.set_up_router({view:h});return h},set_up_router:function(g){new c.TrackBrowserRouter(g);Backbone.history.start()},init_keyboard_nav:function(g){$(document).keyup(function(h){if($(h.srcElement).is(":input")){return}switch(h.which){case 37:g.move_fraction(0.25);break;case 38:var j=Math.round(g.viewport_container.height()/15);g.viewport_container.scrollTop(g.viewport_container.scrollTop()-20);break;case 39:g.move_fraction(-0.25);break;case 40:var j=Math.round(g.viewport_container.height()/15);g.viewport_container.scrollTop(g.viewport_container.scrollTop()+20);break}})},handle_unsaved_changes:function(g){if(g.has_changes){var h=this;Galaxy.modal.show({title:"Close visualization",body:"There are unsaved changes to your visualization which will be lost if you do not save them.",buttons:{Cancel:function(){Galaxy.modal.hide()},"Leave without Saving":function(){$(window).off("beforeunload");window.location=galaxy_config.root+"visualization"},Save:function(){$.when(h.save_viz()).then(function(){window.location=galaxy_config.root+"visualization"})}}})}else{window.location=galaxy_config.root+"visualization"}}});var f=e.Backbone.View.extend({initialize:function(){ui=new d(galaxy_config.root);ui.createButtonMenu();ui.buttonMenu.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(ui.buttonMenu.$el);$("#right .unified-panel-title").append("Bookmarks");$("#right .unified-panel-icons").append("<a id='add-bookmark-button' class='icon-button menu-button plus-button' href='javascript:void(0);' title='Add bookmark'></a>");$("#right-border").click(function(){view.resize_window()});force_right_panel("hide");if(galaxy_config.app.id){this.view_existing()}else{this.view_new()}},view_existing:function(){var g=galaxy_config.app.viz_config;view=ui.create_visualization({container:$("#center .unified-panel-body"),name:g.title,vis_id:g.vis_id,dbkey:g.dbkey},g.viewport,g.tracks,g.bookmarks,true);this.init_editor()},view_new:function(){var g=this;$.ajax({url:galaxy_config.root+"api/genomes?chrom_info=True",data:{},error:function(){alert("Couldn't create new browser.")},success:function(h){Galaxy.modal.show({title:"New Visualization",body:g.template_view_new(h),buttons:{Cancel:function(){window.location=galaxy_config.root+"visualization/list"},Create:function(){g.create_browser($("#new-title").val(),$("#new-dbkey").val());Galaxy.modal.hide()}}});if(galaxy_config.app.default_dbkey){$("#new-dbkey").val(galaxy_config.app.default_dbkey)}$("#new-title").focus();$("select[name='dbkey']").select2();$("#overlay").css("overflow","auto")}})},template_view_new:function(g){var j='<form id="new-browser-form" action="javascript:void(0);" method="post" onsubmit="return false;"><div class="form-row"><label for="new-title">Browser name:</label><div class="form-row-input"><input type="text" name="title" id="new-title" value="Unnamed"></input></div><div style="clear: both;"></div></div><div class="form-row"><label for="new-dbkey">Reference genome build (dbkey): </label><div class="form-row-input"><select name="dbkey" id="new-dbkey">';for(var h=0;h<g.length;h++){j+='<option value="'+g[h][1]+'">'+g[h][0]+"</option>"}j+='</select></div><div style="clear: both;"></div></div><div class="form-row">Is the build not listed here? <a href="'+galaxy_config.root+'user/dbkeys?use_panels=True">Add a Custom Build</a></div></form>';return j},create_browser:function(h,g){$(document).trigger("convert_to_values");view=ui.create_visualization({container:$("#center .unified-panel-body"),name:h,dbkey:g},galaxy_config.app.gene_region);this.init_editor();view.editor=true},init_editor:function(){$("#center .unified-panel-title").text(view.config.get_value("name")+" ("+view.dbkey+")");if(galaxy_config.app.add_dataset){$.ajax({url:galaxy_config.root+"api/datasets/"+galaxy_config.app.add_dataset,data:{hda_ldda:"hda",data_type:"track_config"},dataType:"json",success:function(g){view.add_drawable(a.object_from_template(g,view,view))}})}$("#add-bookmark-button").click(function(){var h=view.chrom+":"+view.low+"-"+view.high,g="Bookmark description";return ui.add_bookmark(h,g,true)});ui.init_keyboard_nav(view);$(window).on("beforeunload",function(){if(view.has_changes){return"There are unsaved changes to your visualization that will be lost if you leave this page."}})}});return{TracksterUI:d,GalaxyApp:f}});
\ No newline at end of file
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -2,8 +2,9 @@
require(
[
'utils/utils',
+ 'mvc/ui/icon-button',
'libs/farbtastic',
-], function(mod_utils)
+], function(mod_utils, mod_icon_btn)
{
// load css
mod_utils.cssLoadFile("static/style/circster.css");
@@ -1075,7 +1076,7 @@
$('#center .unified-panel-header-inner').append(galaxy_config.app.viz_config.title + " " + galaxy_config.app.viz_config.dbkey);
// setup menu
- var menu = create_icon_buttons_menu([
+ var menu = mod_icon_btn.create_icon_buttons_menu([
{
icon_class: 'plus-button', title: 'Add tracks', on_click: function()
{
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/viz/phyloviz.js
--- a/static/scripts/viz/phyloviz.js
+++ b/static/scripts/viz/phyloviz.js
@@ -1,4 +1,9 @@
-define(['libs/d3', 'viz/visualization', 'mvc/data'], function(d3, visualization_mod, data_mod) {
+define([
+ 'libs/d3',
+ 'viz/visualization',
+ 'mvc/data',
+ 'mvc/ui/icon-button'
+], function(d3, visualization_mod, data_mod, mod_icon_btn) {
/**
* Base class of any menus that takes in user interaction. Contains checking methods.
@@ -720,7 +725,7 @@
initRightHeaderBtns : function(){
var self = this;
- rightMenu = create_icon_buttons_menu([
+ rightMenu = mod_icon_btn.create_icon_buttons_menu([
{ icon_class: 'gear', title: 'PhyloViz Settings', on_click: function(){
$("#SettingsMenu").show();
self.settingsMenu.updateUI();
@@ -748,7 +753,7 @@
initNavBtns: function() {
var self = this,
- navMenu = create_icon_buttons_menu([
+ navMenu = mod_icon_btn.create_icon_buttons_menu([
{ icon_class: 'zoom-in', title: 'Zoom in', on_click: function() {
self.phylovizView.zoomAndPan({ zoom : "+"});
} },
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/viz/sweepster.js
--- a/static/scripts/viz/sweepster.js
+++ b/static/scripts/viz/sweepster.js
@@ -3,8 +3,8 @@
* genomic visualization.
*/
-define(["libs/underscore", "libs/d3", "viz/trackster/util", "viz/visualization", "viz/trackster/tracks", "mvc/tools", "mvc/data", "utils/config"],
- function(_, d3, util, visualization, tracks, tools, data, config) {
+define(["libs/underscore", "libs/d3", "viz/trackster/util", "viz/visualization", "viz/trackster/tracks", "mvc/tools", "mvc/data", "utils/config", "mvc/ui/icon-button"],
+ function(_, d3, util, visualization, tracks, tools, data, config, mod_icon_btn) {
/**
* A collection of tool input settings. Object is useful for keeping a list of settings
@@ -375,7 +375,7 @@
settings_div.toggle();
self.trigger('run_on_dataset', settings);
});
- var icon_menu = create_icon_buttons_menu([
+ var icon_menu = mod_icon_btn.create_icon_buttons_menu([
{
title: 'Settings',
icon_class: 'gear track-settings',
@@ -486,7 +486,7 @@
// Add buttons for adding/removing parameter.
var self = this,
- menu = create_icon_buttons_menu([
+ menu = mod_icon_btn.create_icon_buttons_menu([
{
title: 'Add parameter to tree',
icon_class: 'plus-button',
@@ -723,7 +723,7 @@
// Help includes text and a close button.
var help_div = $(this.helpText).addClass('help'),
- close_button = create_icon_buttons_menu([
+ close_button = mod_icon_btn.create_icon_buttons_menu([
{
title: 'Close',
icon_class: 'cross-circle',
@@ -745,7 +745,7 @@
this.handle_node_clicks();
// Set up visualization menu.
- var menu = create_icon_buttons_menu(
+ var menu = mod_icon_btn.create_icon_buttons_menu(
[
// Save.
/*
@@ -939,4 +939,4 @@
SweepsterVisualizationView: SweepsterVisualizationView
};
-});
\ No newline at end of file
+});
diff -r 5b5dde05d21f02afa23cfe1c98396002d907de21 -r 31c50ee295791a8797ff8391986a469778091ee9 static/scripts/viz/trackster.js
--- a/static/scripts/viz/trackster.js
+++ b/static/scripts/viz/trackster.js
@@ -12,6 +12,7 @@
[
// load js libraries
'utils/utils',
+ 'mvc/ui/icon-button',
'libs/jquery/jquery.event.drag',
'libs/jquery/jquery.event.hover',
'libs/jquery/jquery.mousewheel',
@@ -21,7 +22,7 @@
'libs/jquery/jquery.form',
'libs/jquery/jquery.rating',
'mvc/ui'
-], function(mod_utils)
+], function(mod_utils, mod_icon_btn)
{
// load css
mod_utils.cssLoadFile("static/style/jquery.rating.css");
@@ -101,7 +102,7 @@
*/
createButtonMenu: function() {
var self = this,
- menu = create_icon_buttons_menu([
+ menu = mod_icon_btn.create_icon_buttons_menu([
{ icon_class: 'plus-button', title: 'Add tracks', on_click: function() {
visualization.select_datasets(galaxy_config.root + "visualization/list_current_history_datasets", galaxy_config.root + "api/datasets", { 'f-dbkey': view.dbkey },
function(new_tracks) {
@@ -571,4 +572,4 @@
GalaxyApp : TracksterView
};
-});
\ No newline at end of file
+});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: modularize popup menu from ui.js
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5b5dde05d21f/
Changeset: 5b5dde05d21f
User: carlfeberhard
Date: 2014-12-09 18:06:41+00:00
Summary: Client build: modularize popup menu from ui.js
Affected #: 15 files
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 client/galaxy/scripts/mvc/grid/grid-view.js
--- a/client/galaxy/scripts/mvc/grid/grid-view.js
+++ b/client/galaxy/scripts/mvc/grid/grid-view.js
@@ -3,7 +3,11 @@
jQuery.ajaxSettings.traditional = true;
// dependencies
-define(['mvc/grid/grid-model', 'mvc/grid/grid-template', 'mvc/ui'], function(GridModel, Templates) {
+define([
+ 'mvc/grid/grid-model',
+ 'mvc/grid/grid-template',
+ "mvc/ui/popup-menu"
+], function(GridModel, Templates, PopupMenu) {
// grid view
return Backbone.View.extend({
@@ -661,4 +665,4 @@
}
});
-});
\ No newline at end of file
+});
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 client/galaxy/scripts/mvc/history/history-panel-edit.js
--- a/client/galaxy/scripts/mvc/history/history-panel-edit.js
+++ b/client/galaxy/scripts/mvc/history/history-panel-edit.js
@@ -8,6 +8,7 @@
"mvc/tags",
"mvc/annotations",
"jq-plugins/ui/fa-icon-button",
+ "mvc/ui/popup-menu",
"utils/localization"
], function(
HPANEL,
@@ -19,6 +20,7 @@
TAGS,
ANNOTATIONS,
faIconButton,
+ PopupMenu,
_l
){
/* =============================================================================
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 client/galaxy/scripts/mvc/history/options-menu.js
--- a/client/galaxy/scripts/mvc/history/options-menu.js
+++ b/client/galaxy/scripts/mvc/history/options-menu.js
@@ -1,7 +1,8 @@
define([
+ "mvc/ui/popup-menu",
"mvc/base-mvc",
"utils/localization"
-], function( BASE_MVC, _l ){
+], function( PopupMenu, BASE_MVC, _l ){
// ============================================================================
var menu = [
{
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 client/galaxy/scripts/mvc/ui.js
--- a/client/galaxy/scripts/mvc/ui.js
+++ b/client/galaxy/scripts/mvc/ui.js
@@ -169,320 +169,3 @@
// return menu
return new IconButtonMenuView( {collection: buttons} );
};
-
-// =============================================================================
-/**
- *
- */
-var Grid = Backbone.Collection.extend({
-
-});
-
-/**
- *
- */
-var GridView = Backbone.View.extend({
-
-});
-
-// =============================================================================
-/**
- * view for a popup menu
- */
-var PopupMenu = Backbone.View.extend({
-//TODO: maybe better as singleton off the Galaxy obj
- /** Cache the desired button element and options, set up the button click handler
- * NOTE: attaches this view as HTML/jQ data on the button for later use.
- */
- initialize: function( $button, options ){
- // default settings
- this.$button = $button;
- if( !this.$button.size() ){
- this.$button = $( '<div/>' );
- }
- this.options = options || [];
-
- // set up button click -> open menu behavior
- var menu = this;
- this.$button.click( function( event ){
- // if there's already a menu open, remove it
- $( '.popmenu-wrapper' ).remove();
- menu._renderAndShow( event );
- return false;
- });
- },
-
- // render the menu, append to the page body at the click position, and set up the 'click-away' handlers, show
- _renderAndShow: function( clickEvent ){
- this.render();
- this.$el.appendTo( 'body' ).css( this._getShownPosition( clickEvent )).show();
- this._setUpCloseBehavior();
- },
-
- // render the menu
- // this menu doesn't attach itself to the DOM ( see _renderAndShow )
- render: function(){
- // render the menu body absolute and hidden, fill with template
- this.$el.addClass( 'popmenu-wrapper' ).hide()
- .css({ position : 'absolute' })
- .html( this.template( this.$button.attr( 'id' ), this.options ));
-
- // set up behavior on each link/anchor elem
- if( this.options.length ){
- var menu = this;
- //precondition: there should be one option per li
- this.$el.find( 'li' ).each( function( i, li ){
- var option = menu.options[i];
-
- // if the option has 'func', call that function when the anchor is clicked
- if( option.func ){
- $( this ).children( 'a.popupmenu-option' ).click( function( event ){
- option.func.call( menu, event, option );
- // bubble up so that an option click will call the close behavior
- //return false;
- });
- }
- });
- }
- return this;
- },
-
- template : function( id, options ){
- return [
- '<ul id="', id, '-menu" class="dropdown-menu">', this._templateOptions( options ), '</ul>'
- ].join( '' );
- },
-
- _templateOptions : function( options ){
- if( !options.length ){
- return '<li>(no options)</li>';
- }
- return _.map( options, function( option ){
- if( option.divider ){
- return '<li class="divider"></li>';
- } else if( option.header ){
- return [ '<li class="head"><a href="javascript:void(0);">', option.html, '</a></li>' ].join( '' );
- }
- var href = option.href || 'javascript:void(0);',
- target = ( option.target )?( ' target="' + option.target + '"' ):( '' ),
- check = ( option.checked )?( '<span class="fa fa-check"></span>' ):( '' );
- return [
- '<li><a class="popupmenu-option" href="', href, '"', target, '>',
- check, option.html,
- '</a></li>'
- ].join( '' );
- }).join( '' );
- },
-
- // get the absolute position/offset for the menu
- _getShownPosition : function( clickEvent ){
-
- // display menu horiz. centered on click...
- var menuWidth = this.$el.width();
- var x = clickEvent.pageX - menuWidth / 2 ;
-
- // adjust to handle horiz. scroll and window dimensions ( draw entirely on visible screen area )
- x = Math.min( x, $( document ).scrollLeft() + $( window ).width() - menuWidth - 5 );
- x = Math.max( x, $( document ).scrollLeft() + 5 );
- return {
- top: clickEvent.pageY,
- left: x
- };
- },
-
- // bind an event handler to all available frames so that when anything is clicked
- // the menu is removed from the DOM and the event handler unbinds itself
- _setUpCloseBehavior: function(){
- var menu = this;
-//TODO: alternately: focus hack, blocking overlay, jquery.blockui
-
- // function to close popup and unbind itself
- function closePopup( event ){
- $( document ).off( 'click.close_popup' );
- if( window.parent !== window ){
- try {
- $( window.parent.document ).off( "click.close_popup" );
- } catch( err ){}
- } else {
- try {
- $( 'iframe#galaxy_main' ).contents().off( "click.close_popup" );
- } catch( err ){}
- }
- menu.remove();
- }
-
- $( 'html' ).one( "click.close_popup", closePopup );
- if( window.parent !== window ){
- try {
- $( window.parent.document ).find( 'html' ).one( "click.close_popup", closePopup );
- } catch( err ){}
- } else {
- try {
- $( 'iframe#galaxy_main' ).contents().one( "click.close_popup", closePopup );
- } catch( err ){}
- }
- },
-
- // add a menu option/item at the given index
- addItem: function( item, index ){
- // append to end if no index
- index = ( index >= 0 ) ? index : this.options.length;
- this.options.splice( index, 0, item );
- return this;
- },
-
- // remove a menu option/item at the given index
- removeItem: function( index ){
- if( index >=0 ){
- this.options.splice( index, 1 );
- }
- return this;
- },
-
- // search for a menu option by its html
- findIndexByHtml: function( html ){
- for( var i = 0; i < this.options.length; i++ ){
- if( _.has( this.options[i], 'html' ) && ( this.options[i].html === html )){
- return i;
- }
- }
- return null;
- },
-
- // search for a menu option by its html
- findItemByHtml: function( html ){
- return this.options[( this.findIndexByHtml( html ))];
- },
-
- // string representation
- toString: function(){
- return 'PopupMenu';
- }
-});
-/** shortcut to new for when you don't need to preserve the ref */
-PopupMenu.create = function _create( $button, options ){
- return new PopupMenu( $button, options );
-};
-
-// -----------------------------------------------------------------------------
-// the following class functions are bridges from the original make_popupmenu and make_popup_menus
-// to the newer backbone.js PopupMenu
-
-/** Create a PopupMenu from simple map initial_options activated by clicking button_element.
- * Converts initial_options to object array used by PopupMenu.
- * @param {jQuery|DOMElement} button_element element which, when clicked, activates menu
- * @param {Object} initial_options map of key -> values, where
- * key is option text, value is fn to call when option is clicked
- * @returns {PopupMenu} the PopupMenu created
- */
-PopupMenu.make_popupmenu = function( button_element, initial_options ){
- var convertedOptions = [];
- _.each( initial_options, function( optionVal, optionKey ){
- var newOption = { html: optionKey };
-
- // keys with null values indicate: header
- if( optionVal === null ){ // !optionVal? (null only?)
- newOption.header = true;
-
- // keys with function values indicate: a menu option
- } else if( jQuery.type( optionVal ) === 'function' ){
- newOption.func = optionVal;
- }
- //TODO:?? any other special optionVals?
- // there was no divider option originally
- convertedOptions.push( newOption );
- });
- return new PopupMenu( $( button_element ), convertedOptions );
-};
-
-/** Find all anchors in $parent (using selector) and covert anchors into a PopupMenu options map.
- * @param {jQuery} $parent the element that contains the links to convert to options
- * @param {String} selector jq selector string to find links
- * @returns {Object[]} the options array to initialize a PopupMenu
- */
-//TODO: lose parent and selector, pass in array of links, use map to return options
-PopupMenu.convertLinksToOptions = function( $parent, selector ){
- $parent = $( $parent );
- selector = selector || 'a';
- var options = [];
- $parent.find( selector ).each( function( elem, i ){
- var option = {}, $link = $( elem );
-
- // convert link text to the option text (html) and the href into the option func
- option.html = $link.text();
- if( $link.attr( 'href' ) ){
- var linkHref = $link.attr( 'href' ),
- linkTarget = $link.attr( 'target' ),
- confirmText = $link.attr( 'confirm' );
-
- option.func = function(){
- // if there's a "confirm" attribute, throw up a confirmation dialog, and
- // if the user cancels - do nothing
- if( ( confirmText ) && ( !confirm( confirmText ) ) ){ return; }
-
- // if there's no confirm attribute, or the user accepted the confirm dialog:
- switch( linkTarget ){
- // relocate the center panel
- case '_parent':
- window.parent.location = linkHref;
- break;
-
- // relocate the entire window
- case '_top':
- window.top.location = linkHref;
- break;
-
- // relocate this panel
- default:
- window.location = linkHref;
- }
- };
- }
- options.push( option );
- });
- return options;
-};
-
-/** Create a single popupmenu from existing DOM button and anchor elements
- * @param {jQuery} $buttonElement the element that when clicked will open the menu
- * @param {jQuery} $menuElement the element that contains the anchors to convert into a menu
- * @param {String} menuElementLinkSelector jq selector string used to find anchors to be made into menu options
- * @returns {PopupMenu} the PopupMenu (Backbone View) that can render, control the menu
- */
-PopupMenu.fromExistingDom = function( $buttonElement, $menuElement, menuElementLinkSelector ){
- $buttonElement = $( $buttonElement );
- $menuElement = $( $menuElement );
- var options = PopupMenu.convertLinksToOptions( $menuElement, menuElementLinkSelector );
- // we're done with the menu (having converted it to an options map)
- $menuElement.remove();
- return new PopupMenu( $buttonElement, options );
-};
-
-/** Create all popupmenus within a document or a more specific element
- * @param {DOMElement} parent the DOM element in which to search for popupmenus to build (defaults to document)
- * @param {String} menuSelector jq selector string to find popupmenu menu elements (defaults to "div[popupmenu]")
- * @param {Function} buttonSelectorBuildFn the function to build the jq button selector.
- * Will be passed $menuElement, parent.
- * (Defaults to return '#' + $menuElement.attr( 'popupmenu' ); )
- * @returns {PopupMenu[]} array of popupmenus created
- */
-PopupMenu.make_popup_menus = function( parent, menuSelector, buttonSelectorBuildFn ){
- parent = parent || document;
- // orig. Glx popupmenu menus have a (non-std) attribute 'popupmenu'
- // which contains the id of the button that activates the menu
- menuSelector = menuSelector || 'div[popupmenu]';
- // default to (orig. Glx) matching button to menu by using the popupmenu attr of the menu as the id of the button
- buttonSelectorBuildFn = buttonSelectorBuildFn || function( $menuElement, parent ){
- return '#' + $menuElement.attr( 'popupmenu' );
- };
-
- // aggregate and return all PopupMenus
- var popupMenusCreated = [];
- $( parent ).find( menuSelector ).each( function(){
- var $menuElement = $( this ),
- $buttonElement = $( parent ).find( buttonSelectorBuildFn( $menuElement, parent ) );
- popupMenusCreated.push( PopupMenu.fromDom( $buttonElement, $menuElement ) );
- $buttonElement.addClass( 'popup' );
- });
- return popupMenusCreated;
-};
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 client/galaxy/scripts/mvc/ui/popup-menu.js
--- /dev/null
+++ b/client/galaxy/scripts/mvc/ui/popup-menu.js
@@ -0,0 +1,311 @@
+define([
+ //jquery
+ //backbone
+], function(){
+// =============================================================================
+/**
+ * view for a popup menu
+ */
+var PopupMenu = Backbone.View.extend({
+//TODO: maybe better as singleton off the Galaxy obj
+ /** Cache the desired button element and options, set up the button click handler
+ * NOTE: attaches this view as HTML/jQ data on the button for later use.
+ */
+ initialize: function( $button, options ){
+ // default settings
+ this.$button = $button;
+ if( !this.$button.size() ){
+ this.$button = $( '<div/>' );
+ }
+ this.options = options || [];
+
+ // set up button click -> open menu behavior
+ var menu = this;
+ this.$button.click( function( event ){
+ // if there's already a menu open, remove it
+ $( '.popmenu-wrapper' ).remove();
+ menu._renderAndShow( event );
+ return false;
+ });
+ },
+
+ // render the menu, append to the page body at the click position, and set up the 'click-away' handlers, show
+ _renderAndShow: function( clickEvent ){
+ this.render();
+ this.$el.appendTo( 'body' ).css( this._getShownPosition( clickEvent )).show();
+ this._setUpCloseBehavior();
+ },
+
+ // render the menu
+ // this menu doesn't attach itself to the DOM ( see _renderAndShow )
+ render: function(){
+ // render the menu body absolute and hidden, fill with template
+ this.$el.addClass( 'popmenu-wrapper' ).hide()
+ .css({ position : 'absolute' })
+ .html( this.template( this.$button.attr( 'id' ), this.options ));
+
+ // set up behavior on each link/anchor elem
+ if( this.options.length ){
+ var menu = this;
+ //precondition: there should be one option per li
+ this.$el.find( 'li' ).each( function( i, li ){
+ var option = menu.options[i];
+
+ // if the option has 'func', call that function when the anchor is clicked
+ if( option.func ){
+ $( this ).children( 'a.popupmenu-option' ).click( function( event ){
+ option.func.call( menu, event, option );
+ // bubble up so that an option click will call the close behavior
+ //return false;
+ });
+ }
+ });
+ }
+ return this;
+ },
+
+ template : function( id, options ){
+ return [
+ '<ul id="', id, '-menu" class="dropdown-menu">', this._templateOptions( options ), '</ul>'
+ ].join( '' );
+ },
+
+ _templateOptions : function( options ){
+ if( !options.length ){
+ return '<li>(no options)</li>';
+ }
+ return _.map( options, function( option ){
+ if( option.divider ){
+ return '<li class="divider"></li>';
+ } else if( option.header ){
+ return [ '<li class="head"><a href="javascript:void(0);">', option.html, '</a></li>' ].join( '' );
+ }
+ var href = option.href || 'javascript:void(0);',
+ target = ( option.target )?( ' target="' + option.target + '"' ):( '' ),
+ check = ( option.checked )?( '<span class="fa fa-check"></span>' ):( '' );
+ return [
+ '<li><a class="popupmenu-option" href="', href, '"', target, '>',
+ check, option.html,
+ '</a></li>'
+ ].join( '' );
+ }).join( '' );
+ },
+
+ // get the absolute position/offset for the menu
+ _getShownPosition : function( clickEvent ){
+
+ // display menu horiz. centered on click...
+ var menuWidth = this.$el.width();
+ var x = clickEvent.pageX - menuWidth / 2 ;
+
+ // adjust to handle horiz. scroll and window dimensions ( draw entirely on visible screen area )
+ x = Math.min( x, $( document ).scrollLeft() + $( window ).width() - menuWidth - 5 );
+ x = Math.max( x, $( document ).scrollLeft() + 5 );
+ return {
+ top: clickEvent.pageY,
+ left: x
+ };
+ },
+
+ // bind an event handler to all available frames so that when anything is clicked
+ // the menu is removed from the DOM and the event handler unbinds itself
+ _setUpCloseBehavior: function(){
+ var menu = this;
+//TODO: alternately: focus hack, blocking overlay, jquery.blockui
+
+ // function to close popup and unbind itself
+ function closePopup( event ){
+ $( document ).off( 'click.close_popup' );
+ if( window.parent !== window ){
+ try {
+ $( window.parent.document ).off( "click.close_popup" );
+ } catch( err ){}
+ } else {
+ try {
+ $( 'iframe#galaxy_main' ).contents().off( "click.close_popup" );
+ } catch( err ){}
+ }
+ menu.remove();
+ }
+
+ $( 'html' ).one( "click.close_popup", closePopup );
+ if( window.parent !== window ){
+ try {
+ $( window.parent.document ).find( 'html' ).one( "click.close_popup", closePopup );
+ } catch( err ){}
+ } else {
+ try {
+ $( 'iframe#galaxy_main' ).contents().one( "click.close_popup", closePopup );
+ } catch( err ){}
+ }
+ },
+
+ // add a menu option/item at the given index
+ addItem: function( item, index ){
+ // append to end if no index
+ index = ( index >= 0 ) ? index : this.options.length;
+ this.options.splice( index, 0, item );
+ return this;
+ },
+
+ // remove a menu option/item at the given index
+ removeItem: function( index ){
+ if( index >=0 ){
+ this.options.splice( index, 1 );
+ }
+ return this;
+ },
+
+ // search for a menu option by its html
+ findIndexByHtml: function( html ){
+ for( var i = 0; i < this.options.length; i++ ){
+ if( _.has( this.options[i], 'html' ) && ( this.options[i].html === html )){
+ return i;
+ }
+ }
+ return null;
+ },
+
+ // search for a menu option by its html
+ findItemByHtml: function( html ){
+ return this.options[( this.findIndexByHtml( html ))];
+ },
+
+ // string representation
+ toString: function(){
+ return 'PopupMenu';
+ }
+});
+/** shortcut to new for when you don't need to preserve the ref */
+PopupMenu.create = function _create( $button, options ){
+ return new PopupMenu( $button, options );
+};
+
+// -----------------------------------------------------------------------------
+// the following class functions are bridges from the original make_popupmenu and make_popup_menus
+// to the newer backbone.js PopupMenu
+
+/** Create a PopupMenu from simple map initial_options activated by clicking button_element.
+ * Converts initial_options to object array used by PopupMenu.
+ * @param {jQuery|DOMElement} button_element element which, when clicked, activates menu
+ * @param {Object} initial_options map of key -> values, where
+ * key is option text, value is fn to call when option is clicked
+ * @returns {PopupMenu} the PopupMenu created
+ */
+PopupMenu.make_popupmenu = function( button_element, initial_options ){
+ var convertedOptions = [];
+ _.each( initial_options, function( optionVal, optionKey ){
+ var newOption = { html: optionKey };
+
+ // keys with null values indicate: header
+ if( optionVal === null ){ // !optionVal? (null only?)
+ newOption.header = true;
+
+ // keys with function values indicate: a menu option
+ } else if( jQuery.type( optionVal ) === 'function' ){
+ newOption.func = optionVal;
+ }
+ //TODO:?? any other special optionVals?
+ // there was no divider option originally
+ convertedOptions.push( newOption );
+ });
+ return new PopupMenu( $( button_element ), convertedOptions );
+};
+
+/** Find all anchors in $parent (using selector) and covert anchors into a PopupMenu options map.
+ * @param {jQuery} $parent the element that contains the links to convert to options
+ * @param {String} selector jq selector string to find links
+ * @returns {Object[]} the options array to initialize a PopupMenu
+ */
+//TODO: lose parent and selector, pass in array of links, use map to return options
+PopupMenu.convertLinksToOptions = function( $parent, selector ){
+ $parent = $( $parent );
+ selector = selector || 'a';
+ var options = [];
+ $parent.find( selector ).each( function( elem, i ){
+ var option = {}, $link = $( elem );
+
+ // convert link text to the option text (html) and the href into the option func
+ option.html = $link.text();
+ if( $link.attr( 'href' ) ){
+ var linkHref = $link.attr( 'href' ),
+ linkTarget = $link.attr( 'target' ),
+ confirmText = $link.attr( 'confirm' );
+
+ option.func = function(){
+ // if there's a "confirm" attribute, throw up a confirmation dialog, and
+ // if the user cancels - do nothing
+ if( ( confirmText ) && ( !confirm( confirmText ) ) ){ return; }
+
+ // if there's no confirm attribute, or the user accepted the confirm dialog:
+ switch( linkTarget ){
+ // relocate the center panel
+ case '_parent':
+ window.parent.location = linkHref;
+ break;
+
+ // relocate the entire window
+ case '_top':
+ window.top.location = linkHref;
+ break;
+
+ // relocate this panel
+ default:
+ window.location = linkHref;
+ }
+ };
+ }
+ options.push( option );
+ });
+ return options;
+};
+
+/** Create a single popupmenu from existing DOM button and anchor elements
+ * @param {jQuery} $buttonElement the element that when clicked will open the menu
+ * @param {jQuery} $menuElement the element that contains the anchors to convert into a menu
+ * @param {String} menuElementLinkSelector jq selector string used to find anchors to be made into menu options
+ * @returns {PopupMenu} the PopupMenu (Backbone View) that can render, control the menu
+ */
+PopupMenu.fromExistingDom = function( $buttonElement, $menuElement, menuElementLinkSelector ){
+ $buttonElement = $( $buttonElement );
+ $menuElement = $( $menuElement );
+ var options = PopupMenu.convertLinksToOptions( $menuElement, menuElementLinkSelector );
+ // we're done with the menu (having converted it to an options map)
+ $menuElement.remove();
+ return new PopupMenu( $buttonElement, options );
+};
+
+/** Create all popupmenus within a document or a more specific element
+ * @param {DOMElement} parent the DOM element in which to search for popupmenus to build (defaults to document)
+ * @param {String} menuSelector jq selector string to find popupmenu menu elements (defaults to "div[popupmenu]")
+ * @param {Function} buttonSelectorBuildFn the function to build the jq button selector.
+ * Will be passed $menuElement, parent.
+ * (Defaults to return '#' + $menuElement.attr( 'popupmenu' ); )
+ * @returns {PopupMenu[]} array of popupmenus created
+ */
+PopupMenu.make_popup_menus = function( parent, menuSelector, buttonSelectorBuildFn ){
+ parent = parent || document;
+ // orig. Glx popupmenu menus have a (non-std) attribute 'popupmenu'
+ // which contains the id of the button that activates the menu
+ menuSelector = menuSelector || 'div[popupmenu]';
+ // default to (orig. Glx) matching button to menu by using the popupmenu attr of the menu as the id of the button
+ buttonSelectorBuildFn = buttonSelectorBuildFn || function( $menuElement, parent ){
+ return '#' + $menuElement.attr( 'popupmenu' );
+ };
+
+ // aggregate and return all PopupMenus
+ var popupMenusCreated = [];
+ $( parent ).find( menuSelector ).each( function(){
+ var $menuElement = $( this ),
+ $buttonElement = $( parent ).find( buttonSelectorBuildFn( $menuElement, parent ) );
+ popupMenusCreated.push( PopupMenu.fromDom( $buttonElement, $menuElement ) );
+ $buttonElement.addClass( 'popup' );
+ });
+ return popupMenusCreated;
+};
+
+
+// =============================================================================
+ return PopupMenu;
+});
+
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/mvc/grid/grid-view.js
--- a/static/scripts/mvc/grid/grid-view.js
+++ b/static/scripts/mvc/grid/grid-view.js
@@ -3,7 +3,11 @@
jQuery.ajaxSettings.traditional = true;
// dependencies
-define(['mvc/grid/grid-model', 'mvc/grid/grid-template', 'mvc/ui'], function(GridModel, Templates) {
+define([
+ 'mvc/grid/grid-model',
+ 'mvc/grid/grid-template',
+ "mvc/ui/popup-menu"
+], function(GridModel, Templates, PopupMenu) {
// grid view
return Backbone.View.extend({
@@ -661,4 +665,4 @@
}
});
-});
\ No newline at end of file
+});
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/mvc/history/history-panel-edit.js
--- a/static/scripts/mvc/history/history-panel-edit.js
+++ b/static/scripts/mvc/history/history-panel-edit.js
@@ -8,6 +8,7 @@
"mvc/tags",
"mvc/annotations",
"jq-plugins/ui/fa-icon-button",
+ "mvc/ui/popup-menu",
"utils/localization"
], function(
HPANEL,
@@ -19,6 +20,7 @@
TAGS,
ANNOTATIONS,
faIconButton,
+ PopupMenu,
_l
){
/* =============================================================================
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/mvc/history/options-menu.js
--- a/static/scripts/mvc/history/options-menu.js
+++ b/static/scripts/mvc/history/options-menu.js
@@ -1,7 +1,8 @@
define([
+ "mvc/ui/popup-menu",
"mvc/base-mvc",
"utils/localization"
-], function( BASE_MVC, _l ){
+], function( PopupMenu, BASE_MVC, _l ){
// ============================================================================
var menu = [
{
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -169,320 +169,3 @@
// return menu
return new IconButtonMenuView( {collection: buttons} );
};
-
-// =============================================================================
-/**
- *
- */
-var Grid = Backbone.Collection.extend({
-
-});
-
-/**
- *
- */
-var GridView = Backbone.View.extend({
-
-});
-
-// =============================================================================
-/**
- * view for a popup menu
- */
-var PopupMenu = Backbone.View.extend({
-//TODO: maybe better as singleton off the Galaxy obj
- /** Cache the desired button element and options, set up the button click handler
- * NOTE: attaches this view as HTML/jQ data on the button for later use.
- */
- initialize: function( $button, options ){
- // default settings
- this.$button = $button;
- if( !this.$button.size() ){
- this.$button = $( '<div/>' );
- }
- this.options = options || [];
-
- // set up button click -> open menu behavior
- var menu = this;
- this.$button.click( function( event ){
- // if there's already a menu open, remove it
- $( '.popmenu-wrapper' ).remove();
- menu._renderAndShow( event );
- return false;
- });
- },
-
- // render the menu, append to the page body at the click position, and set up the 'click-away' handlers, show
- _renderAndShow: function( clickEvent ){
- this.render();
- this.$el.appendTo( 'body' ).css( this._getShownPosition( clickEvent )).show();
- this._setUpCloseBehavior();
- },
-
- // render the menu
- // this menu doesn't attach itself to the DOM ( see _renderAndShow )
- render: function(){
- // render the menu body absolute and hidden, fill with template
- this.$el.addClass( 'popmenu-wrapper' ).hide()
- .css({ position : 'absolute' })
- .html( this.template( this.$button.attr( 'id' ), this.options ));
-
- // set up behavior on each link/anchor elem
- if( this.options.length ){
- var menu = this;
- //precondition: there should be one option per li
- this.$el.find( 'li' ).each( function( i, li ){
- var option = menu.options[i];
-
- // if the option has 'func', call that function when the anchor is clicked
- if( option.func ){
- $( this ).children( 'a.popupmenu-option' ).click( function( event ){
- option.func.call( menu, event, option );
- // bubble up so that an option click will call the close behavior
- //return false;
- });
- }
- });
- }
- return this;
- },
-
- template : function( id, options ){
- return [
- '<ul id="', id, '-menu" class="dropdown-menu">', this._templateOptions( options ), '</ul>'
- ].join( '' );
- },
-
- _templateOptions : function( options ){
- if( !options.length ){
- return '<li>(no options)</li>';
- }
- return _.map( options, function( option ){
- if( option.divider ){
- return '<li class="divider"></li>';
- } else if( option.header ){
- return [ '<li class="head"><a href="javascript:void(0);">', option.html, '</a></li>' ].join( '' );
- }
- var href = option.href || 'javascript:void(0);',
- target = ( option.target )?( ' target="' + option.target + '"' ):( '' ),
- check = ( option.checked )?( '<span class="fa fa-check"></span>' ):( '' );
- return [
- '<li><a class="popupmenu-option" href="', href, '"', target, '>',
- check, option.html,
- '</a></li>'
- ].join( '' );
- }).join( '' );
- },
-
- // get the absolute position/offset for the menu
- _getShownPosition : function( clickEvent ){
-
- // display menu horiz. centered on click...
- var menuWidth = this.$el.width();
- var x = clickEvent.pageX - menuWidth / 2 ;
-
- // adjust to handle horiz. scroll and window dimensions ( draw entirely on visible screen area )
- x = Math.min( x, $( document ).scrollLeft() + $( window ).width() - menuWidth - 5 );
- x = Math.max( x, $( document ).scrollLeft() + 5 );
- return {
- top: clickEvent.pageY,
- left: x
- };
- },
-
- // bind an event handler to all available frames so that when anything is clicked
- // the menu is removed from the DOM and the event handler unbinds itself
- _setUpCloseBehavior: function(){
- var menu = this;
-//TODO: alternately: focus hack, blocking overlay, jquery.blockui
-
- // function to close popup and unbind itself
- function closePopup( event ){
- $( document ).off( 'click.close_popup' );
- if( window.parent !== window ){
- try {
- $( window.parent.document ).off( "click.close_popup" );
- } catch( err ){}
- } else {
- try {
- $( 'iframe#galaxy_main' ).contents().off( "click.close_popup" );
- } catch( err ){}
- }
- menu.remove();
- }
-
- $( 'html' ).one( "click.close_popup", closePopup );
- if( window.parent !== window ){
- try {
- $( window.parent.document ).find( 'html' ).one( "click.close_popup", closePopup );
- } catch( err ){}
- } else {
- try {
- $( 'iframe#galaxy_main' ).contents().one( "click.close_popup", closePopup );
- } catch( err ){}
- }
- },
-
- // add a menu option/item at the given index
- addItem: function( item, index ){
- // append to end if no index
- index = ( index >= 0 ) ? index : this.options.length;
- this.options.splice( index, 0, item );
- return this;
- },
-
- // remove a menu option/item at the given index
- removeItem: function( index ){
- if( index >=0 ){
- this.options.splice( index, 1 );
- }
- return this;
- },
-
- // search for a menu option by its html
- findIndexByHtml: function( html ){
- for( var i = 0; i < this.options.length; i++ ){
- if( _.has( this.options[i], 'html' ) && ( this.options[i].html === html )){
- return i;
- }
- }
- return null;
- },
-
- // search for a menu option by its html
- findItemByHtml: function( html ){
- return this.options[( this.findIndexByHtml( html ))];
- },
-
- // string representation
- toString: function(){
- return 'PopupMenu';
- }
-});
-/** shortcut to new for when you don't need to preserve the ref */
-PopupMenu.create = function _create( $button, options ){
- return new PopupMenu( $button, options );
-};
-
-// -----------------------------------------------------------------------------
-// the following class functions are bridges from the original make_popupmenu and make_popup_menus
-// to the newer backbone.js PopupMenu
-
-/** Create a PopupMenu from simple map initial_options activated by clicking button_element.
- * Converts initial_options to object array used by PopupMenu.
- * @param {jQuery|DOMElement} button_element element which, when clicked, activates menu
- * @param {Object} initial_options map of key -> values, where
- * key is option text, value is fn to call when option is clicked
- * @returns {PopupMenu} the PopupMenu created
- */
-PopupMenu.make_popupmenu = function( button_element, initial_options ){
- var convertedOptions = [];
- _.each( initial_options, function( optionVal, optionKey ){
- var newOption = { html: optionKey };
-
- // keys with null values indicate: header
- if( optionVal === null ){ // !optionVal? (null only?)
- newOption.header = true;
-
- // keys with function values indicate: a menu option
- } else if( jQuery.type( optionVal ) === 'function' ){
- newOption.func = optionVal;
- }
- //TODO:?? any other special optionVals?
- // there was no divider option originally
- convertedOptions.push( newOption );
- });
- return new PopupMenu( $( button_element ), convertedOptions );
-};
-
-/** Find all anchors in $parent (using selector) and covert anchors into a PopupMenu options map.
- * @param {jQuery} $parent the element that contains the links to convert to options
- * @param {String} selector jq selector string to find links
- * @returns {Object[]} the options array to initialize a PopupMenu
- */
-//TODO: lose parent and selector, pass in array of links, use map to return options
-PopupMenu.convertLinksToOptions = function( $parent, selector ){
- $parent = $( $parent );
- selector = selector || 'a';
- var options = [];
- $parent.find( selector ).each( function( elem, i ){
- var option = {}, $link = $( elem );
-
- // convert link text to the option text (html) and the href into the option func
- option.html = $link.text();
- if( $link.attr( 'href' ) ){
- var linkHref = $link.attr( 'href' ),
- linkTarget = $link.attr( 'target' ),
- confirmText = $link.attr( 'confirm' );
-
- option.func = function(){
- // if there's a "confirm" attribute, throw up a confirmation dialog, and
- // if the user cancels - do nothing
- if( ( confirmText ) && ( !confirm( confirmText ) ) ){ return; }
-
- // if there's no confirm attribute, or the user accepted the confirm dialog:
- switch( linkTarget ){
- // relocate the center panel
- case '_parent':
- window.parent.location = linkHref;
- break;
-
- // relocate the entire window
- case '_top':
- window.top.location = linkHref;
- break;
-
- // relocate this panel
- default:
- window.location = linkHref;
- }
- };
- }
- options.push( option );
- });
- return options;
-};
-
-/** Create a single popupmenu from existing DOM button and anchor elements
- * @param {jQuery} $buttonElement the element that when clicked will open the menu
- * @param {jQuery} $menuElement the element that contains the anchors to convert into a menu
- * @param {String} menuElementLinkSelector jq selector string used to find anchors to be made into menu options
- * @returns {PopupMenu} the PopupMenu (Backbone View) that can render, control the menu
- */
-PopupMenu.fromExistingDom = function( $buttonElement, $menuElement, menuElementLinkSelector ){
- $buttonElement = $( $buttonElement );
- $menuElement = $( $menuElement );
- var options = PopupMenu.convertLinksToOptions( $menuElement, menuElementLinkSelector );
- // we're done with the menu (having converted it to an options map)
- $menuElement.remove();
- return new PopupMenu( $buttonElement, options );
-};
-
-/** Create all popupmenus within a document or a more specific element
- * @param {DOMElement} parent the DOM element in which to search for popupmenus to build (defaults to document)
- * @param {String} menuSelector jq selector string to find popupmenu menu elements (defaults to "div[popupmenu]")
- * @param {Function} buttonSelectorBuildFn the function to build the jq button selector.
- * Will be passed $menuElement, parent.
- * (Defaults to return '#' + $menuElement.attr( 'popupmenu' ); )
- * @returns {PopupMenu[]} array of popupmenus created
- */
-PopupMenu.make_popup_menus = function( parent, menuSelector, buttonSelectorBuildFn ){
- parent = parent || document;
- // orig. Glx popupmenu menus have a (non-std) attribute 'popupmenu'
- // which contains the id of the button that activates the menu
- menuSelector = menuSelector || 'div[popupmenu]';
- // default to (orig. Glx) matching button to menu by using the popupmenu attr of the menu as the id of the button
- buttonSelectorBuildFn = buttonSelectorBuildFn || function( $menuElement, parent ){
- return '#' + $menuElement.attr( 'popupmenu' );
- };
-
- // aggregate and return all PopupMenus
- var popupMenusCreated = [];
- $( parent ).find( menuSelector ).each( function(){
- var $menuElement = $( this ),
- $buttonElement = $( parent ).find( buttonSelectorBuildFn( $menuElement, parent ) );
- popupMenusCreated.push( PopupMenu.fromDom( $buttonElement, $menuElement ) );
- $buttonElement.addClass( 'popup' );
- });
- return popupMenusCreated;
-};
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/mvc/ui/popup-menu.js
--- /dev/null
+++ b/static/scripts/mvc/ui/popup-menu.js
@@ -0,0 +1,311 @@
+define([
+ //jquery
+ //backbone
+], function(){
+// =============================================================================
+/**
+ * view for a popup menu
+ */
+var PopupMenu = Backbone.View.extend({
+//TODO: maybe better as singleton off the Galaxy obj
+ /** Cache the desired button element and options, set up the button click handler
+ * NOTE: attaches this view as HTML/jQ data on the button for later use.
+ */
+ initialize: function( $button, options ){
+ // default settings
+ this.$button = $button;
+ if( !this.$button.size() ){
+ this.$button = $( '<div/>' );
+ }
+ this.options = options || [];
+
+ // set up button click -> open menu behavior
+ var menu = this;
+ this.$button.click( function( event ){
+ // if there's already a menu open, remove it
+ $( '.popmenu-wrapper' ).remove();
+ menu._renderAndShow( event );
+ return false;
+ });
+ },
+
+ // render the menu, append to the page body at the click position, and set up the 'click-away' handlers, show
+ _renderAndShow: function( clickEvent ){
+ this.render();
+ this.$el.appendTo( 'body' ).css( this._getShownPosition( clickEvent )).show();
+ this._setUpCloseBehavior();
+ },
+
+ // render the menu
+ // this menu doesn't attach itself to the DOM ( see _renderAndShow )
+ render: function(){
+ // render the menu body absolute and hidden, fill with template
+ this.$el.addClass( 'popmenu-wrapper' ).hide()
+ .css({ position : 'absolute' })
+ .html( this.template( this.$button.attr( 'id' ), this.options ));
+
+ // set up behavior on each link/anchor elem
+ if( this.options.length ){
+ var menu = this;
+ //precondition: there should be one option per li
+ this.$el.find( 'li' ).each( function( i, li ){
+ var option = menu.options[i];
+
+ // if the option has 'func', call that function when the anchor is clicked
+ if( option.func ){
+ $( this ).children( 'a.popupmenu-option' ).click( function( event ){
+ option.func.call( menu, event, option );
+ // bubble up so that an option click will call the close behavior
+ //return false;
+ });
+ }
+ });
+ }
+ return this;
+ },
+
+ template : function( id, options ){
+ return [
+ '<ul id="', id, '-menu" class="dropdown-menu">', this._templateOptions( options ), '</ul>'
+ ].join( '' );
+ },
+
+ _templateOptions : function( options ){
+ if( !options.length ){
+ return '<li>(no options)</li>';
+ }
+ return _.map( options, function( option ){
+ if( option.divider ){
+ return '<li class="divider"></li>';
+ } else if( option.header ){
+ return [ '<li class="head"><a href="javascript:void(0);">', option.html, '</a></li>' ].join( '' );
+ }
+ var href = option.href || 'javascript:void(0);',
+ target = ( option.target )?( ' target="' + option.target + '"' ):( '' ),
+ check = ( option.checked )?( '<span class="fa fa-check"></span>' ):( '' );
+ return [
+ '<li><a class="popupmenu-option" href="', href, '"', target, '>',
+ check, option.html,
+ '</a></li>'
+ ].join( '' );
+ }).join( '' );
+ },
+
+ // get the absolute position/offset for the menu
+ _getShownPosition : function( clickEvent ){
+
+ // display menu horiz. centered on click...
+ var menuWidth = this.$el.width();
+ var x = clickEvent.pageX - menuWidth / 2 ;
+
+ // adjust to handle horiz. scroll and window dimensions ( draw entirely on visible screen area )
+ x = Math.min( x, $( document ).scrollLeft() + $( window ).width() - menuWidth - 5 );
+ x = Math.max( x, $( document ).scrollLeft() + 5 );
+ return {
+ top: clickEvent.pageY,
+ left: x
+ };
+ },
+
+ // bind an event handler to all available frames so that when anything is clicked
+ // the menu is removed from the DOM and the event handler unbinds itself
+ _setUpCloseBehavior: function(){
+ var menu = this;
+//TODO: alternately: focus hack, blocking overlay, jquery.blockui
+
+ // function to close popup and unbind itself
+ function closePopup( event ){
+ $( document ).off( 'click.close_popup' );
+ if( window.parent !== window ){
+ try {
+ $( window.parent.document ).off( "click.close_popup" );
+ } catch( err ){}
+ } else {
+ try {
+ $( 'iframe#galaxy_main' ).contents().off( "click.close_popup" );
+ } catch( err ){}
+ }
+ menu.remove();
+ }
+
+ $( 'html' ).one( "click.close_popup", closePopup );
+ if( window.parent !== window ){
+ try {
+ $( window.parent.document ).find( 'html' ).one( "click.close_popup", closePopup );
+ } catch( err ){}
+ } else {
+ try {
+ $( 'iframe#galaxy_main' ).contents().one( "click.close_popup", closePopup );
+ } catch( err ){}
+ }
+ },
+
+ // add a menu option/item at the given index
+ addItem: function( item, index ){
+ // append to end if no index
+ index = ( index >= 0 ) ? index : this.options.length;
+ this.options.splice( index, 0, item );
+ return this;
+ },
+
+ // remove a menu option/item at the given index
+ removeItem: function( index ){
+ if( index >=0 ){
+ this.options.splice( index, 1 );
+ }
+ return this;
+ },
+
+ // search for a menu option by its html
+ findIndexByHtml: function( html ){
+ for( var i = 0; i < this.options.length; i++ ){
+ if( _.has( this.options[i], 'html' ) && ( this.options[i].html === html )){
+ return i;
+ }
+ }
+ return null;
+ },
+
+ // search for a menu option by its html
+ findItemByHtml: function( html ){
+ return this.options[( this.findIndexByHtml( html ))];
+ },
+
+ // string representation
+ toString: function(){
+ return 'PopupMenu';
+ }
+});
+/** shortcut to new for when you don't need to preserve the ref */
+PopupMenu.create = function _create( $button, options ){
+ return new PopupMenu( $button, options );
+};
+
+// -----------------------------------------------------------------------------
+// the following class functions are bridges from the original make_popupmenu and make_popup_menus
+// to the newer backbone.js PopupMenu
+
+/** Create a PopupMenu from simple map initial_options activated by clicking button_element.
+ * Converts initial_options to object array used by PopupMenu.
+ * @param {jQuery|DOMElement} button_element element which, when clicked, activates menu
+ * @param {Object} initial_options map of key -> values, where
+ * key is option text, value is fn to call when option is clicked
+ * @returns {PopupMenu} the PopupMenu created
+ */
+PopupMenu.make_popupmenu = function( button_element, initial_options ){
+ var convertedOptions = [];
+ _.each( initial_options, function( optionVal, optionKey ){
+ var newOption = { html: optionKey };
+
+ // keys with null values indicate: header
+ if( optionVal === null ){ // !optionVal? (null only?)
+ newOption.header = true;
+
+ // keys with function values indicate: a menu option
+ } else if( jQuery.type( optionVal ) === 'function' ){
+ newOption.func = optionVal;
+ }
+ //TODO:?? any other special optionVals?
+ // there was no divider option originally
+ convertedOptions.push( newOption );
+ });
+ return new PopupMenu( $( button_element ), convertedOptions );
+};
+
+/** Find all anchors in $parent (using selector) and covert anchors into a PopupMenu options map.
+ * @param {jQuery} $parent the element that contains the links to convert to options
+ * @param {String} selector jq selector string to find links
+ * @returns {Object[]} the options array to initialize a PopupMenu
+ */
+//TODO: lose parent and selector, pass in array of links, use map to return options
+PopupMenu.convertLinksToOptions = function( $parent, selector ){
+ $parent = $( $parent );
+ selector = selector || 'a';
+ var options = [];
+ $parent.find( selector ).each( function( elem, i ){
+ var option = {}, $link = $( elem );
+
+ // convert link text to the option text (html) and the href into the option func
+ option.html = $link.text();
+ if( $link.attr( 'href' ) ){
+ var linkHref = $link.attr( 'href' ),
+ linkTarget = $link.attr( 'target' ),
+ confirmText = $link.attr( 'confirm' );
+
+ option.func = function(){
+ // if there's a "confirm" attribute, throw up a confirmation dialog, and
+ // if the user cancels - do nothing
+ if( ( confirmText ) && ( !confirm( confirmText ) ) ){ return; }
+
+ // if there's no confirm attribute, or the user accepted the confirm dialog:
+ switch( linkTarget ){
+ // relocate the center panel
+ case '_parent':
+ window.parent.location = linkHref;
+ break;
+
+ // relocate the entire window
+ case '_top':
+ window.top.location = linkHref;
+ break;
+
+ // relocate this panel
+ default:
+ window.location = linkHref;
+ }
+ };
+ }
+ options.push( option );
+ });
+ return options;
+};
+
+/** Create a single popupmenu from existing DOM button and anchor elements
+ * @param {jQuery} $buttonElement the element that when clicked will open the menu
+ * @param {jQuery} $menuElement the element that contains the anchors to convert into a menu
+ * @param {String} menuElementLinkSelector jq selector string used to find anchors to be made into menu options
+ * @returns {PopupMenu} the PopupMenu (Backbone View) that can render, control the menu
+ */
+PopupMenu.fromExistingDom = function( $buttonElement, $menuElement, menuElementLinkSelector ){
+ $buttonElement = $( $buttonElement );
+ $menuElement = $( $menuElement );
+ var options = PopupMenu.convertLinksToOptions( $menuElement, menuElementLinkSelector );
+ // we're done with the menu (having converted it to an options map)
+ $menuElement.remove();
+ return new PopupMenu( $buttonElement, options );
+};
+
+/** Create all popupmenus within a document or a more specific element
+ * @param {DOMElement} parent the DOM element in which to search for popupmenus to build (defaults to document)
+ * @param {String} menuSelector jq selector string to find popupmenu menu elements (defaults to "div[popupmenu]")
+ * @param {Function} buttonSelectorBuildFn the function to build the jq button selector.
+ * Will be passed $menuElement, parent.
+ * (Defaults to return '#' + $menuElement.attr( 'popupmenu' ); )
+ * @returns {PopupMenu[]} array of popupmenus created
+ */
+PopupMenu.make_popup_menus = function( parent, menuSelector, buttonSelectorBuildFn ){
+ parent = parent || document;
+ // orig. Glx popupmenu menus have a (non-std) attribute 'popupmenu'
+ // which contains the id of the button that activates the menu
+ menuSelector = menuSelector || 'div[popupmenu]';
+ // default to (orig. Glx) matching button to menu by using the popupmenu attr of the menu as the id of the button
+ buttonSelectorBuildFn = buttonSelectorBuildFn || function( $menuElement, parent ){
+ return '#' + $menuElement.attr( 'popupmenu' );
+ };
+
+ // aggregate and return all PopupMenus
+ var popupMenusCreated = [];
+ $( parent ).find( menuSelector ).each( function(){
+ var $menuElement = $( this ),
+ $buttonElement = $( parent ).find( buttonSelectorBuildFn( $menuElement, parent ) );
+ popupMenusCreated.push( PopupMenu.fromDom( $buttonElement, $menuElement ) );
+ $buttonElement.addClass( 'popup' );
+ });
+ return popupMenusCreated;
+};
+
+
+// =============================================================================
+ return PopupMenu;
+});
+
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/packed/mvc/grid/grid-view.js
--- a/static/scripts/packed/mvc/grid/grid-view.js
+++ b/static/scripts/packed/mvc/grid/grid-view.js
@@ -1,1 +1,1 @@
-jQuery.ajaxSettings.traditional=true;define(["mvc/grid/grid-model","mvc/grid/grid-template","mvc/ui"],function(b,a){return Backbone.View.extend({grid:null,initialize:function(c){this.setElement("#grid-container");if(c.use_panels){$("#center").css({padding:"10px",overflow:"auto"})}this.init_grid(c)},handle_refresh:function(c){if(c){if($.inArray("history",c)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(f){this.grid=new b(f);var e=this.grid.attributes;this.handle_refresh(e.refresh_frames);var d=this.grid.get("url_base");d=d.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",d);this.$el.html(a.grid(e));this.$el.find("#grid-table-header").html(a.header(e));this.$el.find("#grid-table-body").html(a.body(e));this.$el.find("#grid-table-footer").html(a.footer(e));if(e.message){this.$el.find("#grid-message").html(a.message(e));var c=this;if(e.use_hide_message){setTimeout(function(){c.$el.find("#grid-message").html("")},5000)}}this.init_grid_elements();this.init_grid_controls();init_refresh_on_change()},init_grid_controls:function(){var c=this;this.$el.find(".operation-button").each(function(){$(this).off();$(this).click(function(){c.submit_operation(this,operation.confirm);return false})});this.$el.find("input[type=text]").each(function(){$(this).off();$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})});this.$el.find(".sort-link").each(function(){$(this).off();$(this).click(function(){c.set_sort_condition($(this).attr("sort_key"));return false})});this.$el.find(".text-filter-form").each(function(){$(this).off();$(this).submit(function(){var g=$(this).attr("column_key");var f=$("#input-"+g+"-filter");var h=f.val();f.val("");c.add_filter_condition(g,h);return false})});this.$el.find(".text-filter-val > a").each(function(){$(this).off();$(this).click(function(){$(this).parent().remove();c.remove_filter_condition($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});this.$el.find(".categorical-filter > a").each(function(){$(this).off();$(this).click(function(){c.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});var e=this.$el.find("#input-tags-filter");if(e.length){e.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var d=this.$el.find("#input-name-filter");if(d.length){d.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}this.$el.find(".advanced-search-toggle").each(function(){$(this).off();$(this).click(function(){c.$el.find("#standard-search").slideToggle("fast");c.$el.find("#advanced-search").slideToggle("fast");return false})});this.$el.find("#check_all").off();this.$el.find("#check_all").on("click",function(){c.check_all_items()})},init_grid_elements:function(){this.$el.find(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var r=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(r)});r()});if(this.$el.find(".community_rating_star").length!==0){this.$el.find(".community_rating_star").rating({})}var q=this.grid.attributes;var p=this;this.$el.find(".page-link > a").each(function(){$(this).click(function(){p.set_page($(this).attr("page_num"));return false})});this.$el.find(".use-inbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href"),inbound:true});return false})});this.$el.find(".use-outbound").each(function(){$(this).click(function(i){p.execute({href:$(this).attr("href")});return false})});var f=q.items.length;if(f==0){return}for(var k in q.items){var o=q.items[k];var l=this.$el.find("#grid-"+k+"-popup");l.off();var d=new PopupMenu(l);for(var h in q.operations){var e=q.operations[h];var m=e.label;var c=o.operation_config[m];var g=o.encode_id;if(c.allowed&&e.allow_popup){var n={html:e.label,href:c.url_args,target:c.target,confirmation_text:e.confirm,inbound:e.inbound};n.func=function(r){r.preventDefault();var j=$(r.target).html();var i=this.findItemByHtml(j);p.execute(i)};d.addItem(n)}}}},add_filter_condition:function(e,g){if(g===""){return false}this.grid.add_filter(e,g,true);var f=$(a.filter_element(e,g));var d=this;f.click(function(){$(this).remove();d.remove_filter_condition(e,g)});var c=this.$el.find("#"+e+"-filtering-criteria");c.append(f);this.go_page_one();this.execute()},remove_filter_condition:function(c,d){this.grid.remove_filter(c,d);this.go_page_one();this.execute()},set_sort_condition:function(g){var f=this.grid.get("sort_key");var e=g;if(f.indexOf(g)!==-1){if(f.substring(0,1)!=="-"){e="-"+g}}this.$el.find(".sort-arrow").remove();var d=(e.substring(0,1)=="-")?"↑":"↓";var c=$("<span>"+d+"</span>").addClass("sort-arrow");this.$el.find("#"+g+"-header").append(c);this.grid.set("sort_key",e);this.go_page_one();this.execute()},set_categorical_filter:function(e,g){var d=this.grid.get("categorical_filters")[e],f=this.grid.get("filters")[e];var c=this;this.$el.find("."+e+"-filter").each(function(){var k=$.trim($(this).text());var i=d[k];var j=i[e];if(j==g){$(this).empty();$(this).addClass("current-filter");$(this).append(k)}else{if(j==f){$(this).empty();var h=$('<a href="#">'+k+"</a>");h.click(function(){c.set_categorical_filter(e,j)});$(this).removeClass("current-filter");$(this).append(h)}}});this.grid.add_filter(e,g);this.go_page_one();this.execute()},set_page:function(c){var d=this;this.$el.find(".page-link").each(function(){var i=$(this).attr("id"),g=parseInt(i.split("-")[2],10),e=d.grid.get("cur_page"),h;if(g===c){h=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(h)}else{if(g===e){h=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var f=$('<a href="#">'+h+"</a>");f.click(function(){d.set_page(g)});$(this).append(f)}}});if(c==="all"){this.grid.set("cur_page",c)}else{this.grid.set("cur_page",parseInt(c,10))}this.execute()},submit_operation:function(d,g){var e=$(d).val();var f=this.$el.find('input[name="id"]:checked').length;if(!f>0){return false}var c=[];this.$el.find("input[name=id]:checked").each(function(){c.push($(this).val())});this.execute({operation:e,id:c,confirmation_text:g});return true},check_all_items:function(){var c=document.getElementById("check_all"),d=document.getElementsByTagName("input"),f=0,e;if(c.checked===true){for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=true;f++}}}else{for(e=0;e<d.length;e++){if(d[e].name.indexOf("id")!==-1){d[e].checked=false}}}this.init_grid_elements()},go_page_one:function(){var c=this.grid.get("cur_page");if(c!==null&&c!==undefined&&c!=="all"){this.grid.set("cur_page",1)}},execute:function(l){var f=null;var e=null;var g=null;var c=null;var k=null;if(l){e=l.href;g=l.operation;f=l.id;c=l.confirmation_text;k=l.inbound;if(e!==undefined&&e.indexOf("operation=")!=-1){var j=e.split("?");if(j.length>1){var i=j[1];var d=i.split("&");for(var h=0;h<d.length;h++){if(d[h].indexOf("operation")!=-1){g=d[h].split("=")[1];g=g.replace(/\+/g," ")}else{if(d[h].indexOf("id")!=-1){f=d[h].split("=")[1]}}}}}}if(g&&f){if(c&&c!=""&&c!="None"&&c!="null"){if(!confirm(c)){return false}}g=g.toLowerCase();this.grid.set({operation:g,item_ids:f});if(this.grid.can_async_op(g)){this.update_grid()}else{this.go_to(k,e)}return false}if(e){this.go_to(k,e);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(k,e)}return false},go_to:function(f,d){var e=this.grid.get("async");this.grid.set("async",false);advanced_search=this.$el.find("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!d){d=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:e});if(f){var c=$(".grid-header").closest(".inbound");if(c.length!==0){c.load(d);return}}window.location=d},update_grid:function(){var d=(this.grid.get("operation")?"POST":"GET");this.$el.find(".loading-elt-overlay").show();var c=this;$.ajax({type:d,url:c.grid.get("url_base"),data:c.grid.get_url_data(),error:function(e){alert("Grid refresh failed")},success:function(e){var g=c.grid.get("embedded");var h=c.grid.get("insert");var f=$.parseJSON(e);f.embedded=g;f.insert=h;c.init_grid(f);c.$el.find(".loading-elt-overlay").hide()},complete:function(){c.grid.set({operation:undefined,item_ids:undefined})}})}})});
\ No newline at end of file
+jQuery.ajaxSettings.traditional=true;define(["mvc/grid/grid-model","mvc/grid/grid-template","mvc/ui/popup-menu"],function(c,b,a){return Backbone.View.extend({grid:null,initialize:function(d){this.setElement("#grid-container");if(d.use_panels){$("#center").css({padding:"10px",overflow:"auto"})}this.init_grid(d)},handle_refresh:function(d){if(d){if($.inArray("history",d)>-1){if(top.Galaxy&&top.Galaxy.currHistoryPanel){top.Galaxy.currHistoryPanel.loadCurrentHistory()}}}},init_grid:function(g){this.grid=new c(g);var f=this.grid.attributes;this.handle_refresh(f.refresh_frames);var e=this.grid.get("url_base");e=e.replace(/^.*\/\/[^\/]+/,"");this.grid.set("url_base",e);this.$el.html(b.grid(f));this.$el.find("#grid-table-header").html(b.header(f));this.$el.find("#grid-table-body").html(b.body(f));this.$el.find("#grid-table-footer").html(b.footer(f));if(f.message){this.$el.find("#grid-message").html(b.message(f));var d=this;if(f.use_hide_message){setTimeout(function(){d.$el.find("#grid-message").html("")},5000)}}this.init_grid_elements();this.init_grid_controls();init_refresh_on_change()},init_grid_controls:function(){var d=this;this.$el.find(".operation-button").each(function(){$(this).off();$(this).click(function(){d.submit_operation(this,operation.confirm);return false})});this.$el.find("input[type=text]").each(function(){$(this).off();$(this).click(function(){$(this).select()}).keyup(function(){$(this).css("font-style","normal")})});this.$el.find(".sort-link").each(function(){$(this).off();$(this).click(function(){d.set_sort_condition($(this).attr("sort_key"));return false})});this.$el.find(".text-filter-form").each(function(){$(this).off();$(this).submit(function(){var h=$(this).attr("column_key");var g=$("#input-"+h+"-filter");var i=g.val();g.val("");d.add_filter_condition(h,i);return false})});this.$el.find(".text-filter-val > a").each(function(){$(this).off();$(this).click(function(){$(this).parent().remove();d.remove_filter_condition($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});this.$el.find(".categorical-filter > a").each(function(){$(this).off();$(this).click(function(){d.set_categorical_filter($(this).attr("filter_key"),$(this).attr("filter_val"));return false})});var f=this.$el.find("#input-tags-filter");if(f.length){f.autocomplete(this.grid.history_tag_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}var e=this.$el.find("#input-name-filter");if(e.length){e.autocomplete(this.grid.history_name_autocomplete_url,{selectFirst:false,autoFill:false,highlight:false,mustMatch:false})}this.$el.find(".advanced-search-toggle").each(function(){$(this).off();$(this).click(function(){d.$el.find("#standard-search").slideToggle("fast");d.$el.find("#advanced-search").slideToggle("fast");return false})});this.$el.find("#check_all").off();this.$el.find("#check_all").on("click",function(){d.check_all_items()})},init_grid_elements:function(){this.$el.find(".grid").each(function(){var j=$(this).find("input.grid-row-select-checkbox");var i=$(this).find("span.grid-selected-count");var s=function(){i.text($(j).filter(":checked").length)};$(j).each(function(){$(this).change(s)});s()});if(this.$el.find(".community_rating_star").length!==0){this.$el.find(".community_rating_star").rating({})}var r=this.grid.attributes;var q=this;this.$el.find(".page-link > a").each(function(){$(this).click(function(){q.set_page($(this).attr("page_num"));return false})});this.$el.find(".use-inbound").each(function(){$(this).click(function(i){q.execute({href:$(this).attr("href"),inbound:true});return false})});this.$el.find(".use-outbound").each(function(){$(this).click(function(i){q.execute({href:$(this).attr("href")});return false})});var g=r.items.length;if(g==0){return}for(var l in r.items){var p=r.items[l];var m=this.$el.find("#grid-"+l+"-popup");m.off();var e=new a(m);for(var k in r.operations){var f=r.operations[k];var n=f.label;var d=p.operation_config[n];var h=p.encode_id;if(d.allowed&&f.allow_popup){var o={html:f.label,href:d.url_args,target:d.target,confirmation_text:f.confirm,inbound:f.inbound};o.func=function(s){s.preventDefault();var j=$(s.target).html();var i=this.findItemByHtml(j);q.execute(i)};e.addItem(o)}}}},add_filter_condition:function(f,h){if(h===""){return false}this.grid.add_filter(f,h,true);var g=$(b.filter_element(f,h));var e=this;g.click(function(){$(this).remove();e.remove_filter_condition(f,h)});var d=this.$el.find("#"+f+"-filtering-criteria");d.append(g);this.go_page_one();this.execute()},remove_filter_condition:function(d,e){this.grid.remove_filter(d,e);this.go_page_one();this.execute()},set_sort_condition:function(h){var g=this.grid.get("sort_key");var f=h;if(g.indexOf(h)!==-1){if(g.substring(0,1)!=="-"){f="-"+h}}this.$el.find(".sort-arrow").remove();var e=(f.substring(0,1)=="-")?"↑":"↓";var d=$("<span>"+e+"</span>").addClass("sort-arrow");this.$el.find("#"+h+"-header").append(d);this.grid.set("sort_key",f);this.go_page_one();this.execute()},set_categorical_filter:function(f,h){var e=this.grid.get("categorical_filters")[f],g=this.grid.get("filters")[f];var d=this;this.$el.find("."+f+"-filter").each(function(){var l=$.trim($(this).text());var j=e[l];var k=j[f];if(k==h){$(this).empty();$(this).addClass("current-filter");$(this).append(l)}else{if(k==g){$(this).empty();var i=$('<a href="#">'+l+"</a>");i.click(function(){d.set_categorical_filter(f,k)});$(this).removeClass("current-filter");$(this).append(i)}}});this.grid.add_filter(f,h);this.go_page_one();this.execute()},set_page:function(d){var e=this;this.$el.find(".page-link").each(function(){var j=$(this).attr("id"),h=parseInt(j.split("-")[2],10),f=e.grid.get("cur_page"),i;if(h===d){i=$(this).children().text();$(this).empty();$(this).addClass("inactive-link");$(this).text(i)}else{if(h===f){i=$(this).text();$(this).empty();$(this).removeClass("inactive-link");var g=$('<a href="#">'+i+"</a>");g.click(function(){e.set_page(h)});$(this).append(g)}}});if(d==="all"){this.grid.set("cur_page",d)}else{this.grid.set("cur_page",parseInt(d,10))}this.execute()},submit_operation:function(e,h){var f=$(e).val();var g=this.$el.find('input[name="id"]:checked').length;if(!g>0){return false}var d=[];this.$el.find("input[name=id]:checked").each(function(){d.push($(this).val())});this.execute({operation:f,id:d,confirmation_text:h});return true},check_all_items:function(){var d=document.getElementById("check_all"),e=document.getElementsByTagName("input"),g=0,f;if(d.checked===true){for(f=0;f<e.length;f++){if(e[f].name.indexOf("id")!==-1){e[f].checked=true;g++}}}else{for(f=0;f<e.length;f++){if(e[f].name.indexOf("id")!==-1){e[f].checked=false}}}this.init_grid_elements()},go_page_one:function(){var d=this.grid.get("cur_page");if(d!==null&&d!==undefined&&d!=="all"){this.grid.set("cur_page",1)}},execute:function(m){var g=null;var f=null;var h=null;var d=null;var l=null;if(m){f=m.href;h=m.operation;g=m.id;d=m.confirmation_text;l=m.inbound;if(f!==undefined&&f.indexOf("operation=")!=-1){var k=f.split("?");if(k.length>1){var j=k[1];var e=j.split("&");for(var i=0;i<e.length;i++){if(e[i].indexOf("operation")!=-1){h=e[i].split("=")[1];h=h.replace(/\+/g," ")}else{if(e[i].indexOf("id")!=-1){g=e[i].split("=")[1]}}}}}}if(h&&g){if(d&&d!=""&&d!="None"&&d!="null"){if(!confirm(d)){return false}}h=h.toLowerCase();this.grid.set({operation:h,item_ids:g});if(this.grid.can_async_op(h)){this.update_grid()}else{this.go_to(l,f)}return false}if(f){this.go_to(l,f);return false}if(this.grid.get("async")){this.update_grid()}else{this.go_to(l,f)}return false},go_to:function(g,e){var f=this.grid.get("async");this.grid.set("async",false);advanced_search=this.$el.find("#advanced-search").is(":visible");this.grid.set("advanced_search",advanced_search);if(!e){e=this.grid.get("url_base")+"?"+$.param(this.grid.get_url_data())}this.grid.set({operation:undefined,item_ids:undefined,async:f});if(g){var d=$(".grid-header").closest(".inbound");if(d.length!==0){d.load(e);return}}window.location=e},update_grid:function(){var e=(this.grid.get("operation")?"POST":"GET");this.$el.find(".loading-elt-overlay").show();var d=this;$.ajax({type:e,url:d.grid.get("url_base"),data:d.grid.get_url_data(),error:function(f){alert("Grid refresh failed")},success:function(f){var h=d.grid.get("embedded");var i=d.grid.get("insert");var g=$.parseJSON(f);g.embedded=h;g.insert=i;d.init_grid(g);d.$el.find(".loading-elt-overlay").hide()},complete:function(){d.grid.set({operation:undefined,item_ids:undefined})}})}})});
\ No newline at end of file
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/packed/mvc/history/history-panel-edit.js
--- a/static/scripts/packed/mvc/history/history-panel-edit.js
+++ b/static/scripts/packed/mvc/history/history-panel-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-panel","mvc/history/history-contents","mvc/dataset/states","mvc/history/hda-model","mvc/history/hda-li-edit","mvc/history/hdca-li-edit","mvc/tags","mvc/annotations","jq-plugins/ui/fa-icon-button","utils/localization"],function(g,i,l,e,d,h,k,b,a,c){var j=g.HistoryPanel;var f=j.extend({HDAViewClass:d.HDAListItemEdit,HDCAViewClass:h.HDCAListItemEdit,initialize:function(m){m=m||{};j.prototype.initialize.call(this,m);this.tagsEditor=null;this.annotationEditor=null;this.purgeAllowed=m.purgeAllowed||false;this.annotationEditorShown=m.annotationEditorShown||false;this.tagsEditorShown=m.tagsEditorShown||false;this.multiselectActions=m.multiselectActions||this._getActions()},_setUpListeners:function(){j.prototype._setUpListeners.call(this);this.on("drop",function(m,n){this.dataDropped(n);this.dropTargetOff()})},_setUpCollectionListeners:function(){j.prototype._setUpCollectionListeners.call(this);this.collection.on("change:deleted",this._handleHdaDeletionChange,this);this.collection.on("change:visible",this._handleHdaVisibleChange,this);this.collection.on("change:purged",function(m){this.model.fetch()},this);return this},_setUpModelListeners:function(){j.prototype._setUpModelListeners.call(this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);return this},_buildNewRender:function(){var m=j.prototype._buildNewRender.call(this);if(!this.model){return m}if(Galaxy&&Galaxy.currUser&&Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(m);this._renderAnnotation(m)}return m},renderItems:function(n){var m=j.prototype.renderItems.call(this,n);this._renderCounts(n);return m},_renderCounts:function(o){function n(r,s){return['<a class="',r,'" href="javascript:void(0);">',s,"</a>"].join("")}o=o||this.$el;var m=this.collection.where({deleted:true}),q=this.collection.where({visible:false}),p=[];if(this.views.length){p.push([this.views.length,c("shown")].join(" "))}if(m.length){p.push((!this.showDeleted)?([m.length,n("toggle-deleted-link",c("deleted"))].join(" ")):(n("toggle-deleted-link",c("hide deleted"))))}if(q.length){p.push((!this.showHidden)?([q.length,n("toggle-hidden-link",c("hidden"))].join(" ")):(n("toggle-hidden-link",c("hide hidden"))))}return o.find("> .controls .subtitle").html(p.join(", "))},_renderTags:function(m){var n=this;this.tagsEditor=new k.TagsEditor({model:this.model,el:m.find(".controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){n.toggleHDATagEditors(true,n.fxSpeed)},onhide:function(){n.toggleHDATagEditors(false,n.fxSpeed)},$activator:a({title:c("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(m.find(".controls .actions"))})},_renderAnnotation:function(m){var n=this;this.annotationEditor=new b.AnnotationEditor({model:this.model,el:m.find(".controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){n.toggleHDAAnnotationEditors(true,n.fxSpeed)},onhide:function(){n.toggleHDAAnnotationEditors(false,n.fxSpeed)},$activator:a({title:c("Edit history annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(m.find(".controls .actions"))})},_setUpBehaviors:function(m){m=m||this.$el;j.prototype._setUpBehaviors.call(this,m);if(!this.model){return}if(this.multiselectActions.length){this.actionsPopup=new PopupMenu(m.find(".list-action-popup-btn"),this.multiselectActions)}if((!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var n=this,o=".controls .name";m.find(o).attr("title",c("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(p){var q=n.model.get("name");if(p&&p!==q){n.$el.find(o).text(p);n.model.save({name:p}).fail(function(){n.$el.find(o).text(n.model.previous("name"))})}else{n.$el.find(o).text(q)}}})},_getActions:function(){var m=this,n=[{html:c("Hide datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype.hide;m.getSelectedModels().ajaxQueue(o)}},{html:c("Unhide datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype.unhide;m.getSelectedModels().ajaxQueue(o)}},{html:c("Delete datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype["delete"];m.getSelectedModels().ajaxQueue(o)}},{html:c("Undelete datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype.undelete;m.getSelectedModels().ajaxQueue(o)}}];if(m.purgeAllowed){n.push({html:c("Permanently delete datasets"),func:function(){if(confirm(c("This will permanently remove the data in your datasets. Are you sure?"))){var o=e.HistoryDatasetAssociation.prototype.purge;m.getSelectedModels().ajaxQueue(o)}}})}n.push({html:c("Build Dataset List"),func:function(){m.getSelectedModels().promoteToHistoryDatasetCollection(m.model,"list")}});n.push({html:c("Build Dataset Pair"),func:function(){m.getSelectedModels().promoteToHistoryDatasetCollection(m.model,"paired")}});n.push({html:c("Build List of Dataset Pairs"),func:_.bind(m._showPairedCollectionModal,m)});return n},_showPairedCollectionModal:function(){var m=this,n=m.getSelectedModels().toJSON().filter(function(o){return o.history_content_type==="dataset"&&o.state===l.OK});if(n.length){require(["mvc/collection/paired-collection-creator"],function(o){window.creator=o.pairedCollectionCreatorModal(n,{historyId:m.model.id})})}else{}},_attachItems:function(m){this.$list(m).append(this.views.reverse().map(function(n){return n.$el}));return this},_attachView:function(n){var m=this;m.views.unshift(n);m.$list().prepend(n.render(0).$el.hide());n.$el.slideDown(m.fxSpeed)},_getItemViewOptions:function(n){var m=j.prototype._getItemViewOptions.call(this,n);_.extend(m,{purgeAllowed:this.purgeAllowed,tagsEditorShown:(this.tagsEditor&&!this.tagsEditor.hidden),annotationEditorShown:(this.annotationEditor&&!this.annotationEditor.hidden)});return m},_handleHdaDeletionChange:function(m){if(m.get("deleted")&&!this.showDeleted){this.removeItemView(m)}this._renderCounts()},_handleHdaVisibleChange:function(m){if(m.hidden()&&!this.storage.showHidden){this.removeItemView(m)}this._renderCounts()},toggleHDATagEditors:function(m){var n=Array.prototype.slice.call(arguments,1);_.each(this.views,function(o){if(o.tagsEditor){o.tagsEditor.toggle.apply(o.tagsEditor,n)}})},toggleHDAAnnotationEditors:function(m){var n=Array.prototype.slice.call(arguments,1);_.each(this.views,function(o){if(o.annotationEditor){o.annotationEditor.toggle.apply(o.annotationEditor,n)}})},events:_.extend(_.clone(j.prototype.events),{"click .show-selectors-btn":"toggleSelectors","click .toggle-deleted-link":function(m){this.toggleShowDeleted()},"click .toggle-hidden-link":function(m){this.toggleShowHidden()}}),updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},dropTargetOn:function(){if(this.dropTarget){return this}this.dropTarget=true;var n={dragenter:_.bind(this.dragenter,this),dragover:_.bind(this.dragover,this),dragleave:_.bind(this.dragleave,this),drop:_.bind(this.drop,this)};var o=this._renderDropTarget();this.$list().before([this._renderDropTargetHelp(),o]);for(var m in n){if(n.hasOwnProperty(m)){o.on(m,n[m])}}return this},_renderDropTarget:function(){return $("<div/>").addClass("history-drop-target").css({height:"64px",margin:"0px 10px 10px 10px",border:"1px dashed black","border-radius":"3px"})},_renderDropTargetHelp:function(){return $("<div/>").addClass("history-drop-target-help").css({margin:"10px 10px 4px 10px",color:"grey","font-size":"80%","font-style":"italic"}).text(c("Drag datasets here to copy them to the current history"))},dropTargetOff:function(){if(!this.dropTarget){return this}this.dropTarget=false;this.$(".history-drop-target").remove();this.$(".history-drop-target-help").remove();return this},dropTargetToggle:function(){if(this.dropTarget){this.dropTargetOff()}else{this.dropTargetOn()}return this},dragenter:function(m){m.preventDefault();m.stopPropagation();this.$(".history-drop-target").css("border","2px solid black")},dragover:function(m){m.preventDefault();m.stopPropagation()},dragleave:function(m){m.preventDefault();m.stopPropagation();this.$(".history-drop-target").css("border","1px dashed black")},drop:function(o){o.preventDefault();o.dataTransfer.dropEffect="move";var m=this,p=o.dataTransfer.getData("text");try{p=JSON.parse(p)}catch(n){this.warn("error parsing JSON from drop:",p)}this.trigger("droptarget:drop",o,p,m);return false},dataDropped:function(n){var m=this;if(_.isObject(n)&&n.model_class==="HistoryDatasetAssociation"&&n.id){return m.model.contents.copy(n.id)}return jQuery.when()},toString:function(){return"HistoryPanelEdit("+((this.model)?(this.model.get("name")):(""))+")"}});return{HistoryPanelEdit:f}});
\ No newline at end of file
+define(["mvc/history/history-panel","mvc/history/history-contents","mvc/dataset/states","mvc/history/hda-model","mvc/history/hda-li-edit","mvc/history/hdca-li-edit","mvc/tags","mvc/annotations","jq-plugins/ui/fa-icon-button","mvc/ui/popup-menu","utils/localization"],function(h,j,m,f,e,i,l,c,b,a,d){var k=h.HistoryPanel;var g=k.extend({HDAViewClass:e.HDAListItemEdit,HDCAViewClass:i.HDCAListItemEdit,initialize:function(n){n=n||{};k.prototype.initialize.call(this,n);this.tagsEditor=null;this.annotationEditor=null;this.purgeAllowed=n.purgeAllowed||false;this.annotationEditorShown=n.annotationEditorShown||false;this.tagsEditorShown=n.tagsEditorShown||false;this.multiselectActions=n.multiselectActions||this._getActions()},_setUpListeners:function(){k.prototype._setUpListeners.call(this);this.on("drop",function(n,o){this.dataDropped(o);this.dropTargetOff()})},_setUpCollectionListeners:function(){k.prototype._setUpCollectionListeners.call(this);this.collection.on("change:deleted",this._handleHdaDeletionChange,this);this.collection.on("change:visible",this._handleHdaVisibleChange,this);this.collection.on("change:purged",function(n){this.model.fetch()},this);return this},_setUpModelListeners:function(){k.prototype._setUpModelListeners.call(this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);return this},_buildNewRender:function(){var n=k.prototype._buildNewRender.call(this);if(!this.model){return n}if(Galaxy&&Galaxy.currUser&&Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(n);this._renderAnnotation(n)}return n},renderItems:function(o){var n=k.prototype.renderItems.call(this,o);this._renderCounts(o);return n},_renderCounts:function(p){function o(s,t){return['<a class="',s,'" href="javascript:void(0);">',t,"</a>"].join("")}p=p||this.$el;var n=this.collection.where({deleted:true}),r=this.collection.where({visible:false}),q=[];if(this.views.length){q.push([this.views.length,d("shown")].join(" "))}if(n.length){q.push((!this.showDeleted)?([n.length,o("toggle-deleted-link",d("deleted"))].join(" ")):(o("toggle-deleted-link",d("hide deleted"))))}if(r.length){q.push((!this.showHidden)?([r.length,o("toggle-hidden-link",d("hidden"))].join(" ")):(o("toggle-hidden-link",d("hide hidden"))))}return p.find("> .controls .subtitle").html(q.join(", "))},_renderTags:function(n){var o=this;this.tagsEditor=new l.TagsEditor({model:this.model,el:n.find(".controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){o.toggleHDATagEditors(true,o.fxSpeed)},onhide:function(){o.toggleHDATagEditors(false,o.fxSpeed)},$activator:b({title:d("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(n.find(".controls .actions"))})},_renderAnnotation:function(n){var o=this;this.annotationEditor=new c.AnnotationEditor({model:this.model,el:n.find(".controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){o.toggleHDAAnnotationEditors(true,o.fxSpeed)},onhide:function(){o.toggleHDAAnnotationEditors(false,o.fxSpeed)},$activator:b({title:d("Edit history annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(n.find(".controls .actions"))})},_setUpBehaviors:function(n){n=n||this.$el;k.prototype._setUpBehaviors.call(this,n);if(!this.model){return}if(this.multiselectActions.length){this.actionsPopup=new a(n.find(".list-action-popup-btn"),this.multiselectActions)}if((!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var o=this,p=".controls .name";n.find(p).attr("title",d("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(q){var r=o.model.get("name");if(q&&q!==r){o.$el.find(p).text(q);o.model.save({name:q}).fail(function(){o.$el.find(p).text(o.model.previous("name"))})}else{o.$el.find(p).text(r)}}})},_getActions:function(){var n=this,o=[{html:d("Hide datasets"),func:function(){var p=f.HistoryDatasetAssociation.prototype.hide;n.getSelectedModels().ajaxQueue(p)}},{html:d("Unhide datasets"),func:function(){var p=f.HistoryDatasetAssociation.prototype.unhide;n.getSelectedModels().ajaxQueue(p)}},{html:d("Delete datasets"),func:function(){var p=f.HistoryDatasetAssociation.prototype["delete"];n.getSelectedModels().ajaxQueue(p)}},{html:d("Undelete datasets"),func:function(){var p=f.HistoryDatasetAssociation.prototype.undelete;n.getSelectedModels().ajaxQueue(p)}}];if(n.purgeAllowed){o.push({html:d("Permanently delete datasets"),func:function(){if(confirm(d("This will permanently remove the data in your datasets. Are you sure?"))){var p=f.HistoryDatasetAssociation.prototype.purge;n.getSelectedModels().ajaxQueue(p)}}})}o.push({html:d("Build Dataset List"),func:function(){n.getSelectedModels().promoteToHistoryDatasetCollection(n.model,"list")}});o.push({html:d("Build Dataset Pair"),func:function(){n.getSelectedModels().promoteToHistoryDatasetCollection(n.model,"paired")}});o.push({html:d("Build List of Dataset Pairs"),func:_.bind(n._showPairedCollectionModal,n)});return o},_showPairedCollectionModal:function(){var n=this,o=n.getSelectedModels().toJSON().filter(function(p){return p.history_content_type==="dataset"&&p.state===m.OK});if(o.length){require(["mvc/collection/paired-collection-creator"],function(p){window.creator=p.pairedCollectionCreatorModal(o,{historyId:n.model.id})})}else{}},_attachItems:function(n){this.$list(n).append(this.views.reverse().map(function(o){return o.$el}));return this},_attachView:function(o){var n=this;n.views.unshift(o);n.$list().prepend(o.render(0).$el.hide());o.$el.slideDown(n.fxSpeed)},_getItemViewOptions:function(o){var n=k.prototype._getItemViewOptions.call(this,o);_.extend(n,{purgeAllowed:this.purgeAllowed,tagsEditorShown:(this.tagsEditor&&!this.tagsEditor.hidden),annotationEditorShown:(this.annotationEditor&&!this.annotationEditor.hidden)});return n},_handleHdaDeletionChange:function(n){if(n.get("deleted")&&!this.showDeleted){this.removeItemView(n)}this._renderCounts()},_handleHdaVisibleChange:function(n){if(n.hidden()&&!this.storage.showHidden){this.removeItemView(n)}this._renderCounts()},toggleHDATagEditors:function(n){var o=Array.prototype.slice.call(arguments,1);_.each(this.views,function(p){if(p.tagsEditor){p.tagsEditor.toggle.apply(p.tagsEditor,o)}})},toggleHDAAnnotationEditors:function(n){var o=Array.prototype.slice.call(arguments,1);_.each(this.views,function(p){if(p.annotationEditor){p.annotationEditor.toggle.apply(p.annotationEditor,o)}})},events:_.extend(_.clone(k.prototype.events),{"click .show-selectors-btn":"toggleSelectors","click .toggle-deleted-link":function(n){this.toggleShowDeleted()},"click .toggle-hidden-link":function(n){this.toggleShowHidden()}}),updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},dropTargetOn:function(){if(this.dropTarget){return this}this.dropTarget=true;var o={dragenter:_.bind(this.dragenter,this),dragover:_.bind(this.dragover,this),dragleave:_.bind(this.dragleave,this),drop:_.bind(this.drop,this)};var p=this._renderDropTarget();this.$list().before([this._renderDropTargetHelp(),p]);for(var n in o){if(o.hasOwnProperty(n)){p.on(n,o[n])}}return this},_renderDropTarget:function(){return $("<div/>").addClass("history-drop-target").css({height:"64px",margin:"0px 10px 10px 10px",border:"1px dashed black","border-radius":"3px"})},_renderDropTargetHelp:function(){return $("<div/>").addClass("history-drop-target-help").css({margin:"10px 10px 4px 10px",color:"grey","font-size":"80%","font-style":"italic"}).text(d("Drag datasets here to copy them to the current history"))},dropTargetOff:function(){if(!this.dropTarget){return this}this.dropTarget=false;this.$(".history-drop-target").remove();this.$(".history-drop-target-help").remove();return this},dropTargetToggle:function(){if(this.dropTarget){this.dropTargetOff()}else{this.dropTargetOn()}return this},dragenter:function(n){n.preventDefault();n.stopPropagation();this.$(".history-drop-target").css("border","2px solid black")},dragover:function(n){n.preventDefault();n.stopPropagation()},dragleave:function(n){n.preventDefault();n.stopPropagation();this.$(".history-drop-target").css("border","1px dashed black")},drop:function(p){p.preventDefault();p.dataTransfer.dropEffect="move";var n=this,q=p.dataTransfer.getData("text");try{q=JSON.parse(q)}catch(o){this.warn("error parsing JSON from drop:",q)}this.trigger("droptarget:drop",p,q,n);return false},dataDropped:function(o){var n=this;if(_.isObject(o)&&o.model_class==="HistoryDatasetAssociation"&&o.id){return n.model.contents.copy(o.id)}return jQuery.when()},toString:function(){return"HistoryPanelEdit("+((this.model)?(this.model.get("name")):(""))+")"}});return{HistoryPanelEdit:g}});
\ No newline at end of file
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/packed/mvc/history/options-menu.js
--- a/static/scripts/packed/mvc/history/options-menu.js
+++ b/static/scripts/packed/mvc/history/options-menu.js
@@ -1,1 +1,1 @@
-define(["mvc/base-mvc","utils/localization"],function(a,d){var e=[{html:d("History Lists"),header:true},{html:d("Saved Histories"),href:"history/list"},{html:d("Histories Shared with Me"),href:"history/list_shared"},{html:d("Current History"),header:true,anon:true},{html:d("Create New"),func:function(){if(Galaxy&&Galaxy.currHistoryPanel){Galaxy.currHistoryPanel.createNewHistory()}}},{html:d("Copy History"),href:"history/copy"},{html:d("Copy Datasets"),href:"dataset/copy_datasets"},{html:d("Share or Publish"),href:"history/sharing"},{html:d("Extract Workflow"),href:"workflow/build_from_current_history"},{html:d("Dataset Security"),href:"root/history_set_default_permissions"},{html:d("Resume Paused Jobs"),href:"history/resume_paused_jobs?current=True",anon:true},{html:d("Collapse Expanded Datasets"),func:function(){if(Galaxy&&Galaxy.currHistoryPanel){Galaxy.currHistoryPanel.collapseAll()}}},{html:d("Unhide Hidden Datasets"),confirm:d("Really unhide all hidden datasets?"),href:"history/unhide_datasets?current=True",anon:true},{html:d("Delete Hidden Datasets"),confirm:d("Really delete all hidden datasets?"),href:"history/delete_hidden_datasets",anon:true},{html:d("Purge Deleted Datasets"),confirm:d("Really delete all deleted datasets permanently? This cannot be undone."),href:"history/purge_deleted_datasets",purge:true,anon:true},{html:d("Show Structure"),href:"history/display_structured",anon:true},{html:d("Export Citations"),href:"history/citations",anon:true},{html:d("Export to File"),href:"history/export_archive?preview=True",anon:true},{html:d("Delete"),confirm:d("Really delete the current history?"),href:"history/delete_current"},{html:d("Delete Permanently"),confirm:d("Really delete the current history permanently? This cannot be undone."),href:"history/delete_current?purge=True",purge:true,anon:true},{html:d("Other Actions"),header:true},{html:d("Import from File"),href:"history/import_archive"}];function c(h,g,f){return _.clone(e).filter(function(i){if(h&&!i.anon){return false}if(!g&&i.purge){return false}if(i.href){i.href=f+i.href;i.target="galaxy_main"}if(i.confirm){i.func=function(){if(confirm(i.confirm)){galaxy_main.location=i.href}}}return true})}var b=function(i,g){g=g||{};var j=g.anonymous===undefined?true:g.anonymous,h=g.purgeAllowed||false,f=g.root||((Galaxy&&Galaxy.options)?Galaxy.options.root:"/"),k=c(j,h,f);return new PopupMenu(i,k)};return b});
\ No newline at end of file
+define(["mvc/ui/popup-menu","mvc/base-mvc","utils/localization"],function(b,a,e){var f=[{html:e("History Lists"),header:true},{html:e("Saved Histories"),href:"history/list"},{html:e("Histories Shared with Me"),href:"history/list_shared"},{html:e("Current History"),header:true,anon:true},{html:e("Create New"),func:function(){if(Galaxy&&Galaxy.currHistoryPanel){Galaxy.currHistoryPanel.createNewHistory()}}},{html:e("Copy History"),href:"history/copy"},{html:e("Copy Datasets"),href:"dataset/copy_datasets"},{html:e("Share or Publish"),href:"history/sharing"},{html:e("Extract Workflow"),href:"workflow/build_from_current_history"},{html:e("Dataset Security"),href:"root/history_set_default_permissions"},{html:e("Resume Paused Jobs"),href:"history/resume_paused_jobs?current=True",anon:true},{html:e("Collapse Expanded Datasets"),func:function(){if(Galaxy&&Galaxy.currHistoryPanel){Galaxy.currHistoryPanel.collapseAll()}}},{html:e("Unhide Hidden Datasets"),confirm:e("Really unhide all hidden datasets?"),href:"history/unhide_datasets?current=True",anon:true},{html:e("Delete Hidden Datasets"),confirm:e("Really delete all hidden datasets?"),href:"history/delete_hidden_datasets",anon:true},{html:e("Purge Deleted Datasets"),confirm:e("Really delete all deleted datasets permanently? This cannot be undone."),href:"history/purge_deleted_datasets",purge:true,anon:true},{html:e("Show Structure"),href:"history/display_structured",anon:true},{html:e("Export Citations"),href:"history/citations",anon:true},{html:e("Export to File"),href:"history/export_archive?preview=True",anon:true},{html:e("Delete"),confirm:e("Really delete the current history?"),href:"history/delete_current"},{html:e("Delete Permanently"),confirm:e("Really delete the current history permanently? This cannot be undone."),href:"history/delete_current?purge=True",purge:true,anon:true},{html:e("Other Actions"),header:true},{html:e("Import from File"),href:"history/import_archive"}];function d(i,h,g){return _.clone(f).filter(function(j){if(i&&!j.anon){return false}if(!h&&j.purge){return false}if(j.href){j.href=g+j.href;j.target="galaxy_main"}if(j.confirm){j.func=function(){if(confirm(j.confirm)){galaxy_main.location=j.href}}}return true})}var c=function(j,h){h=h||{};var k=h.anonymous===undefined?true:h.anonymous,i=h.purgeAllowed||false,g=h.root||((Galaxy&&Galaxy.options)?Galaxy.options.root:"/"),l=d(k,i,g);return new b(j,l)};return c});
\ No newline at end of file
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};
\ No newline at end of file
+var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};
\ No newline at end of file
diff -r 6c9848ad6d02691c7c68cd8faada68753126b472 -r 5b5dde05d21f02afa23cfe1c98396002d907de21 static/scripts/packed/mvc/ui/popup-menu.js
--- /dev/null
+++ b/static/scripts/packed/mvc/ui/popup-menu.js
@@ -0,0 +1,1 @@
+define([],function(){var a=Backbone.View.extend({initialize:function(d,c){this.$button=d;if(!this.$button.size()){this.$button=$("<div/>")}this.options=c||[];var e=this;this.$button.click(function(f){$(".popmenu-wrapper").remove();e._renderAndShow(f);return false})},_renderAndShow:function(c){this.render();this.$el.appendTo("body").css(this._getShownPosition(c)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var c=this;this.$el.find("li").each(function(e,d){var f=c.options[e];if(f.func){$(this).children("a.popupmenu-option").click(function(g){f.func.call(c,g,f)})}})}return this},template:function(d,c){return['<ul id="',d,'-menu" class="dropdown-menu">',this._templateOptions(c),"</ul>"].join("")},_templateOptions:function(c){if(!c.length){return"<li>(no options)</li>"}return _.map(c,function(f){if(f.divider){return'<li class="divider"></li>'}else{if(f.header){return['<li class="head"><a href="javascript:void(0);">',f.html,"</a></li>"].join("")}}var e=f.href||"javascript:void(0);",g=(f.target)?(' target="'+f.target+'"'):(""),d=(f.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',e,'"',g,">",d,f.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(d){var e=this.$el.width();var c=d.pageX-e/2;c=Math.min(c,$(document).scrollLeft()+$(window).width()-e-5);c=Math.max(c,$(document).scrollLeft()+5);return{top:d.pageY,left:c}},_setUpCloseBehavior:function(){var e=this;function c(g){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(f){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(f){}}e.remove()}$("html").one("click.close_popup",c);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",c)}catch(d){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",c)}catch(d){}}},addItem:function(d,c){c=(c>=0)?c:this.options.length;this.options.splice(c,0,d);return this},removeItem:function(c){if(c>=0){this.options.splice(c,1)}return this},findIndexByHtml:function(d){for(var c=0;c<this.options.length;c++){if(_.has(this.options[c],"html")&&(this.options[c].html===d)){return c}}return null},findItemByHtml:function(c){return this.options[(this.findIndexByHtml(c))]},toString:function(){return"PopupMenu"}});a.create=function b(d,c){return new a(d,c)};a.make_popupmenu=function(d,e){var c=[];_.each(e,function(h,f){var g={html:f};if(h===null){g.header=true}else{if(jQuery.type(h)==="function"){g.func=h}}c.push(g)});return new a($(d),c)};a.convertLinksToOptions=function(e,c){e=$(e);c=c||"a";var d=[];e.find(c).each(function(j,g){var h={},f=$(j);h.html=f.text();if(f.attr("href")){var l=f.attr("href"),m=f.attr("target"),k=f.attr("confirm");h.func=function(){if((k)&&(!confirm(k))){return}switch(m){case"_parent":window.parent.location=l;break;case"_top":window.top.location=l;break;default:window.location=l}}}d.push(h)});return d};a.fromExistingDom=function(f,e,c){f=$(f);e=$(e);var d=a.convertLinksToOptions(e,c);e.remove();return new a(f,d)};a.make_popup_menus=function(e,d,f){e=e||document;d=d||"div[popupmenu]";f=f||function(g,h){return"#"+g.attr("popupmenu")};var c=[];$(e).find(d).each(function(){var g=$(this),h=$(e).find(f(g,e));c.push(a.fromDom(h,g));h.addClass("popup")});return c};return a});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: modularize fa-icon button from ui.js
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6c9848ad6d02/
Changeset: 6c9848ad6d02
User: carlfeberhard
Date: 2014-12-09 17:55:24+00:00
Summary: Client build: modularize fa-icon button from ui.js
Affected #: 21 files
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/jq-plugins/ui/fa-icon-button.js
--- /dev/null
+++ b/client/galaxy/scripts/jq-plugins/ui/fa-icon-button.js
@@ -0,0 +1,48 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define([], factory);
+ } else {
+ root.faIconButton = factory();
+ }
+
+}(this, function () {
+//============================================================================
+ /** Returns a jQuery object containing a clickable font-awesome button.
+ * options:
+ * tooltipConfig : option map for bootstrap tool tip
+ * classes : array of class names (will always be classed as icon-btn)
+ * disabled : T/F - add the 'disabled' class?
+ * title : tooltip/title string
+ * target : optional href target
+ * href : optional href
+ * faIcon : which font awesome icon to use
+ * onclick : function to call when the button is clicked
+ */
+ var faIconButton = function( options ){
+ options = options || {};
+ options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' };
+
+ options.classes = [ 'icon-btn' ].concat( options.classes || [] );
+ if( options.disabled ){
+ options.classes.push( 'disabled' );
+ }
+
+ var html = [
+ '<a class="', options.classes.join( ' ' ), '"',
+ (( options.title )?( ' title="' + options.title + '"' ):( '' )),
+ (( !options.disabled && options.target )? ( ' target="' + options.target + '"' ):( '' )),
+ ' href="', (( !options.disabled && options.href )?( options.href ):( 'javascript:void(0);' )), '">',
+ // could go with something less specific here - like 'html'
+ '<span class="fa ', options.faIcon, '"></span>',
+ '</a>'
+ ].join( '' );
+ var $button = $( html ).tooltip( options.tooltipConfig );
+ if( _.isFunction( options.onclick ) ){
+ $button.click( options.onclick );
+ }
+ return $button;
+ };
+
+//============================================================================
+ return faIconButton;
+}));
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/mvc/dataset/dataset-li-edit.js
--- a/client/galaxy/scripts/mvc/dataset/dataset-li-edit.js
+++ b/client/galaxy/scripts/mvc/dataset/dataset-li-edit.js
@@ -3,9 +3,10 @@
"mvc/dataset/dataset-li",
"mvc/tags",
"mvc/annotations",
+ "jq-plugins/ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization"
-], function( STATES, DATASET_LI, TAGS, ANNOTATIONS, BASE_MVC, _l ){
+], function( STATES, DATASET_LI, TAGS, ANNOTATIONS, faIconButton, BASE_MVC, _l ){
//==============================================================================
var _super = DATASET_LI.DatasetListItemView;
/** @class Editing view for DatasetAssociation.
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/mvc/dataset/dataset-li.js
--- a/client/galaxy/scripts/mvc/dataset/dataset-li.js
+++ b/client/galaxy/scripts/mvc/dataset/dataset-li.js
@@ -1,9 +1,10 @@
define([
"mvc/list/list-item",
"mvc/dataset/states",
+ "jq-plugins/ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization"
-], function( LIST_ITEM, STATES, BASE_MVC, _l ){
+], function( LIST_ITEM, STATES, faIconButton, BASE_MVC, _l ){
/* global Backbone */
/*==============================================================================
TODO:
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/mvc/history/hdca-li-edit.js
--- a/client/galaxy/scripts/mvc/history/hdca-li-edit.js
+++ b/client/galaxy/scripts/mvc/history/hdca-li-edit.js
@@ -1,8 +1,9 @@
define([
"mvc/dataset/states",
"mvc/history/hdca-li",
+ "jq-plugins/ui/fa-icon-button",
"utils/localization"
-], function( STATES, HDCA_LI, _l ){
+], function( STATES, HDCA_LI, faIconButton, _l ){
//==============================================================================
var _super = HDCA_LI.HDCAListItemView;
/** @class Editing view for HistoryDatasetCollectionAssociation.
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/mvc/history/history-panel-edit.js
--- a/client/galaxy/scripts/mvc/history/history-panel-edit.js
+++ b/client/galaxy/scripts/mvc/history/history-panel-edit.js
@@ -7,6 +7,7 @@
"mvc/history/hdca-li-edit",
"mvc/tags",
"mvc/annotations",
+ "jq-plugins/ui/fa-icon-button",
"utils/localization"
], function(
HPANEL,
@@ -17,6 +18,7 @@
HDCA_LI_EDIT,
TAGS,
ANNOTATIONS,
+ faIconButton,
_l
){
/* =============================================================================
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/mvc/history/history-panel.js
--- a/client/galaxy/scripts/mvc/history/history-panel.js
+++ b/client/galaxy/scripts/mvc/history/history-panel.js
@@ -6,6 +6,7 @@
"mvc/history/hdca-li",
"mvc/collection/collection-panel",
"mvc/user/user-model",
+ "jq-plugins/ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization",
"jq-plugins/ui/search-input"
@@ -17,6 +18,7 @@
HDCA_LI,
COLLECTION_PANEL,
USER,
+ faIconButton,
BASE_MVC,
_l
){
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 client/galaxy/scripts/mvc/ui.js
--- a/client/galaxy/scripts/mvc/ui.js
+++ b/client/galaxy/scripts/mvc/ui.js
@@ -486,31 +486,3 @@
});
return popupMenusCreated;
};
-
-
-//==============================================================================
-var faIconButton = function( options ){
-//TODO: move out of global
- options = options || {};
- options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' };
-
- options.classes = [ 'icon-btn' ].concat( options.classes || [] );
- if( options.disabled ){
- options.classes.push( 'disabled' );
- }
-
- var html = [
- '<a class="', options.classes.join( ' ' ), '"',
- (( options.title )?( ' title="' + options.title + '"' ):( '' )),
- (( !options.disabled && options.target )? ( ' target="' + options.target + '"' ):( '' )),
- ' href="', (( !options.disabled && options.href )?( options.href ):( 'javascript:void(0);' )), '">',
- // could go with something less specific here - like 'html'
- '<span class="fa ', options.faIcon, '"></span>',
- '</a>'
- ].join( '' );
- var $button = $( html ).tooltip( options.tooltipConfig );
- if( _.isFunction( options.onclick ) ){
- $button.click( options.onclick );
- }
- return $button;
-};
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/jq-plugins/ui/fa-icon-button.js
--- /dev/null
+++ b/static/scripts/jq-plugins/ui/fa-icon-button.js
@@ -0,0 +1,48 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define([], factory);
+ } else {
+ root.faIconButton = factory();
+ }
+
+}(this, function () {
+//============================================================================
+ /** Returns a jQuery object containing a clickable font-awesome button.
+ * options:
+ * tooltipConfig : option map for bootstrap tool tip
+ * classes : array of class names (will always be classed as icon-btn)
+ * disabled : T/F - add the 'disabled' class?
+ * title : tooltip/title string
+ * target : optional href target
+ * href : optional href
+ * faIcon : which font awesome icon to use
+ * onclick : function to call when the button is clicked
+ */
+ var faIconButton = function( options ){
+ options = options || {};
+ options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' };
+
+ options.classes = [ 'icon-btn' ].concat( options.classes || [] );
+ if( options.disabled ){
+ options.classes.push( 'disabled' );
+ }
+
+ var html = [
+ '<a class="', options.classes.join( ' ' ), '"',
+ (( options.title )?( ' title="' + options.title + '"' ):( '' )),
+ (( !options.disabled && options.target )? ( ' target="' + options.target + '"' ):( '' )),
+ ' href="', (( !options.disabled && options.href )?( options.href ):( 'javascript:void(0);' )), '">',
+ // could go with something less specific here - like 'html'
+ '<span class="fa ', options.faIcon, '"></span>',
+ '</a>'
+ ].join( '' );
+ var $button = $( html ).tooltip( options.tooltipConfig );
+ if( _.isFunction( options.onclick ) ){
+ $button.click( options.onclick );
+ }
+ return $button;
+ };
+
+//============================================================================
+ return faIconButton;
+}));
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/mvc/dataset/dataset-li-edit.js
--- a/static/scripts/mvc/dataset/dataset-li-edit.js
+++ b/static/scripts/mvc/dataset/dataset-li-edit.js
@@ -3,9 +3,10 @@
"mvc/dataset/dataset-li",
"mvc/tags",
"mvc/annotations",
+ "jq-plugins/ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization"
-], function( STATES, DATASET_LI, TAGS, ANNOTATIONS, BASE_MVC, _l ){
+], function( STATES, DATASET_LI, TAGS, ANNOTATIONS, faIconButton, BASE_MVC, _l ){
//==============================================================================
var _super = DATASET_LI.DatasetListItemView;
/** @class Editing view for DatasetAssociation.
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/mvc/dataset/dataset-li.js
--- a/static/scripts/mvc/dataset/dataset-li.js
+++ b/static/scripts/mvc/dataset/dataset-li.js
@@ -1,9 +1,10 @@
define([
"mvc/list/list-item",
"mvc/dataset/states",
+ "jq-plugins/ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization"
-], function( LIST_ITEM, STATES, BASE_MVC, _l ){
+], function( LIST_ITEM, STATES, faIconButton, BASE_MVC, _l ){
/* global Backbone */
/*==============================================================================
TODO:
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/mvc/history/hdca-li-edit.js
--- a/static/scripts/mvc/history/hdca-li-edit.js
+++ b/static/scripts/mvc/history/hdca-li-edit.js
@@ -1,8 +1,9 @@
define([
"mvc/dataset/states",
"mvc/history/hdca-li",
+ "jq-plugins/ui/fa-icon-button",
"utils/localization"
-], function( STATES, HDCA_LI, _l ){
+], function( STATES, HDCA_LI, faIconButton, _l ){
//==============================================================================
var _super = HDCA_LI.HDCAListItemView;
/** @class Editing view for HistoryDatasetCollectionAssociation.
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/mvc/history/history-panel-edit.js
--- a/static/scripts/mvc/history/history-panel-edit.js
+++ b/static/scripts/mvc/history/history-panel-edit.js
@@ -7,6 +7,7 @@
"mvc/history/hdca-li-edit",
"mvc/tags",
"mvc/annotations",
+ "jq-plugins/ui/fa-icon-button",
"utils/localization"
], function(
HPANEL,
@@ -17,6 +18,7 @@
HDCA_LI_EDIT,
TAGS,
ANNOTATIONS,
+ faIconButton,
_l
){
/* =============================================================================
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/mvc/history/history-panel.js
--- a/static/scripts/mvc/history/history-panel.js
+++ b/static/scripts/mvc/history/history-panel.js
@@ -6,6 +6,7 @@
"mvc/history/hdca-li",
"mvc/collection/collection-panel",
"mvc/user/user-model",
+ "jq-plugins/ui/fa-icon-button",
"mvc/base-mvc",
"utils/localization",
"jq-plugins/ui/search-input"
@@ -17,6 +18,7 @@
HDCA_LI,
COLLECTION_PANEL,
USER,
+ faIconButton,
BASE_MVC,
_l
){
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -486,31 +486,3 @@
});
return popupMenusCreated;
};
-
-
-//==============================================================================
-var faIconButton = function( options ){
-//TODO: move out of global
- options = options || {};
- options.tooltipConfig = options.tooltipConfig || { placement: 'bottom' };
-
- options.classes = [ 'icon-btn' ].concat( options.classes || [] );
- if( options.disabled ){
- options.classes.push( 'disabled' );
- }
-
- var html = [
- '<a class="', options.classes.join( ' ' ), '"',
- (( options.title )?( ' title="' + options.title + '"' ):( '' )),
- (( !options.disabled && options.target )? ( ' target="' + options.target + '"' ):( '' )),
- ' href="', (( !options.disabled && options.href )?( options.href ):( 'javascript:void(0);' )), '">',
- // could go with something less specific here - like 'html'
- '<span class="fa ', options.faIcon, '"></span>',
- '</a>'
- ].join( '' );
- var $button = $( html ).tooltip( options.tooltipConfig );
- if( _.isFunction( options.onclick ) ){
- $button.click( options.onclick );
- }
- return $button;
-};
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/jq-plugins/ui/fa-icon-button.js
--- /dev/null
+++ b/static/scripts/packed/jq-plugins/ui/fa-icon-button.js
@@ -0,0 +1,1 @@
+(function(a,b){if(typeof define==="function"&&define.amd){define([],b)}else{a.faIconButton=b()}}(this,function(){var a=function(b){b=b||{};b.tooltipConfig=b.tooltipConfig||{placement:"bottom"};b.classes=["icon-btn"].concat(b.classes||[]);if(b.disabled){b.classes.push("disabled")}var c=['<a class="',b.classes.join(" "),'"',((b.title)?(' title="'+b.title+'"'):("")),((!b.disabled&&b.target)?(' target="'+b.target+'"'):("")),' href="',((!b.disabled&&b.href)?(b.href):("javascript:void(0);")),'">','<span class="fa ',b.faIcon,'"></span>',"</a>"].join("");var d=$(c).tooltip(b.tooltipConfig);if(_.isFunction(b.onclick)){d.click(b.onclick)}return d};return a}));
\ No newline at end of file
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/mvc/dataset/dataset-li-edit.js
--- a/static/scripts/packed/mvc/dataset/dataset-li-edit.js
+++ b/static/scripts/packed/mvc/dataset/dataset-li-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/states","mvc/dataset/dataset-li","mvc/tags","mvc/annotations","mvc/base-mvc","utils/localization"],function(b,h,g,e,c,d){var f=h.DatasetListItemView;var a=f.extend({initialize:function(i){f.prototype.initialize.call(this,i);this.hasUser=i.hasUser;this.purgeAllowed=i.purgeAllowed||false;this.tagsEditorShown=i.tagsEditorShown||false;this.annotationEditorShown=i.annotationEditorShown||false},_renderPrimaryActions:function(){var i=f.prototype._renderPrimaryActions.call(this);if(this.model.get("state")===b.NOT_VIEWABLE){return i}return f.prototype._renderPrimaryActions.call(this).concat([this._renderEditButton(),this._renderDeleteButton()])},_renderEditButton:function(){if((this.model.get("state")===b.DISCARDED)||(!this.model.get("accessible"))){return null}var k=this.model.get("purged"),i=this.model.get("deleted"),j={title:d("Edit attributes"),href:this.model.urls.edit,target:this.linkTarget,faIcon:"fa-pencil",classes:"edit-btn"};if(i||k){j.disabled=true;if(k){j.title=d("Cannot edit attributes of datasets removed from disk")}else{if(i){j.title=d("Undelete dataset to edit attributes")}}}else{if(_.contains([b.UPLOAD,b.NEW],this.model.get("state"))){j.disabled=true;j.title=d("This dataset is not yet editable")}}return faIconButton(j)},_renderDeleteButton:function(){if((!this.model.get("accessible"))){return null}var i=this,j=this.model.isDeletedOrPurged();return faIconButton({title:!j?d("Delete"):d("Dataset is already deleted"),disabled:j,faIcon:"fa-times",classes:"delete-btn",onclick:function(){i.$el.find(".icon-btn.delete-btn").trigger("mouseout");i.model["delete"]()}})},_renderDetails:function(){var i=f.prototype._renderDetails.call(this),j=this.model.get("state");if(!this.model.isDeletedOrPurged()&&_.contains([b.OK,b.FAILED_METADATA],j)){this._renderTags(i);this._renderAnnotation(i);this._makeDbkeyEditLink(i)}this._setUpBehaviors(i);return i},_renderSecondaryActions:function(){var i=f.prototype._renderSecondaryActions.call(this);switch(this.model.get("state")){case b.UPLOAD:case b.NEW:case b.NOT_VIEWABLE:return i;case b.ERROR:i.unshift(this._renderErrButton());return i.concat([this._renderRerunButton()]);case b.OK:case b.FAILED_METADATA:return i.concat([this._renderRerunButton(),this._renderVisualizationsButton()])}return i.concat([this._renderRerunButton()])},_renderErrButton:function(){return faIconButton({title:d("View or report this error"),href:this.model.urls.report_error,classes:"report-error-btn",target:this.linkTarget,faIcon:"fa-bug"})},_renderRerunButton:function(){return faIconButton({title:d("Run this job again"),href:this.model.urls.rerun,classes:"rerun-btn",target:this.linkTarget,faIcon:"fa-refresh"})},_renderVisualizationsButton:function(){var i=this.model.get("visualizations");if((this.model.isDeletedOrPurged())||(!this.hasUser)||(!this.model.hasData())||(_.isEmpty(i))){return null}if(!_.isObject(i[0])){this.warn("Visualizations have been switched off");return null}var j=$(this.templates.visualizations(i,this));j.find('[target="galaxy_main"]').attr("target",this.linkTarget);this._addScratchBookFn(j.find(".visualization-link").addBack(".visualization-link"));return j},_addScratchBookFn:function(j){var i=this;j.click(function(k){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Visualization",type:"url",content:$(this).attr("href")});k.preventDefault();k.stopPropagation()}})},_renderTags:function(i){if(!this.hasUser){return}var j=this;this.tagsEditor=new g.TagsEditor({model:this.model,el:i.find(".tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){j.tagsEditorShown=true},onhide:function(){j.tagsEditorShown=false},$activator:faIconButton({title:d("Edit dataset tags"),classes:"tag-btn",faIcon:"fa-tags"}).appendTo(i.find(".actions .right"))});if(this.tagsEditorShown){this.tagsEditor.toggle(true)}},_renderAnnotation:function(i){if(!this.hasUser){return}var j=this;this.annotationEditor=new e.AnnotationEditor({model:this.model,el:i.find(".annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){j.annotationEditorShown=true},onhide:function(){j.annotationEditorShown=false},$activator:faIconButton({title:d("Edit dataset annotation"),classes:"annotate-btn",faIcon:"fa-comment"}).appendTo(i.find(".actions .right"))});if(this.annotationEditorShown){this.annotationEditor.toggle(true)}},_makeDbkeyEditLink:function(i){if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){var j=$('<a class="value">?</a>').attr("href",this.model.urls.edit).attr("target",this.linkTarget);i.find(".dbkey .value").replaceWith(j)}},events:_.extend(_.clone(f.prototype.events),{"click .undelete-link":"_clickUndeleteLink","click .purge-link":"_clickPurgeLink","click .edit-btn":function(i){this.trigger("edit",this,i)},"click .delete-btn":function(i){this.trigger("delete",this,i)},"click .rerun-btn":function(i){this.trigger("rerun",this,i)},"click .report-err-btn":function(i){this.trigger("report-err",this,i)},"click .visualization-btn":function(i){this.trigger("visualize",this,i)},"click .dbkey a":function(i){this.trigger("edit",this,i)}}),_clickUndeleteLink:function(i){this.model.undelete();return false},_clickPurgeLink:function(i){this.model.purge();return false},toString:function(){var i=(this.model)?(this.model+""):("(no model)");return"HDAEditView("+i+")"}});a.prototype.templates=(function(){var j=_.extend({},f.prototype.templates.warnings,{failed_metadata:c.wrapTemplate(['<% if( dataset.state === "failed_metadata" ){ %>','<div class="failed_metadata-warning warningmessagesmall">',d("An error occurred setting the metadata for this dataset"),'<br /><a href="<%= dataset.urls.edit %>" target="<%= view.linkTarget %>">',d("Set it manually or retry auto-detection"),"</a>","</div>","<% } %>"],"dataset"),deleted:c.wrapTemplate(["<% if( dataset.deleted && !dataset.purged ){ %>",'<div class="deleted-msg warningmessagesmall">',d("This dataset has been deleted"),'<br /><a class="undelete-link" href="javascript:void(0);">',d("Undelete it"),"</a>","<% if( view.purgeAllowed ){ %>",'<br /><a class="purge-link" href="javascript:void(0);">',d("Permanently remove it from disk"),"</a>","<% } %>","</div>","<% } %>"],"dataset")});var i=c.wrapTemplate(["<% if( visualizations.length === 1 ){ %>",'<a class="visualization-btn visualization-link icon-btn" href="<%= visualizations[0].href %>"',' target="<%= visualizations[0].target %>" title="',d("Visualize in"),' <%= visualizations[0].html %>">','<span class="fa fa-bar-chart-o"></span>',"</a>","<% } else { %>",'<div class="visualizations-dropdown dropdown">','<a class="visualization-btn icon-btn" data-toggle="dropdown" title="',d("Visualize"),'">','<span class="fa fa-bar-chart-o"></span>',"</a>",'<ul class="dropdown-menu" role="menu">',"<% _.each( visualizations, function( visualization ){ %>",'<li><a class="visualization-link" href="<%= visualization.href %>"',' target="<%= visualization.target %>">',"<%= visualization.html %>","</a></li>","<% }); %>","</ul>","</div>","<% } %>"],"visualizations");return _.extend({},f.prototype.templates,{warnings:j,visualizations:i})}());return{DatasetListItemEdit:a}});
\ No newline at end of file
+define(["mvc/dataset/states","mvc/dataset/dataset-li","mvc/tags","mvc/annotations","jq-plugins/ui/fa-icon-button","mvc/base-mvc","utils/localization"],function(g,d,e,b,a,i,c){var f=d.DatasetListItemView;var h=f.extend({initialize:function(j){f.prototype.initialize.call(this,j);this.hasUser=j.hasUser;this.purgeAllowed=j.purgeAllowed||false;this.tagsEditorShown=j.tagsEditorShown||false;this.annotationEditorShown=j.annotationEditorShown||false},_renderPrimaryActions:function(){var j=f.prototype._renderPrimaryActions.call(this);if(this.model.get("state")===g.NOT_VIEWABLE){return j}return f.prototype._renderPrimaryActions.call(this).concat([this._renderEditButton(),this._renderDeleteButton()])},_renderEditButton:function(){if((this.model.get("state")===g.DISCARDED)||(!this.model.get("accessible"))){return null}var l=this.model.get("purged"),j=this.model.get("deleted"),k={title:c("Edit attributes"),href:this.model.urls.edit,target:this.linkTarget,faIcon:"fa-pencil",classes:"edit-btn"};if(j||l){k.disabled=true;if(l){k.title=c("Cannot edit attributes of datasets removed from disk")}else{if(j){k.title=c("Undelete dataset to edit attributes")}}}else{if(_.contains([g.UPLOAD,g.NEW],this.model.get("state"))){k.disabled=true;k.title=c("This dataset is not yet editable")}}return a(k)},_renderDeleteButton:function(){if((!this.model.get("accessible"))){return null}var j=this,k=this.model.isDeletedOrPurged();return a({title:!k?c("Delete"):c("Dataset is already deleted"),disabled:k,faIcon:"fa-times",classes:"delete-btn",onclick:function(){j.$el.find(".icon-btn.delete-btn").trigger("mouseout");j.model["delete"]()}})},_renderDetails:function(){var j=f.prototype._renderDetails.call(this),k=this.model.get("state");if(!this.model.isDeletedOrPurged()&&_.contains([g.OK,g.FAILED_METADATA],k)){this._renderTags(j);this._renderAnnotation(j);this._makeDbkeyEditLink(j)}this._setUpBehaviors(j);return j},_renderSecondaryActions:function(){var j=f.prototype._renderSecondaryActions.call(this);switch(this.model.get("state")){case g.UPLOAD:case g.NEW:case g.NOT_VIEWABLE:return j;case g.ERROR:j.unshift(this._renderErrButton());return j.concat([this._renderRerunButton()]);case g.OK:case g.FAILED_METADATA:return j.concat([this._renderRerunButton(),this._renderVisualizationsButton()])}return j.concat([this._renderRerunButton()])},_renderErrButton:function(){return a({title:c("View or report this error"),href:this.model.urls.report_error,classes:"report-error-btn",target:this.linkTarget,faIcon:"fa-bug"})},_renderRerunButton:function(){return a({title:c("Run this job again"),href:this.model.urls.rerun,classes:"rerun-btn",target:this.linkTarget,faIcon:"fa-refresh"})},_renderVisualizationsButton:function(){var j=this.model.get("visualizations");if((this.model.isDeletedOrPurged())||(!this.hasUser)||(!this.model.hasData())||(_.isEmpty(j))){return null}if(!_.isObject(j[0])){this.warn("Visualizations have been switched off");return null}var k=$(this.templates.visualizations(j,this));k.find('[target="galaxy_main"]').attr("target",this.linkTarget);this._addScratchBookFn(k.find(".visualization-link").addBack(".visualization-link"));return k},_addScratchBookFn:function(k){var j=this;k.click(function(l){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add({title:"Visualization",type:"url",content:$(this).attr("href")});l.preventDefault();l.stopPropagation()}})},_renderTags:function(j){if(!this.hasUser){return}var k=this;this.tagsEditor=new e.TagsEditor({model:this.model,el:j.find(".tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){k.tagsEditorShown=true},onhide:function(){k.tagsEditorShown=false},$activator:a({title:c("Edit dataset tags"),classes:"tag-btn",faIcon:"fa-tags"}).appendTo(j.find(".actions .right"))});if(this.tagsEditorShown){this.tagsEditor.toggle(true)}},_renderAnnotation:function(j){if(!this.hasUser){return}var k=this;this.annotationEditor=new b.AnnotationEditor({model:this.model,el:j.find(".annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){k.annotationEditorShown=true},onhide:function(){k.annotationEditorShown=false},$activator:a({title:c("Edit dataset annotation"),classes:"annotate-btn",faIcon:"fa-comment"}).appendTo(j.find(".actions .right"))});if(this.annotationEditorShown){this.annotationEditor.toggle(true)}},_makeDbkeyEditLink:function(j){if(this.model.get("metadata_dbkey")==="?"&&!this.model.isDeletedOrPurged()){var k=$('<a class="value">?</a>').attr("href",this.model.urls.edit).attr("target",this.linkTarget);j.find(".dbkey .value").replaceWith(k)}},events:_.extend(_.clone(f.prototype.events),{"click .undelete-link":"_clickUndeleteLink","click .purge-link":"_clickPurgeLink","click .edit-btn":function(j){this.trigger("edit",this,j)},"click .delete-btn":function(j){this.trigger("delete",this,j)},"click .rerun-btn":function(j){this.trigger("rerun",this,j)},"click .report-err-btn":function(j){this.trigger("report-err",this,j)},"click .visualization-btn":function(j){this.trigger("visualize",this,j)},"click .dbkey a":function(j){this.trigger("edit",this,j)}}),_clickUndeleteLink:function(j){this.model.undelete();return false},_clickPurgeLink:function(j){this.model.purge();return false},toString:function(){var j=(this.model)?(this.model+""):("(no model)");return"HDAEditView("+j+")"}});h.prototype.templates=(function(){var k=_.extend({},f.prototype.templates.warnings,{failed_metadata:i.wrapTemplate(['<% if( dataset.state === "failed_metadata" ){ %>','<div class="failed_metadata-warning warningmessagesmall">',c("An error occurred setting the metadata for this dataset"),'<br /><a href="<%= dataset.urls.edit %>" target="<%= view.linkTarget %>">',c("Set it manually or retry auto-detection"),"</a>","</div>","<% } %>"],"dataset"),deleted:i.wrapTemplate(["<% if( dataset.deleted && !dataset.purged ){ %>",'<div class="deleted-msg warningmessagesmall">',c("This dataset has been deleted"),'<br /><a class="undelete-link" href="javascript:void(0);">',c("Undelete it"),"</a>","<% if( view.purgeAllowed ){ %>",'<br /><a class="purge-link" href="javascript:void(0);">',c("Permanently remove it from disk"),"</a>","<% } %>","</div>","<% } %>"],"dataset")});var j=i.wrapTemplate(["<% if( visualizations.length === 1 ){ %>",'<a class="visualization-btn visualization-link icon-btn" href="<%= visualizations[0].href %>"',' target="<%= visualizations[0].target %>" title="',c("Visualize in"),' <%= visualizations[0].html %>">','<span class="fa fa-bar-chart-o"></span>',"</a>","<% } else { %>",'<div class="visualizations-dropdown dropdown">','<a class="visualization-btn icon-btn" data-toggle="dropdown" title="',c("Visualize"),'">','<span class="fa fa-bar-chart-o"></span>',"</a>",'<ul class="dropdown-menu" role="menu">',"<% _.each( visualizations, function( visualization ){ %>",'<li><a class="visualization-link" href="<%= visualization.href %>"',' target="<%= visualization.target %>">',"<%= visualization.html %>","</a></li>","<% }); %>","</ul>","</div>","<% } %>"],"visualizations");return _.extend({},f.prototype.templates,{warnings:k,visualizations:j})}());return{DatasetListItemEdit:h}});
\ No newline at end of file
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/mvc/dataset/dataset-li.js
--- a/static/scripts/packed/mvc/dataset/dataset-li.js
+++ b/static/scripts/packed/mvc/dataset/dataset-li.js
@@ -1,1 +1,1 @@
-define(["mvc/list/list-item","mvc/dataset/states","mvc/base-mvc","utils/localization"],function(d,a,b,c){var f=d.ListItemView;var e=f.extend({className:f.prototype.className+" dataset",id:function(){return["dataset",this.model.get("id")].join("-")},initialize:function(g){if(g.logger){this.logger=this.model.logger=g.logger}this.log(this+".initialize:",g);f.prototype.initialize.call(this,g);this.linkTarget=g.linkTarget||"_blank";this._setUpListeners()},_setUpListeners:function(){f.prototype._setUpListeners.call(this);this.model.on("change",function(h,g){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},_fetchModelDetails:function(){var g=this;if(g.model.inReadyState()&&!g.model.hasDetails()){return g.model.fetch({silent:true})}return jQuery.when()},remove:function(h,i){var g=this;h=h||this.fxSpeed;this.$el.fadeOut(h,function(){Backbone.View.prototype.remove.call(g);if(i){i.call(g)}})},render:function(g){return f.prototype.render.call(this,g)},_swapNewRender:function(g){f.prototype._swapNewRender.call(this,g);if(this.model.has("state")){this.$el.addClass("state-"+this.model.get("state"))}return this.$el},_renderPrimaryActions:function(){return[this._renderDisplayButton()]},_renderDisplayButton:function(){var i=this.model.get("state");if((i===a.NOT_VIEWABLE)||(i===a.DISCARDED)||(!this.model.get("accessible"))){return null}var h={target:this.linkTarget,classes:"display-btn"};if(this.model.get("purged")){h.disabled=true;h.title=c("Cannot display datasets removed from disk")}else{if(i===a.UPLOAD){h.disabled=true;h.title=c("This dataset must finish uploading before it can be viewed")}else{if(i===a.NEW){h.disabled=true;h.title=c("This dataset is not yet viewable")}else{h.title=c("View data");h.href=this.model.urls.display;var g=this;h.onclick=function(j){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add_dataset(g.model.get("id"));j.preventDefault()}}}}}h.faIcon="fa-eye";return faIconButton(h)},_renderDetails:function(){if(this.model.get("state")===a.NOT_VIEWABLE){return $(this.templates.noAccess(this.model.toJSON(),this))}var g=f.prototype._renderDetails.call(this);g.find(".actions .left").empty().append(this._renderSecondaryActions());g.find(".summary").html(this._renderSummary()).prepend(this._renderDetailMessages());g.find(".display-applications").html(this._renderDisplayApplications());this._setUpBehaviors(g);return g},_renderSummary:function(){var g=this.model.toJSON(),h=this.templates.summaries[g.state];h=h||this.templates.summaries.unknown;return h(g,this)},_renderDetailMessages:function(){var g=this,i=$('<div class="detail-messages"></div>'),h=g.model.toJSON();_.each(g.templates.detailMessages,function(j){i.append($(j(h,g)))});return i},_renderDisplayApplications:function(){if(this.model.isDeletedOrPurged()){return""}return[this.templates.displayApplications(this.model.get("display_apps"),this),this.templates.displayApplications(this.model.get("display_types"),this)].join("")},_renderSecondaryActions:function(){this.debug("_renderSecondaryActions");switch(this.model.get("state")){case a.NOT_VIEWABLE:return[];case a.OK:case a.FAILED_METADATA:case a.ERROR:return[this._renderDownloadButton(),this._renderShowParamsButton()]}return[this._renderShowParamsButton()]},_renderShowParamsButton:function(){return faIconButton({title:c("View details"),classes:"params-btn",href:this.model.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_renderDownloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}if(!_.isEmpty(this.model.get("meta_files"))){return this._renderMetaFileDownloadButton()}return $(['<a class="download-btn icon-btn" href="',this.model.urls.download,'" title="'+c("Download")+'">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))},_renderMetaFileDownloadButton:function(){var g=this.model.urls;return $(['<div class="metafile-dropdown dropdown">','<a class="download-btn icon-btn" href="javascript:void(0)" data-toggle="dropdown"',' title="'+c("Download")+'">','<span class="fa fa-floppy-o"></span>',"</a>",'<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">','<li><a href="'+g.download+'">',c("Download dataset"),"</a></li>",_.map(this.model.get("meta_files"),function(h){return['<li><a href="',g.meta_download+h.file_type,'">',c("Download")," ",h.file_type,"</a></li>"].join("")}).join("\n"),"</ul>","</div>"].join("\n"))},events:_.extend(_.clone(f.prototype.events),{"click .display-btn":function(g){this.trigger("display",this,g)},"click .params-btn":function(g){this.trigger("params",this,g)},"click .download-btn":function(g){this.trigger("download",this,g)}}),toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"DatasetListItemView("+g+")"}});e.prototype.templates=(function(){var i=_.extend({},f.prototype.templates.warnings,{failed_metadata:b.wrapTemplate(['<% if( model.state === "failed_metadata" ){ %>','<div class="warningmessagesmall">',c("An error occurred setting the metadata for this dataset"),"</div>","<% } %>"]),error:b.wrapTemplate(["<% if( model.error ){ %>",'<div class="errormessagesmall">',c("There was an error getting the data for this dataset"),": <%- model.error %>","</div>","<% } %>"]),purged:b.wrapTemplate(["<% if( model.purged ){ %>",'<div class="purged-msg warningmessagesmall">',c("This dataset has been deleted and removed from disk"),"</div>","<% } %>"]),deleted:b.wrapTemplate(["<% if( model.deleted && !model.purged ){ %>",'<div class="deleted-msg warningmessagesmall">',c("This dataset has been deleted"),"</div>","<% } %>"])});var j=b.wrapTemplate(['<div class="details">','<div class="summary"></div>','<div class="actions clear">','<div class="left"></div>','<div class="right"></div>',"</div>","<% if( !dataset.deleted && !dataset.purged ){ %>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="display-applications"></div>',"<% if( dataset.peek ){ %>",'<pre class="dataset-peek"><%= dataset.peek %></pre>',"<% } %>","<% } %>","</div>"],"dataset");var h=b.wrapTemplate(['<div class="details">','<div class="summary">',c("You do not have permission to view this dataset"),"</div>","</div>"],"dataset");var k={};k[a.OK]=k[a.FAILED_METADATA]=b.wrapTemplate(["<% if( dataset.misc_blurb ){ %>",'<div class="blurb">','<span class="value"><%- dataset.misc_blurb %></span>',"</div>","<% } %>","<% if( dataset.file_ext ){ %>",'<div class="datatype">','<label class="prompt">',c("format"),"</label>",'<span class="value"><%- dataset.file_ext %></span>',"</div>","<% } %>","<% if( dataset.metadata_dbkey ){ %>",'<div class="dbkey">','<label class="prompt">',c("database"),"</label>",'<span class="value">',"<%- dataset.metadata_dbkey %>","</span>","</div>","<% } %>","<% if( dataset.misc_info ){ %>",'<div class="info">','<span class="value"><%- dataset.misc_info %></span>',"</div>","<% } %>"],"dataset");k[a.NEW]=b.wrapTemplate(["<div>",c("This is a new dataset and not all of its data are available yet"),"</div>"],"dataset");k[a.NOT_VIEWABLE]=b.wrapTemplate(["<div>",c("You do not have permission to view this dataset"),"</div>"],"dataset");k[a.DISCARDED]=b.wrapTemplate(["<div>",c("The job creating this dataset was cancelled before completion"),"</div>"],"dataset");k[a.QUEUED]=b.wrapTemplate(["<div>",c("This job is waiting to run"),"</div>"],"dataset");k[a.RUNNING]=b.wrapTemplate(["<div>",c("This job is currently running"),"</div>"],"dataset");k[a.UPLOAD]=b.wrapTemplate(["<div>",c("This dataset is currently uploading"),"</div>"],"dataset");k[a.SETTING_METADATA]=b.wrapTemplate(["<div>",c("Metadata is being auto-detected"),"</div>"],"dataset");k[a.PAUSED]=b.wrapTemplate(["<div>",c('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume'),"</div>"],"dataset");k[a.ERROR]=b.wrapTemplate(["<% if( !dataset.purged ){ %>","<div><%- dataset.misc_blurb %></div>","<% } %>",'<span class="help-text">',c("An error occurred with this dataset"),":</span>",'<div class="job-error-text"><%- dataset.misc_info %></div>'],"dataset");k[a.EMPTY]=b.wrapTemplate(["<div>",c("No data"),": <i><%- dataset.misc_blurb %></i></div>"],"dataset");k.unknown=b.wrapTemplate(['<div>Error: unknown dataset state: "<%- dataset.state %>"</div>'],"dataset");var l={resubmitted:b.wrapTemplate(["<% if( model.resubmitted ){ %>",'<div class="resubmitted-msg infomessagesmall">',c("The job creating this dataset has been resubmitted"),"</div>","<% } %>"])};var g=b.wrapTemplate(["<% _.each( apps, function( app ){ %>",'<div class="display-application">','<span class="display-application-location"><%- app.label %></span> ','<span class="display-application-links">',"<% _.each( app.links, function( link ){ %>",'<a target="<%= link.target %>" href="<%= link.href %>">',"<% print( _l( link.text ) ); %>","</a> ","<% }); %>","</span>","</div>","<% }); %>"],"apps");return _.extend({},f.prototype.templates,{warnings:i,details:j,noAccess:h,summaries:k,detailMessages:l,displayApplications:g})}());return{DatasetListItemView:e}});
\ No newline at end of file
+define(["mvc/list/list-item","mvc/dataset/states","jq-plugins/ui/fa-icon-button","mvc/base-mvc","utils/localization"],function(d,a,e,b,c){var g=d.ListItemView;var f=g.extend({className:g.prototype.className+" dataset",id:function(){return["dataset",this.model.get("id")].join("-")},initialize:function(h){if(h.logger){this.logger=this.model.logger=h.logger}this.log(this+".initialize:",h);g.prototype.initialize.call(this,h);this.linkTarget=h.linkTarget||"_blank";this._setUpListeners()},_setUpListeners:function(){g.prototype._setUpListeners.call(this);this.model.on("change",function(i,h){if(this.model.changedAttributes().state&&this.model.inReadyState()&&this.expanded&&!this.model.hasDetails()){this.model.fetch()}else{this.render()}},this)},_fetchModelDetails:function(){var h=this;if(h.model.inReadyState()&&!h.model.hasDetails()){return h.model.fetch({silent:true})}return jQuery.when()},remove:function(i,j){var h=this;i=i||this.fxSpeed;this.$el.fadeOut(i,function(){Backbone.View.prototype.remove.call(h);if(j){j.call(h)}})},render:function(h){return g.prototype.render.call(this,h)},_swapNewRender:function(h){g.prototype._swapNewRender.call(this,h);if(this.model.has("state")){this.$el.addClass("state-"+this.model.get("state"))}return this.$el},_renderPrimaryActions:function(){return[this._renderDisplayButton()]},_renderDisplayButton:function(){var j=this.model.get("state");if((j===a.NOT_VIEWABLE)||(j===a.DISCARDED)||(!this.model.get("accessible"))){return null}var i={target:this.linkTarget,classes:"display-btn"};if(this.model.get("purged")){i.disabled=true;i.title=c("Cannot display datasets removed from disk")}else{if(j===a.UPLOAD){i.disabled=true;i.title=c("This dataset must finish uploading before it can be viewed")}else{if(j===a.NEW){i.disabled=true;i.title=c("This dataset is not yet viewable")}else{i.title=c("View data");i.href=this.model.urls.display;var h=this;i.onclick=function(k){if(Galaxy.frame&&Galaxy.frame.active){Galaxy.frame.add_dataset(h.model.get("id"));k.preventDefault()}}}}}i.faIcon="fa-eye";return e(i)},_renderDetails:function(){if(this.model.get("state")===a.NOT_VIEWABLE){return $(this.templates.noAccess(this.model.toJSON(),this))}var h=g.prototype._renderDetails.call(this);h.find(".actions .left").empty().append(this._renderSecondaryActions());h.find(".summary").html(this._renderSummary()).prepend(this._renderDetailMessages());h.find(".display-applications").html(this._renderDisplayApplications());this._setUpBehaviors(h);return h},_renderSummary:function(){var h=this.model.toJSON(),i=this.templates.summaries[h.state];i=i||this.templates.summaries.unknown;return i(h,this)},_renderDetailMessages:function(){var h=this,j=$('<div class="detail-messages"></div>'),i=h.model.toJSON();_.each(h.templates.detailMessages,function(k){j.append($(k(i,h)))});return j},_renderDisplayApplications:function(){if(this.model.isDeletedOrPurged()){return""}return[this.templates.displayApplications(this.model.get("display_apps"),this),this.templates.displayApplications(this.model.get("display_types"),this)].join("")},_renderSecondaryActions:function(){this.debug("_renderSecondaryActions");switch(this.model.get("state")){case a.NOT_VIEWABLE:return[];case a.OK:case a.FAILED_METADATA:case a.ERROR:return[this._renderDownloadButton(),this._renderShowParamsButton()]}return[this._renderShowParamsButton()]},_renderShowParamsButton:function(){return e({title:c("View details"),classes:"params-btn",href:this.model.urls.show_params,target:this.linkTarget,faIcon:"fa-info-circle"})},_renderDownloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}if(!_.isEmpty(this.model.get("meta_files"))){return this._renderMetaFileDownloadButton()}return $(['<a class="download-btn icon-btn" href="',this.model.urls.download,'" title="'+c("Download")+'">','<span class="fa fa-floppy-o"></span>',"</a>"].join(""))},_renderMetaFileDownloadButton:function(){var h=this.model.urls;return $(['<div class="metafile-dropdown dropdown">','<a class="download-btn icon-btn" href="javascript:void(0)" data-toggle="dropdown"',' title="'+c("Download")+'">','<span class="fa fa-floppy-o"></span>',"</a>",'<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">','<li><a href="'+h.download+'">',c("Download dataset"),"</a></li>",_.map(this.model.get("meta_files"),function(i){return['<li><a href="',h.meta_download+i.file_type,'">',c("Download")," ",i.file_type,"</a></li>"].join("")}).join("\n"),"</ul>","</div>"].join("\n"))},events:_.extend(_.clone(g.prototype.events),{"click .display-btn":function(h){this.trigger("display",this,h)},"click .params-btn":function(h){this.trigger("params",this,h)},"click .download-btn":function(h){this.trigger("download",this,h)}}),toString:function(){var h=(this.model)?(this.model+""):("(no model)");return"DatasetListItemView("+h+")"}});f.prototype.templates=(function(){var j=_.extend({},g.prototype.templates.warnings,{failed_metadata:b.wrapTemplate(['<% if( model.state === "failed_metadata" ){ %>','<div class="warningmessagesmall">',c("An error occurred setting the metadata for this dataset"),"</div>","<% } %>"]),error:b.wrapTemplate(["<% if( model.error ){ %>",'<div class="errormessagesmall">',c("There was an error getting the data for this dataset"),": <%- model.error %>","</div>","<% } %>"]),purged:b.wrapTemplate(["<% if( model.purged ){ %>",'<div class="purged-msg warningmessagesmall">',c("This dataset has been deleted and removed from disk"),"</div>","<% } %>"]),deleted:b.wrapTemplate(["<% if( model.deleted && !model.purged ){ %>",'<div class="deleted-msg warningmessagesmall">',c("This dataset has been deleted"),"</div>","<% } %>"])});var k=b.wrapTemplate(['<div class="details">','<div class="summary"></div>','<div class="actions clear">','<div class="left"></div>','<div class="right"></div>',"</div>","<% if( !dataset.deleted && !dataset.purged ){ %>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="display-applications"></div>',"<% if( dataset.peek ){ %>",'<pre class="dataset-peek"><%= dataset.peek %></pre>',"<% } %>","<% } %>","</div>"],"dataset");var i=b.wrapTemplate(['<div class="details">','<div class="summary">',c("You do not have permission to view this dataset"),"</div>","</div>"],"dataset");var l={};l[a.OK]=l[a.FAILED_METADATA]=b.wrapTemplate(["<% if( dataset.misc_blurb ){ %>",'<div class="blurb">','<span class="value"><%- dataset.misc_blurb %></span>',"</div>","<% } %>","<% if( dataset.file_ext ){ %>",'<div class="datatype">','<label class="prompt">',c("format"),"</label>",'<span class="value"><%- dataset.file_ext %></span>',"</div>","<% } %>","<% if( dataset.metadata_dbkey ){ %>",'<div class="dbkey">','<label class="prompt">',c("database"),"</label>",'<span class="value">',"<%- dataset.metadata_dbkey %>","</span>","</div>","<% } %>","<% if( dataset.misc_info ){ %>",'<div class="info">','<span class="value"><%- dataset.misc_info %></span>',"</div>","<% } %>"],"dataset");l[a.NEW]=b.wrapTemplate(["<div>",c("This is a new dataset and not all of its data are available yet"),"</div>"],"dataset");l[a.NOT_VIEWABLE]=b.wrapTemplate(["<div>",c("You do not have permission to view this dataset"),"</div>"],"dataset");l[a.DISCARDED]=b.wrapTemplate(["<div>",c("The job creating this dataset was cancelled before completion"),"</div>"],"dataset");l[a.QUEUED]=b.wrapTemplate(["<div>",c("This job is waiting to run"),"</div>"],"dataset");l[a.RUNNING]=b.wrapTemplate(["<div>",c("This job is currently running"),"</div>"],"dataset");l[a.UPLOAD]=b.wrapTemplate(["<div>",c("This dataset is currently uploading"),"</div>"],"dataset");l[a.SETTING_METADATA]=b.wrapTemplate(["<div>",c("Metadata is being auto-detected"),"</div>"],"dataset");l[a.PAUSED]=b.wrapTemplate(["<div>",c('This job is paused. Use the "Resume Paused Jobs" in the history menu to resume'),"</div>"],"dataset");l[a.ERROR]=b.wrapTemplate(["<% if( !dataset.purged ){ %>","<div><%- dataset.misc_blurb %></div>","<% } %>",'<span class="help-text">',c("An error occurred with this dataset"),":</span>",'<div class="job-error-text"><%- dataset.misc_info %></div>'],"dataset");l[a.EMPTY]=b.wrapTemplate(["<div>",c("No data"),": <i><%- dataset.misc_blurb %></i></div>"],"dataset");l.unknown=b.wrapTemplate(['<div>Error: unknown dataset state: "<%- dataset.state %>"</div>'],"dataset");var m={resubmitted:b.wrapTemplate(["<% if( model.resubmitted ){ %>",'<div class="resubmitted-msg infomessagesmall">',c("The job creating this dataset has been resubmitted"),"</div>","<% } %>"])};var h=b.wrapTemplate(["<% _.each( apps, function( app ){ %>",'<div class="display-application">','<span class="display-application-location"><%- app.label %></span> ','<span class="display-application-links">',"<% _.each( app.links, function( link ){ %>",'<a target="<%= link.target %>" href="<%= link.href %>">',"<% print( _l( link.text ) ); %>","</a> ","<% }); %>","</span>","</div>","<% }); %>"],"apps");return _.extend({},g.prototype.templates,{warnings:j,details:k,noAccess:i,summaries:l,detailMessages:m,displayApplications:h})}());return{DatasetListItemView:f}});
\ No newline at end of file
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/mvc/history/hdca-li-edit.js
--- a/static/scripts/packed/mvc/history/hdca-li-edit.js
+++ b/static/scripts/packed/mvc/history/hdca-li-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/dataset/states","mvc/history/hdca-li","utils/localization"],function(a,e,b){var c=e.HDCAListItemView;var d=c.extend({_renderPrimaryActions:function(){this.log(this+"._renderPrimaryActions");return c.prototype._renderPrimaryActions.call(this).concat([this._renderDeleteButton()])},_renderDeleteButton:function(){var g=this,f=this.model.get("deleted");return faIconButton({title:f?b("Dataset collection is already deleted"):b("Delete"),classes:"delete-btn",faIcon:"fa-times",disabled:f,onclick:function(){g.$el.find(".icon-btn.delete-btn").trigger("mouseout");g.model["delete"]()}})},toString:function(){var f=(this.model)?(this.model+""):("(no model)");return"HDCAListItemEdit("+f+")"}});return{HDCAListItemEdit:d}});
\ No newline at end of file
+define(["mvc/dataset/states","mvc/history/hdca-li","jq-plugins/ui/fa-icon-button","utils/localization"],function(a,f,c,b){var d=f.HDCAListItemView;var e=d.extend({_renderPrimaryActions:function(){this.log(this+"._renderPrimaryActions");return d.prototype._renderPrimaryActions.call(this).concat([this._renderDeleteButton()])},_renderDeleteButton:function(){var h=this,g=this.model.get("deleted");return c({title:g?b("Dataset collection is already deleted"):b("Delete"),classes:"delete-btn",faIcon:"fa-times",disabled:g,onclick:function(){h.$el.find(".icon-btn.delete-btn").trigger("mouseout");h.model["delete"]()}})},toString:function(){var g=(this.model)?(this.model+""):("(no model)");return"HDCAListItemEdit("+g+")"}});return{HDCAListItemEdit:e}});
\ No newline at end of file
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/mvc/history/history-panel-edit.js
--- a/static/scripts/packed/mvc/history/history-panel-edit.js
+++ b/static/scripts/packed/mvc/history/history-panel-edit.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-panel","mvc/history/history-contents","mvc/dataset/states","mvc/history/hda-model","mvc/history/hda-li-edit","mvc/history/hdca-li-edit","mvc/tags","mvc/annotations","utils/localization"],function(f,h,k,d,c,g,j,a,b){var i=f.HistoryPanel;var e=i.extend({HDAViewClass:c.HDAListItemEdit,HDCAViewClass:g.HDCAListItemEdit,initialize:function(l){l=l||{};i.prototype.initialize.call(this,l);this.tagsEditor=null;this.annotationEditor=null;this.purgeAllowed=l.purgeAllowed||false;this.annotationEditorShown=l.annotationEditorShown||false;this.tagsEditorShown=l.tagsEditorShown||false;this.multiselectActions=l.multiselectActions||this._getActions()},_setUpListeners:function(){i.prototype._setUpListeners.call(this);this.on("drop",function(l,m){this.dataDropped(m);this.dropTargetOff()})},_setUpCollectionListeners:function(){i.prototype._setUpCollectionListeners.call(this);this.collection.on("change:deleted",this._handleHdaDeletionChange,this);this.collection.on("change:visible",this._handleHdaVisibleChange,this);this.collection.on("change:purged",function(l){this.model.fetch()},this);return this},_setUpModelListeners:function(){i.prototype._setUpModelListeners.call(this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);return this},_buildNewRender:function(){var l=i.prototype._buildNewRender.call(this);if(!this.model){return l}if(Galaxy&&Galaxy.currUser&&Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(l);this._renderAnnotation(l)}return l},renderItems:function(m){var l=i.prototype.renderItems.call(this,m);this._renderCounts(m);return l},_renderCounts:function(n){function m(q,r){return['<a class="',q,'" href="javascript:void(0);">',r,"</a>"].join("")}n=n||this.$el;var l=this.collection.where({deleted:true}),p=this.collection.where({visible:false}),o=[];if(this.views.length){o.push([this.views.length,b("shown")].join(" "))}if(l.length){o.push((!this.showDeleted)?([l.length,m("toggle-deleted-link",b("deleted"))].join(" ")):(m("toggle-deleted-link",b("hide deleted"))))}if(p.length){o.push((!this.showHidden)?([p.length,m("toggle-hidden-link",b("hidden"))].join(" ")):(m("toggle-hidden-link",b("hide hidden"))))}return n.find("> .controls .subtitle").html(o.join(", "))},_renderTags:function(l){var m=this;this.tagsEditor=new j.TagsEditor({model:this.model,el:l.find(".controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){m.toggleHDATagEditors(true,m.fxSpeed)},onhide:function(){m.toggleHDATagEditors(false,m.fxSpeed)},$activator:faIconButton({title:b("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(l.find(".controls .actions"))})},_renderAnnotation:function(l){var m=this;this.annotationEditor=new a.AnnotationEditor({model:this.model,el:l.find(".controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){m.toggleHDAAnnotationEditors(true,m.fxSpeed)},onhide:function(){m.toggleHDAAnnotationEditors(false,m.fxSpeed)},$activator:faIconButton({title:b("Edit history annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(l.find(".controls .actions"))})},_setUpBehaviors:function(l){l=l||this.$el;i.prototype._setUpBehaviors.call(this,l);if(!this.model){return}if(this.multiselectActions.length){this.actionsPopup=new PopupMenu(l.find(".list-action-popup-btn"),this.multiselectActions)}if((!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var m=this,n=".controls .name";l.find(n).attr("title",b("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(o){var p=m.model.get("name");if(o&&o!==p){m.$el.find(n).text(o);m.model.save({name:o}).fail(function(){m.$el.find(n).text(m.model.previous("name"))})}else{m.$el.find(n).text(p)}}})},_getActions:function(){var l=this,m=[{html:b("Hide datasets"),func:function(){var n=d.HistoryDatasetAssociation.prototype.hide;l.getSelectedModels().ajaxQueue(n)}},{html:b("Unhide datasets"),func:function(){var n=d.HistoryDatasetAssociation.prototype.unhide;l.getSelectedModels().ajaxQueue(n)}},{html:b("Delete datasets"),func:function(){var n=d.HistoryDatasetAssociation.prototype["delete"];l.getSelectedModels().ajaxQueue(n)}},{html:b("Undelete datasets"),func:function(){var n=d.HistoryDatasetAssociation.prototype.undelete;l.getSelectedModels().ajaxQueue(n)}}];if(l.purgeAllowed){m.push({html:b("Permanently delete datasets"),func:function(){if(confirm(b("This will permanently remove the data in your datasets. Are you sure?"))){var n=d.HistoryDatasetAssociation.prototype.purge;l.getSelectedModels().ajaxQueue(n)}}})}m.push({html:b("Build Dataset List"),func:function(){l.getSelectedModels().promoteToHistoryDatasetCollection(l.model,"list")}});m.push({html:b("Build Dataset Pair"),func:function(){l.getSelectedModels().promoteToHistoryDatasetCollection(l.model,"paired")}});m.push({html:b("Build List of Dataset Pairs"),func:_.bind(l._showPairedCollectionModal,l)});return m},_showPairedCollectionModal:function(){var l=this,m=l.getSelectedModels().toJSON().filter(function(n){return n.history_content_type==="dataset"&&n.state===k.OK});if(m.length){require(["mvc/collection/paired-collection-creator"],function(n){window.creator=n.pairedCollectionCreatorModal(m,{historyId:l.model.id})})}else{}},_attachItems:function(l){this.$list(l).append(this.views.reverse().map(function(m){return m.$el}));return this},_attachView:function(m){var l=this;l.views.unshift(m);l.$list().prepend(m.render(0).$el.hide());m.$el.slideDown(l.fxSpeed)},_getItemViewOptions:function(m){var l=i.prototype._getItemViewOptions.call(this,m);_.extend(l,{purgeAllowed:this.purgeAllowed,tagsEditorShown:(this.tagsEditor&&!this.tagsEditor.hidden),annotationEditorShown:(this.annotationEditor&&!this.annotationEditor.hidden)});return l},_handleHdaDeletionChange:function(l){if(l.get("deleted")&&!this.showDeleted){this.removeItemView(l)}this._renderCounts()},_handleHdaVisibleChange:function(l){if(l.hidden()&&!this.storage.showHidden){this.removeItemView(l)}this._renderCounts()},toggleHDATagEditors:function(l){var m=Array.prototype.slice.call(arguments,1);_.each(this.views,function(n){if(n.tagsEditor){n.tagsEditor.toggle.apply(n.tagsEditor,m)}})},toggleHDAAnnotationEditors:function(l){var m=Array.prototype.slice.call(arguments,1);_.each(this.views,function(n){if(n.annotationEditor){n.annotationEditor.toggle.apply(n.annotationEditor,m)}})},events:_.extend(_.clone(i.prototype.events),{"click .show-selectors-btn":"toggleSelectors","click .toggle-deleted-link":function(l){this.toggleShowDeleted()},"click .toggle-hidden-link":function(l){this.toggleShowHidden()}}),updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},dropTargetOn:function(){if(this.dropTarget){return this}this.dropTarget=true;var m={dragenter:_.bind(this.dragenter,this),dragover:_.bind(this.dragover,this),dragleave:_.bind(this.dragleave,this),drop:_.bind(this.drop,this)};var n=this._renderDropTarget();this.$list().before([this._renderDropTargetHelp(),n]);for(var l in m){if(m.hasOwnProperty(l)){n.on(l,m[l])}}return this},_renderDropTarget:function(){return $("<div/>").addClass("history-drop-target").css({height:"64px",margin:"0px 10px 10px 10px",border:"1px dashed black","border-radius":"3px"})},_renderDropTargetHelp:function(){return $("<div/>").addClass("history-drop-target-help").css({margin:"10px 10px 4px 10px",color:"grey","font-size":"80%","font-style":"italic"}).text(b("Drag datasets here to copy them to the current history"))},dropTargetOff:function(){if(!this.dropTarget){return this}this.dropTarget=false;this.$(".history-drop-target").remove();this.$(".history-drop-target-help").remove();return this},dropTargetToggle:function(){if(this.dropTarget){this.dropTargetOff()}else{this.dropTargetOn()}return this},dragenter:function(l){l.preventDefault();l.stopPropagation();this.$(".history-drop-target").css("border","2px solid black")},dragover:function(l){l.preventDefault();l.stopPropagation()},dragleave:function(l){l.preventDefault();l.stopPropagation();this.$(".history-drop-target").css("border","1px dashed black")},drop:function(n){n.preventDefault();n.dataTransfer.dropEffect="move";var l=this,o=n.dataTransfer.getData("text");try{o=JSON.parse(o)}catch(m){this.warn("error parsing JSON from drop:",o)}this.trigger("droptarget:drop",n,o,l);return false},dataDropped:function(m){var l=this;if(_.isObject(m)&&m.model_class==="HistoryDatasetAssociation"&&m.id){return l.model.contents.copy(m.id)}return jQuery.when()},toString:function(){return"HistoryPanelEdit("+((this.model)?(this.model.get("name")):(""))+")"}});return{HistoryPanelEdit:e}});
\ No newline at end of file
+define(["mvc/history/history-panel","mvc/history/history-contents","mvc/dataset/states","mvc/history/hda-model","mvc/history/hda-li-edit","mvc/history/hdca-li-edit","mvc/tags","mvc/annotations","jq-plugins/ui/fa-icon-button","utils/localization"],function(g,i,l,e,d,h,k,b,a,c){var j=g.HistoryPanel;var f=j.extend({HDAViewClass:d.HDAListItemEdit,HDCAViewClass:h.HDCAListItemEdit,initialize:function(m){m=m||{};j.prototype.initialize.call(this,m);this.tagsEditor=null;this.annotationEditor=null;this.purgeAllowed=m.purgeAllowed||false;this.annotationEditorShown=m.annotationEditorShown||false;this.tagsEditorShown=m.tagsEditorShown||false;this.multiselectActions=m.multiselectActions||this._getActions()},_setUpListeners:function(){j.prototype._setUpListeners.call(this);this.on("drop",function(m,n){this.dataDropped(n);this.dropTargetOff()})},_setUpCollectionListeners:function(){j.prototype._setUpCollectionListeners.call(this);this.collection.on("change:deleted",this._handleHdaDeletionChange,this);this.collection.on("change:visible",this._handleHdaVisibleChange,this);this.collection.on("change:purged",function(m){this.model.fetch()},this);return this},_setUpModelListeners:function(){j.prototype._setUpModelListeners.call(this);this.model.on("change:nice_size",this.updateHistoryDiskSize,this);return this},_buildNewRender:function(){var m=j.prototype._buildNewRender.call(this);if(!this.model){return m}if(Galaxy&&Galaxy.currUser&&Galaxy.currUser.id&&Galaxy.currUser.id===this.model.get("user_id")){this._renderTags(m);this._renderAnnotation(m)}return m},renderItems:function(n){var m=j.prototype.renderItems.call(this,n);this._renderCounts(n);return m},_renderCounts:function(o){function n(r,s){return['<a class="',r,'" href="javascript:void(0);">',s,"</a>"].join("")}o=o||this.$el;var m=this.collection.where({deleted:true}),q=this.collection.where({visible:false}),p=[];if(this.views.length){p.push([this.views.length,c("shown")].join(" "))}if(m.length){p.push((!this.showDeleted)?([m.length,n("toggle-deleted-link",c("deleted"))].join(" ")):(n("toggle-deleted-link",c("hide deleted"))))}if(q.length){p.push((!this.showHidden)?([q.length,n("toggle-hidden-link",c("hidden"))].join(" ")):(n("toggle-hidden-link",c("hide hidden"))))}return o.find("> .controls .subtitle").html(p.join(", "))},_renderTags:function(m){var n=this;this.tagsEditor=new k.TagsEditor({model:this.model,el:m.find(".controls .tags-display"),onshowFirstTime:function(){this.render()},onshow:function(){n.toggleHDATagEditors(true,n.fxSpeed)},onhide:function(){n.toggleHDATagEditors(false,n.fxSpeed)},$activator:a({title:c("Edit history tags"),classes:"history-tag-btn",faIcon:"fa-tags"}).appendTo(m.find(".controls .actions"))})},_renderAnnotation:function(m){var n=this;this.annotationEditor=new b.AnnotationEditor({model:this.model,el:m.find(".controls .annotation-display"),onshowFirstTime:function(){this.render()},onshow:function(){n.toggleHDAAnnotationEditors(true,n.fxSpeed)},onhide:function(){n.toggleHDAAnnotationEditors(false,n.fxSpeed)},$activator:a({title:c("Edit history annotation"),classes:"history-annotate-btn",faIcon:"fa-comment"}).appendTo(m.find(".controls .actions"))})},_setUpBehaviors:function(m){m=m||this.$el;j.prototype._setUpBehaviors.call(this,m);if(!this.model){return}if(this.multiselectActions.length){this.actionsPopup=new PopupMenu(m.find(".list-action-popup-btn"),this.multiselectActions)}if((!Galaxy.currUser||Galaxy.currUser.isAnonymous())||(Galaxy.currUser.id!==this.model.get("user_id"))){return}var n=this,o=".controls .name";m.find(o).attr("title",c("Click to rename history")).tooltip({placement:"bottom"}).make_text_editable({on_finish:function(p){var q=n.model.get("name");if(p&&p!==q){n.$el.find(o).text(p);n.model.save({name:p}).fail(function(){n.$el.find(o).text(n.model.previous("name"))})}else{n.$el.find(o).text(q)}}})},_getActions:function(){var m=this,n=[{html:c("Hide datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype.hide;m.getSelectedModels().ajaxQueue(o)}},{html:c("Unhide datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype.unhide;m.getSelectedModels().ajaxQueue(o)}},{html:c("Delete datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype["delete"];m.getSelectedModels().ajaxQueue(o)}},{html:c("Undelete datasets"),func:function(){var o=e.HistoryDatasetAssociation.prototype.undelete;m.getSelectedModels().ajaxQueue(o)}}];if(m.purgeAllowed){n.push({html:c("Permanently delete datasets"),func:function(){if(confirm(c("This will permanently remove the data in your datasets. Are you sure?"))){var o=e.HistoryDatasetAssociation.prototype.purge;m.getSelectedModels().ajaxQueue(o)}}})}n.push({html:c("Build Dataset List"),func:function(){m.getSelectedModels().promoteToHistoryDatasetCollection(m.model,"list")}});n.push({html:c("Build Dataset Pair"),func:function(){m.getSelectedModels().promoteToHistoryDatasetCollection(m.model,"paired")}});n.push({html:c("Build List of Dataset Pairs"),func:_.bind(m._showPairedCollectionModal,m)});return n},_showPairedCollectionModal:function(){var m=this,n=m.getSelectedModels().toJSON().filter(function(o){return o.history_content_type==="dataset"&&o.state===l.OK});if(n.length){require(["mvc/collection/paired-collection-creator"],function(o){window.creator=o.pairedCollectionCreatorModal(n,{historyId:m.model.id})})}else{}},_attachItems:function(m){this.$list(m).append(this.views.reverse().map(function(n){return n.$el}));return this},_attachView:function(n){var m=this;m.views.unshift(n);m.$list().prepend(n.render(0).$el.hide());n.$el.slideDown(m.fxSpeed)},_getItemViewOptions:function(n){var m=j.prototype._getItemViewOptions.call(this,n);_.extend(m,{purgeAllowed:this.purgeAllowed,tagsEditorShown:(this.tagsEditor&&!this.tagsEditor.hidden),annotationEditorShown:(this.annotationEditor&&!this.annotationEditor.hidden)});return m},_handleHdaDeletionChange:function(m){if(m.get("deleted")&&!this.showDeleted){this.removeItemView(m)}this._renderCounts()},_handleHdaVisibleChange:function(m){if(m.hidden()&&!this.storage.showHidden){this.removeItemView(m)}this._renderCounts()},toggleHDATagEditors:function(m){var n=Array.prototype.slice.call(arguments,1);_.each(this.views,function(o){if(o.tagsEditor){o.tagsEditor.toggle.apply(o.tagsEditor,n)}})},toggleHDAAnnotationEditors:function(m){var n=Array.prototype.slice.call(arguments,1);_.each(this.views,function(o){if(o.annotationEditor){o.annotationEditor.toggle.apply(o.annotationEditor,n)}})},events:_.extend(_.clone(j.prototype.events),{"click .show-selectors-btn":"toggleSelectors","click .toggle-deleted-link":function(m){this.toggleShowDeleted()},"click .toggle-hidden-link":function(m){this.toggleShowHidden()}}),updateHistoryDiskSize:function(){this.$el.find(".history-size").text(this.model.get("nice_size"))},dropTargetOn:function(){if(this.dropTarget){return this}this.dropTarget=true;var n={dragenter:_.bind(this.dragenter,this),dragover:_.bind(this.dragover,this),dragleave:_.bind(this.dragleave,this),drop:_.bind(this.drop,this)};var o=this._renderDropTarget();this.$list().before([this._renderDropTargetHelp(),o]);for(var m in n){if(n.hasOwnProperty(m)){o.on(m,n[m])}}return this},_renderDropTarget:function(){return $("<div/>").addClass("history-drop-target").css({height:"64px",margin:"0px 10px 10px 10px",border:"1px dashed black","border-radius":"3px"})},_renderDropTargetHelp:function(){return $("<div/>").addClass("history-drop-target-help").css({margin:"10px 10px 4px 10px",color:"grey","font-size":"80%","font-style":"italic"}).text(c("Drag datasets here to copy them to the current history"))},dropTargetOff:function(){if(!this.dropTarget){return this}this.dropTarget=false;this.$(".history-drop-target").remove();this.$(".history-drop-target-help").remove();return this},dropTargetToggle:function(){if(this.dropTarget){this.dropTargetOff()}else{this.dropTargetOn()}return this},dragenter:function(m){m.preventDefault();m.stopPropagation();this.$(".history-drop-target").css("border","2px solid black")},dragover:function(m){m.preventDefault();m.stopPropagation()},dragleave:function(m){m.preventDefault();m.stopPropagation();this.$(".history-drop-target").css("border","1px dashed black")},drop:function(o){o.preventDefault();o.dataTransfer.dropEffect="move";var m=this,p=o.dataTransfer.getData("text");try{p=JSON.parse(p)}catch(n){this.warn("error parsing JSON from drop:",p)}this.trigger("droptarget:drop",o,p,m);return false},dataDropped:function(n){var m=this;if(_.isObject(n)&&n.model_class==="HistoryDatasetAssociation"&&n.id){return m.model.contents.copy(n.id)}return jQuery.when()},toString:function(){return"HistoryPanelEdit("+((this.model)?(this.model.get("name")):(""))+")"}});return{HistoryPanelEdit:f}});
\ No newline at end of file
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/mvc/history/history-panel.js
--- a/static/scripts/packed/mvc/history/history-panel.js
+++ b/static/scripts/packed/mvc/history/history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/list/list-panel","mvc/history/history-model","mvc/history/history-contents","mvc/history/hda-li","mvc/history/hdca-li","mvc/collection/collection-panel","mvc/user/user-model","mvc/base-mvc","utils/localization","jq-plugins/ui/search-input"],function(d,f,l,b,a,m,g,o,e){var j=o.SessionStorageModel.extend({defaults:{expandedIds:{},show_deleted:false,show_hidden:false},addExpanded:function(p){var q="expandedIds";this.save(q,_.extend(this.get(q),_.object([p.id],[p.get("id")])))},removeExpanded:function(p){var q="expandedIds";this.save(q,_.omit(this.get(q),p.id))},toString:function(){return"HistoryPrefs("+this.id+")"}});j.storageKeyPrefix="history:";j.historyStorageKey=function h(p){if(!p){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+p)}return(j.storageKeyPrefix+p)};j.get=function c(p){return new j({id:j.historyStorageKey(p)})};j.clearAll=function i(q){for(var p in sessionStorage){if(p.indexOf(j.storageKeyPrefix)===0){sessionStorage.removeItem(p)}}};var n=d.ModelListPanel;var k=n.extend({HDAViewClass:b.HDAListItemView,HDCAViewClass:a.HDCAListItemView,collectionClass:l.HistoryContents,modelCollectionKey:"contents",tagName:"div",className:n.prototype.className+" history-panel",emptyMsg:e("This history is empty"),noneFoundMsg:e("No matching datasets found"),searchPlaceholder:e("search datasets"),initialize:function(p){n.prototype.initialize.call(this,p);this.linkTarget=p.linkTarget||"_blank"},freeModel:function(){n.prototype.freeModel.call(this);if(this.model){this.model.clearUpdateTimeout()}return this},_setUpListeners:function(){n.prototype._setUpListeners.call(this);this.on("error",function(q,t,p,s,r){this.errorHandler(q,t,p,s,r)});this.on("loading-done",function(){if(!this.views.length){this.trigger("empty-history",this)}})},loadHistoryWithDetails:function(s,r,q,t){this.info("loadHistoryWithDetails:",s,r,q,t);var p=function(u){return _.values(j.get(u.id).get("expandedIds"))};return this.loadHistory(s,r,q,t,p)},loadHistory:function(t,s,r,u,p){this.info("loadHistory:",t,s,r,u,p);var q=this;s=s||{};q.trigger("loading",q);var v=f.History.getHistoryData(t,{historyFn:r,contentsFn:u,detailIdsFn:s.initiallyExpanded||p});return q._loadHistoryFromXHR(v,s).fail(function(y,w,x){q.trigger("error",q,y,s,e("An error was encountered while "+w),{historyId:t,history:x||{}})}).always(function(){q.trigger("loading-done",q)})},_loadHistoryFromXHR:function(r,q){var p=this;r.then(function(s,t){p.JSONToModel(s,t,q);p.render()});r.fail(function(t,s){p.render()});return r},refreshContents:function(q,p){if(this.model){return this.model.refresh(q,p)}return $.when()},JSONToModel:function(s,p,q){this.log("JSONToModel:",s,p,q);q=q||{};var r=new f.History(s,p,q);this.setModel(r);return r},setModel:function(q,p){p=p||{};n.prototype.setModel.call(this,q,p);if(this.model){this._setUpWebStorage(p.initiallyExpanded,p.show_deleted,p.show_hidden)}},_setUpWebStorage:function(q,p,r){if(this.storage){this.stopListening(this.storage)}this.storage=new j({id:j.historyStorageKey(this.model.get("id"))});if(_.isObject(q)){this.storage.set("expandedIds",q)}if(_.isBoolean(p)){this.storage.set("show_deleted",p)}if(_.isBoolean(r)){this.storage.set("show_hidden",r)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());this.listenTo(this.storage,{"change:show_deleted":function(s,t){this.showDeleted=t},"change:show_hidden":function(s,t){this.showHidden=t}},this);this.showDeleted=(p!==undefined)?p:this.storage.get("show_deleted");this.showHidden=(r!==undefined)?r:this.storage.get("show_hidden");return this},_buildNewRender:function(){var p=n.prototype._buildNewRender.call(this);if(this.multiselectActions.length){p.find(".controls .actions").prepend(this._renderSelectButton())}return p},_renderSelectButton:function(p){return faIconButton({title:e("Operations on multiple datasets"),classes:"show-selectors-btn",faIcon:"fa-check-square-o"})},_getItemViewClass:function(p){var q=p.get("history_content_type");switch(q){case"dataset":return this.HDAViewClass;case"dataset_collection":return this.HDCAViewClass}throw new TypeError("Unknown history_content_type: "+q)},_filterItem:function(q){var p=this;return(n.prototype._filterItem.call(p,q)&&(!q.hidden()||p.showHidden)&&(!q.isDeletedOrPurged()||p.showDeleted))},_getItemViewOptions:function(q){var p=n.prototype._getItemViewOptions.call(this,q);return _.extend(p,{linkTarget:this.linkTarget,expanded:!!this.storage.get("expandedIds")[q.id],hasUser:this.model.ownedByCurrUser()})},_setUpItemViewListeners:function(q){var p=this;n.prototype._setUpItemViewListeners.call(p,q);q.on("expanded",function(r){p.storage.addExpanded(r.model)});q.on("collapsed",function(r){p.storage.removeExpanded(r.model)});return this},getSelectedModels:function(){var p=n.prototype.getSelectedModels.call(this);p.historyId=this.collection.historyId;return p},events:_.extend(_.clone(n.prototype.events),{"click .show-selectors-btn":"toggleSelectors"}),toggleShowDeleted:function(p,q){p=(p!==undefined)?(p):(!this.showDeleted);q=(q!==undefined)?(q):(true);this.showDeleted=p;if(q){this.storage.set("show_deleted",p)}this.trigger("show-hidden",p);this.renderItems();return this.showDeleted},toggleShowHidden:function(p,q){p=(p!==undefined)?(p):(!this.showHidden);q=(q!==undefined)?(q):(true);this.showHidden=p;if(q){this.storage.set("show_hidden",p)}this.trigger("show-hidden",p);this.renderItems();return this.showHidden},_firstSearch:function(p){var q=this,r=".history-search-input";this.log("onFirstSearch",p);if(q.model.contents.haveDetails()){q.searchItems(p);return}q.$el.find(r).searchInput("toggle-loading");q.model.contents.fetchAllDetails({silent:true}).always(function(){q.$el.find(r).searchInput("toggle-loading")}).done(function(){q.searchItems(p)})},errorHandler:function(r,u,q,t,s){this.error(r,u,q,t,s);if(u&&u.status===0&&u.readyState===0){}else{if(u&&u.status===502){}else{var p=this._parseErrorMessage(r,u,q,t,s);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",p.message,p.details)})}else{this.displayMessage("error",p.message,p.details)}}}},_parseErrorMessage:function(t,w,x,r,p,u){var s=Galaxy.currUser,v={message:this._bePolite(r),details:{message:r,raven:(window.Raven&&_.isFunction(Raven.lastEventId))?(Raven.lastEventId()):(undefined),agent:navigator.userAgent,url:(window.Galaxy)?(Galaxy.lastAjax.url):(undefined),data:(window.Galaxy)?(Galaxy.lastAjax.data):(undefined),options:(w)?(_.omit(x,"xhr")):(x),xhr:w,source:(_.isFunction(t.toJSON))?(t.toJSON()):(t+""),user:(s instanceof g.User)?(s.toJSON()):(s+"")}};_.extend(v.details,p||{});if(w&&_.isFunction(w.getAllResponseHeaders)){var q=w.getAllResponseHeaders();q=_.compact(q.split("\n"));q=_.map(q,function(y){return y.split(": ")});v.details.xhr.responseHeaders=_.object(q)}return v},_bePolite:function(p){p=p||e("An error occurred while getting updates from the server");return p+". "+e("Please contact a Galaxy administrator if the problem persists")+"."},displayMessage:function(u,v,t){var r=this;this.scrollToTop();var s=this.$messages(),p=$("<div/>").addClass(u+"message").html(v);if(!_.isEmpty(t)){var q=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(r._messageToModalOptions(u,v,t));return false});p.append(" ",q)}return s.html(p)},_messageToModalOptions:function(s,v,r){var p=this,q={title:"Details"};if(_.isObject(r)){r=_.omit(r,_.functions(r));var u=JSON.stringify(r,null," "),t=$("<pre/>").text(u);q.body=$("<div/>").append(t)}else{q.body=$("<div/>").html(r)}q.buttons={Ok:function(){Galaxy.modal.hide();p.clearMessages()}};return q},clearMessages:function(p){$(p.currentTarget).fadeOut(this.fxSpeed,function(){$(this).remove()});return this},scrollToHid:function(p){return this.scrollToItem(_.first(this.viewsWhereModel({hid:p})))},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});k.prototype.templates=(function(){var p=o.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= history.name %></div>',"</div>",'<div class="subtitle"></div>','<div class="history-size"><%= history.nice_size %></div>','<div class="actions"></div>','<div class="messages">',"<% if( history.deleted ){ %>",'<div class="deleted-msg warningmessagesmall">',e("This history has been deleted"),"</div>","<% } %>","<% if( history.message ){ %>",'<div class="<%= history.message.level || "info" %>messagesmall">',"<%= history.message.text %>","</div>","<% } %>","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',e("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',e("None"),"</button>","</div>",'<button class="list-action-popup-btn btn btn-default">',e("For all selected"),"...</button>","</div>","</div>"],"history");return _.extend(_.clone(n.prototype.templates),{controls:p})}());return{HistoryPanel:k}});
\ No newline at end of file
+define(["mvc/list/list-panel","mvc/history/history-model","mvc/history/history-contents","mvc/history/hda-li","mvc/history/hdca-li","mvc/collection/collection-panel","mvc/user/user-model","jq-plugins/ui/fa-icon-button","mvc/base-mvc","utils/localization","jq-plugins/ui/search-input"],function(e,g,m,c,a,n,h,b,p,f){var k=p.SessionStorageModel.extend({defaults:{expandedIds:{},show_deleted:false,show_hidden:false},addExpanded:function(q){var r="expandedIds";this.save(r,_.extend(this.get(r),_.object([q.id],[q.get("id")])))},removeExpanded:function(q){var r="expandedIds";this.save(r,_.omit(this.get(r),q.id))},toString:function(){return"HistoryPrefs("+this.id+")"}});k.storageKeyPrefix="history:";k.historyStorageKey=function i(q){if(!q){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+q)}return(k.storageKeyPrefix+q)};k.get=function d(q){return new k({id:k.historyStorageKey(q)})};k.clearAll=function j(r){for(var q in sessionStorage){if(q.indexOf(k.storageKeyPrefix)===0){sessionStorage.removeItem(q)}}};var o=e.ModelListPanel;var l=o.extend({HDAViewClass:c.HDAListItemView,HDCAViewClass:a.HDCAListItemView,collectionClass:m.HistoryContents,modelCollectionKey:"contents",tagName:"div",className:o.prototype.className+" history-panel",emptyMsg:f("This history is empty"),noneFoundMsg:f("No matching datasets found"),searchPlaceholder:f("search datasets"),initialize:function(q){o.prototype.initialize.call(this,q);this.linkTarget=q.linkTarget||"_blank"},freeModel:function(){o.prototype.freeModel.call(this);if(this.model){this.model.clearUpdateTimeout()}return this},_setUpListeners:function(){o.prototype._setUpListeners.call(this);this.on("error",function(r,u,q,t,s){this.errorHandler(r,u,q,t,s)});this.on("loading-done",function(){if(!this.views.length){this.trigger("empty-history",this)}})},loadHistoryWithDetails:function(t,s,r,u){this.info("loadHistoryWithDetails:",t,s,r,u);var q=function(v){return _.values(k.get(v.id).get("expandedIds"))};return this.loadHistory(t,s,r,u,q)},loadHistory:function(u,t,s,v,q){this.info("loadHistory:",u,t,s,v,q);var r=this;t=t||{};r.trigger("loading",r);var w=g.History.getHistoryData(u,{historyFn:s,contentsFn:v,detailIdsFn:t.initiallyExpanded||q});return r._loadHistoryFromXHR(w,t).fail(function(z,x,y){r.trigger("error",r,z,t,f("An error was encountered while "+x),{historyId:u,history:y||{}})}).always(function(){r.trigger("loading-done",r)})},_loadHistoryFromXHR:function(s,r){var q=this;s.then(function(t,u){q.JSONToModel(t,u,r);q.render()});s.fail(function(u,t){q.render()});return s},refreshContents:function(r,q){if(this.model){return this.model.refresh(r,q)}return $.when()},JSONToModel:function(t,q,r){this.log("JSONToModel:",t,q,r);r=r||{};var s=new g.History(t,q,r);this.setModel(s);return s},setModel:function(r,q){q=q||{};o.prototype.setModel.call(this,r,q);if(this.model){this._setUpWebStorage(q.initiallyExpanded,q.show_deleted,q.show_hidden)}},_setUpWebStorage:function(r,q,s){if(this.storage){this.stopListening(this.storage)}this.storage=new k({id:k.historyStorageKey(this.model.get("id"))});if(_.isObject(r)){this.storage.set("expandedIds",r)}if(_.isBoolean(q)){this.storage.set("show_deleted",q)}if(_.isBoolean(s)){this.storage.set("show_hidden",s)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());this.listenTo(this.storage,{"change:show_deleted":function(t,u){this.showDeleted=u},"change:show_hidden":function(t,u){this.showHidden=u}},this);this.showDeleted=(q!==undefined)?q:this.storage.get("show_deleted");this.showHidden=(s!==undefined)?s:this.storage.get("show_hidden");return this},_buildNewRender:function(){var q=o.prototype._buildNewRender.call(this);if(this.multiselectActions.length){q.find(".controls .actions").prepend(this._renderSelectButton())}return q},_renderSelectButton:function(q){return b({title:f("Operations on multiple datasets"),classes:"show-selectors-btn",faIcon:"fa-check-square-o"})},_getItemViewClass:function(q){var r=q.get("history_content_type");switch(r){case"dataset":return this.HDAViewClass;case"dataset_collection":return this.HDCAViewClass}throw new TypeError("Unknown history_content_type: "+r)},_filterItem:function(r){var q=this;return(o.prototype._filterItem.call(q,r)&&(!r.hidden()||q.showHidden)&&(!r.isDeletedOrPurged()||q.showDeleted))},_getItemViewOptions:function(r){var q=o.prototype._getItemViewOptions.call(this,r);return _.extend(q,{linkTarget:this.linkTarget,expanded:!!this.storage.get("expandedIds")[r.id],hasUser:this.model.ownedByCurrUser()})},_setUpItemViewListeners:function(r){var q=this;o.prototype._setUpItemViewListeners.call(q,r);r.on("expanded",function(s){q.storage.addExpanded(s.model)});r.on("collapsed",function(s){q.storage.removeExpanded(s.model)});return this},getSelectedModels:function(){var q=o.prototype.getSelectedModels.call(this);q.historyId=this.collection.historyId;return q},events:_.extend(_.clone(o.prototype.events),{"click .show-selectors-btn":"toggleSelectors"}),toggleShowDeleted:function(q,r){q=(q!==undefined)?(q):(!this.showDeleted);r=(r!==undefined)?(r):(true);this.showDeleted=q;if(r){this.storage.set("show_deleted",q)}this.trigger("show-hidden",q);this.renderItems();return this.showDeleted},toggleShowHidden:function(q,r){q=(q!==undefined)?(q):(!this.showHidden);r=(r!==undefined)?(r):(true);this.showHidden=q;if(r){this.storage.set("show_hidden",q)}this.trigger("show-hidden",q);this.renderItems();return this.showHidden},_firstSearch:function(q){var r=this,s=".history-search-input";this.log("onFirstSearch",q);if(r.model.contents.haveDetails()){r.searchItems(q);return}r.$el.find(s).searchInput("toggle-loading");r.model.contents.fetchAllDetails({silent:true}).always(function(){r.$el.find(s).searchInput("toggle-loading")}).done(function(){r.searchItems(q)})},errorHandler:function(s,v,r,u,t){this.error(s,v,r,u,t);if(v&&v.status===0&&v.readyState===0){}else{if(v&&v.status===502){}else{var q=this._parseErrorMessage(s,v,r,u,t);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",q.message,q.details)})}else{this.displayMessage("error",q.message,q.details)}}}},_parseErrorMessage:function(u,x,y,s,q,v){var t=Galaxy.currUser,w={message:this._bePolite(s),details:{message:s,raven:(window.Raven&&_.isFunction(Raven.lastEventId))?(Raven.lastEventId()):(undefined),agent:navigator.userAgent,url:(window.Galaxy)?(Galaxy.lastAjax.url):(undefined),data:(window.Galaxy)?(Galaxy.lastAjax.data):(undefined),options:(x)?(_.omit(y,"xhr")):(y),xhr:x,source:(_.isFunction(u.toJSON))?(u.toJSON()):(u+""),user:(t instanceof h.User)?(t.toJSON()):(t+"")}};_.extend(w.details,q||{});if(x&&_.isFunction(x.getAllResponseHeaders)){var r=x.getAllResponseHeaders();r=_.compact(r.split("\n"));r=_.map(r,function(z){return z.split(": ")});w.details.xhr.responseHeaders=_.object(r)}return w},_bePolite:function(q){q=q||f("An error occurred while getting updates from the server");return q+". "+f("Please contact a Galaxy administrator if the problem persists")+"."},displayMessage:function(v,w,u){var s=this;this.scrollToTop();var t=this.$messages(),q=$("<div/>").addClass(v+"message").html(w);if(!_.isEmpty(u)){var r=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(s._messageToModalOptions(v,w,u));return false});q.append(" ",r)}return t.html(q)},_messageToModalOptions:function(t,w,s){var q=this,r={title:"Details"};if(_.isObject(s)){s=_.omit(s,_.functions(s));var v=JSON.stringify(s,null," "),u=$("<pre/>").text(v);r.body=$("<div/>").append(u)}else{r.body=$("<div/>").html(s)}r.buttons={Ok:function(){Galaxy.modal.hide();q.clearMessages()}};return r},clearMessages:function(q){$(q.currentTarget).fadeOut(this.fxSpeed,function(){$(this).remove()});return this},scrollToHid:function(q){return this.scrollToItem(_.first(this.viewsWhereModel({hid:q})))},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});l.prototype.templates=(function(){var q=p.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= history.name %></div>',"</div>",'<div class="subtitle"></div>','<div class="history-size"><%= history.nice_size %></div>','<div class="actions"></div>','<div class="messages">',"<% if( history.deleted ){ %>",'<div class="deleted-msg warningmessagesmall">',f("This history has been deleted"),"</div>","<% } %>","<% if( history.message ){ %>",'<div class="<%= history.message.level || "info" %>messagesmall">',"<%= history.message.text %>","</div>","<% } %>","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',f("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',f("None"),"</button>","</div>",'<button class="list-action-popup-btn btn btn-default">',f("For all selected"),"...</button>","</div>","</div>"],"history");return _.extend(_.clone(o.prototype.templates),{controls:q})}());return{HistoryPanel:l}});
\ No newline at end of file
diff -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 -r 6c9848ad6d02691c7c68cd8faada68753126b472 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};
\ No newline at end of file
+var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: modularize loading indicator from ui.js
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/558cfd39bb3f/
Changeset: 558cfd39bb3f
User: carlfeberhard
Date: 2014-12-09 17:37:36+00:00
Summary: Client build: modularize loading indicator from ui.js
Affected #: 9 files
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 client/galaxy/scripts/jq-plugins/ui/loading-indicator.js
--- /dev/null
+++ b/client/galaxy/scripts/jq-plugins/ui/loading-indicator.js
@@ -0,0 +1,98 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([], factory);
+ } else {
+ // Browser globals
+ root.LoadingIndicator = factory();
+ }
+
+//============================================================================
+}(this, function () {
+ //TODO: too specific to history panel
+ function LoadingIndicator( $where, options ){
+
+ var self = this;
+ // defaults
+ options = jQuery.extend({
+ cover : false
+ }, options || {} );
+
+ function render(){
+ var html = [
+ '<div class="loading-indicator">',
+ '<div class="loading-indicator-text">',
+ '<span class="fa fa-spinner fa-spin fa-lg"></span>',
+ '<span class="loading-indicator-message">loading...</span>',
+ '</div>',
+ '</div>'
+ ].join( '\n' );
+
+ var $indicator = $( html ).hide().css( options.css || {
+ position : 'fixed'
+ }),
+ $text = $indicator.children( '.loading-indicator-text' );
+
+ if( options.cover ){
+ $indicator.css({
+ 'z-index' : 2,
+ top : $where.css( 'top' ),
+ bottom : $where.css( 'bottom' ),
+ left : $where.css( 'left' ),
+ right : $where.css( 'right' ),
+ opacity : 0.5,
+ 'background-color': 'white',
+ 'text-align': 'center'
+ });
+ $text = $indicator.children( '.loading-indicator-text' ).css({
+ 'margin-top' : '20px'
+ });
+
+ } else {
+ $text = $indicator.children( '.loading-indicator-text' ).css({
+ margin : '12px 0px 0px 10px',
+ opacity : '0.85',
+ color : 'grey'
+ });
+ $text.children( '.loading-indicator-message' ).css({
+ margin : '0px 8px 0px 0px',
+ 'font-style' : 'italic'
+ });
+ }
+ return $indicator;
+ }
+
+ self.show = function( msg, speed, callback ){
+ msg = msg || 'loading...';
+ speed = speed || 'fast';
+ // remove previous
+ $where.parent().find( '.loading-indicator' ).remove();
+ // since position is fixed - we insert as sibling
+ self.$indicator = render().insertBefore( $where );
+ self.message( msg );
+ self.$indicator.fadeIn( speed, callback );
+ return self;
+ };
+
+ self.message = function( msg ){
+ self.$indicator.find( 'i' ).text( msg );
+ };
+
+ self.hide = function( speed, callback ){
+ speed = speed || 'fast';
+ if( self.$indicator && self.$indicator.size() ){
+ self.$indicator.fadeOut( speed, function(){
+ self.$indicator.remove();
+ if( callback ){ callback(); }
+ });
+ } else {
+ if( callback ){ callback(); }
+ }
+ return self;
+ };
+ return self;
+ }
+
+//============================================================================
+ return LoadingIndicator;
+}));
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 client/galaxy/scripts/mvc/list/list-panel.js
--- a/client/galaxy/scripts/mvc/list/list-panel.js
+++ b/client/galaxy/scripts/mvc/list/list-panel.js
@@ -1,9 +1,10 @@
define([
"mvc/list/list-item",
+ "jq-plugins/ui/loading-indicator",
"mvc/base-mvc",
"utils/localization",
"jq-plugins/ui/search-input"
-], function( LIST_ITEM, BASE_MVC, _l ){
+], function( LIST_ITEM, LoadingIndicator, BASE_MVC, _l ){
/* ============================================================================
TODO:
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 client/galaxy/scripts/mvc/ui.js
--- a/client/galaxy/scripts/mvc/ui.js
+++ b/client/galaxy/scripts/mvc/ui.js
@@ -514,90 +514,3 @@
}
return $button;
};
-
-
-//==============================================================================
-function LoadingIndicator( $where, options ){
-//TODO: move out of global
-//TODO: too specific to history panel
-
- var self = this;
- // defaults
- options = jQuery.extend({
- cover : false
- }, options || {} );
-
- function render(){
- var html = [
- '<div class="loading-indicator">',
- '<div class="loading-indicator-text">',
- '<span class="fa fa-spinner fa-spin fa-lg"></span>',
- '<span class="loading-indicator-message">loading...</span>',
- '</div>',
- '</div>'
- ].join( '\n' );
-
- var $indicator = $( html ).hide().css( options.css || {
- position : 'fixed'
- }),
- $text = $indicator.children( '.loading-indicator-text' );
-
- if( options.cover ){
- $indicator.css({
- 'z-index' : 2,
- top : $where.css( 'top' ),
- bottom : $where.css( 'bottom' ),
- left : $where.css( 'left' ),
- right : $where.css( 'right' ),
- opacity : 0.5,
- 'background-color': 'white',
- 'text-align': 'center'
- });
- $text = $indicator.children( '.loading-indicator-text' ).css({
- 'margin-top' : '20px'
- });
-
- } else {
- $text = $indicator.children( '.loading-indicator-text' ).css({
- margin : '12px 0px 0px 10px',
- opacity : '0.85',
- color : 'grey'
- });
- $text.children( '.loading-indicator-message' ).css({
- margin : '0px 8px 0px 0px',
- 'font-style' : 'italic'
- });
- }
- return $indicator;
- }
-
- self.show = function( msg, speed, callback ){
- msg = msg || 'loading...';
- speed = speed || 'fast';
- // remove previous
- $where.parent().find( '.loading-indicator' ).remove();
- // since position is fixed - we insert as sibling
- self.$indicator = render().insertBefore( $where );
- self.message( msg );
- self.$indicator.fadeIn( speed, callback );
- return self;
- };
-
- self.message = function( msg ){
- self.$indicator.find( 'i' ).text( msg );
- };
-
- self.hide = function( speed, callback ){
- speed = speed || 'fast';
- if( self.$indicator && self.$indicator.size() ){
- self.$indicator.fadeOut( speed, function(){
- self.$indicator.remove();
- if( callback ){ callback(); }
- });
- } else {
- if( callback ){ callback(); }
- }
- return self;
- };
- return self;
-}
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 static/scripts/jq-plugins/ui/loading-indicator.js
--- /dev/null
+++ b/static/scripts/jq-plugins/ui/loading-indicator.js
@@ -0,0 +1,98 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define([], factory);
+ } else {
+ // Browser globals
+ root.LoadingIndicator = factory();
+ }
+
+//============================================================================
+}(this, function () {
+ //TODO: too specific to history panel
+ function LoadingIndicator( $where, options ){
+
+ var self = this;
+ // defaults
+ options = jQuery.extend({
+ cover : false
+ }, options || {} );
+
+ function render(){
+ var html = [
+ '<div class="loading-indicator">',
+ '<div class="loading-indicator-text">',
+ '<span class="fa fa-spinner fa-spin fa-lg"></span>',
+ '<span class="loading-indicator-message">loading...</span>',
+ '</div>',
+ '</div>'
+ ].join( '\n' );
+
+ var $indicator = $( html ).hide().css( options.css || {
+ position : 'fixed'
+ }),
+ $text = $indicator.children( '.loading-indicator-text' );
+
+ if( options.cover ){
+ $indicator.css({
+ 'z-index' : 2,
+ top : $where.css( 'top' ),
+ bottom : $where.css( 'bottom' ),
+ left : $where.css( 'left' ),
+ right : $where.css( 'right' ),
+ opacity : 0.5,
+ 'background-color': 'white',
+ 'text-align': 'center'
+ });
+ $text = $indicator.children( '.loading-indicator-text' ).css({
+ 'margin-top' : '20px'
+ });
+
+ } else {
+ $text = $indicator.children( '.loading-indicator-text' ).css({
+ margin : '12px 0px 0px 10px',
+ opacity : '0.85',
+ color : 'grey'
+ });
+ $text.children( '.loading-indicator-message' ).css({
+ margin : '0px 8px 0px 0px',
+ 'font-style' : 'italic'
+ });
+ }
+ return $indicator;
+ }
+
+ self.show = function( msg, speed, callback ){
+ msg = msg || 'loading...';
+ speed = speed || 'fast';
+ // remove previous
+ $where.parent().find( '.loading-indicator' ).remove();
+ // since position is fixed - we insert as sibling
+ self.$indicator = render().insertBefore( $where );
+ self.message( msg );
+ self.$indicator.fadeIn( speed, callback );
+ return self;
+ };
+
+ self.message = function( msg ){
+ self.$indicator.find( 'i' ).text( msg );
+ };
+
+ self.hide = function( speed, callback ){
+ speed = speed || 'fast';
+ if( self.$indicator && self.$indicator.size() ){
+ self.$indicator.fadeOut( speed, function(){
+ self.$indicator.remove();
+ if( callback ){ callback(); }
+ });
+ } else {
+ if( callback ){ callback(); }
+ }
+ return self;
+ };
+ return self;
+ }
+
+//============================================================================
+ return LoadingIndicator;
+}));
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 static/scripts/mvc/list/list-panel.js
--- a/static/scripts/mvc/list/list-panel.js
+++ b/static/scripts/mvc/list/list-panel.js
@@ -1,9 +1,10 @@
define([
"mvc/list/list-item",
+ "jq-plugins/ui/loading-indicator",
"mvc/base-mvc",
"utils/localization",
"jq-plugins/ui/search-input"
-], function( LIST_ITEM, BASE_MVC, _l ){
+], function( LIST_ITEM, LoadingIndicator, BASE_MVC, _l ){
/* ============================================================================
TODO:
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -514,90 +514,3 @@
}
return $button;
};
-
-
-//==============================================================================
-function LoadingIndicator( $where, options ){
-//TODO: move out of global
-//TODO: too specific to history panel
-
- var self = this;
- // defaults
- options = jQuery.extend({
- cover : false
- }, options || {} );
-
- function render(){
- var html = [
- '<div class="loading-indicator">',
- '<div class="loading-indicator-text">',
- '<span class="fa fa-spinner fa-spin fa-lg"></span>',
- '<span class="loading-indicator-message">loading...</span>',
- '</div>',
- '</div>'
- ].join( '\n' );
-
- var $indicator = $( html ).hide().css( options.css || {
- position : 'fixed'
- }),
- $text = $indicator.children( '.loading-indicator-text' );
-
- if( options.cover ){
- $indicator.css({
- 'z-index' : 2,
- top : $where.css( 'top' ),
- bottom : $where.css( 'bottom' ),
- left : $where.css( 'left' ),
- right : $where.css( 'right' ),
- opacity : 0.5,
- 'background-color': 'white',
- 'text-align': 'center'
- });
- $text = $indicator.children( '.loading-indicator-text' ).css({
- 'margin-top' : '20px'
- });
-
- } else {
- $text = $indicator.children( '.loading-indicator-text' ).css({
- margin : '12px 0px 0px 10px',
- opacity : '0.85',
- color : 'grey'
- });
- $text.children( '.loading-indicator-message' ).css({
- margin : '0px 8px 0px 0px',
- 'font-style' : 'italic'
- });
- }
- return $indicator;
- }
-
- self.show = function( msg, speed, callback ){
- msg = msg || 'loading...';
- speed = speed || 'fast';
- // remove previous
- $where.parent().find( '.loading-indicator' ).remove();
- // since position is fixed - we insert as sibling
- self.$indicator = render().insertBefore( $where );
- self.message( msg );
- self.$indicator.fadeIn( speed, callback );
- return self;
- };
-
- self.message = function( msg ){
- self.$indicator.find( 'i' ).text( msg );
- };
-
- self.hide = function( speed, callback ){
- speed = speed || 'fast';
- if( self.$indicator && self.$indicator.size() ){
- self.$indicator.fadeOut( speed, function(){
- self.$indicator.remove();
- if( callback ){ callback(); }
- });
- } else {
- if( callback ){ callback(); }
- }
- return self;
- };
- return self;
-}
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 static/scripts/packed/jq-plugins/ui/loading-indicator.js
--- /dev/null
+++ b/static/scripts/packed/jq-plugins/ui/loading-indicator.js
@@ -0,0 +1,1 @@
+(function(a,b){if(typeof define==="function"&&define.amd){define([],b)}else{a.LoadingIndicator=b()}}(this,function(){function a(b,d){var c=this;d=jQuery.extend({cover:false},d||{});function e(){var f=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var h=$(f).hide().css(d.css||{position:"fixed"}),g=h.children(".loading-indicator-text");if(d.cover){h.css({"z-index":2,top:b.css("top"),bottom:b.css("bottom"),left:b.css("left"),right:b.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});g=h.children(".loading-indicator-text").css({"margin-top":"20px"})}else{g=h.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});g.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return h}c.show=function(g,f,h){g=g||"loading...";f=f||"fast";b.parent().find(".loading-indicator").remove();c.$indicator=e().insertBefore(b);c.message(g);c.$indicator.fadeIn(f,h);return c};c.message=function(f){c.$indicator.find("i").text(f)};c.hide=function(f,g){f=f||"fast";if(c.$indicator&&c.$indicator.size()){c.$indicator.fadeOut(f,function(){c.$indicator.remove();if(g){g()}})}else{if(g){g()}}return c};return c}return a}));
\ No newline at end of file
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 static/scripts/packed/mvc/list/list-panel.js
--- a/static/scripts/packed/mvc/list/list-panel.js
+++ b/static/scripts/packed/mvc/list/list-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/list/list-item","mvc/base-mvc","utils/localization","jq-plugins/ui/search-input"],function(d,b,c){var e=Backbone.View.extend(b.LoggableMixin).extend({viewClass:d.ListItemView,collectionClass:Backbone.Collection,tagName:"div",className:"list-panel",fxSpeed:"fast",emptyMsg:c("This list is empty"),noneFoundMsg:c("No matching items found"),searchPlaceholder:c("search"),multiselectActions:[],initialize:function(f,g){f=f||{};if(f.logger){this.logger=f.logger}this.log(this+".initialize:",f);this.fxSpeed=_.has(f,"fxSpeed")?(f.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor=f.searchFor||"";this.indicator=new LoadingIndicator(this.$el);this.selecting=(f.selecting!==undefined)?f.selecting:true;this.selected=f.selected||[];this.lastSelected=null;this.dragItems=f.dragItems||false;this.viewClass=f.viewClass||this.viewClass;this.views=[];this.collection=f.collection||(new this.collectionClass([]));this.filters=f.filters||[];this.$scrollContainer=f.$scrollContainer||this.$scrollContainer;this.title=f.title||"";this.subtitle=f.subtitle||"";this.multiselectActions=f.multiselectActions||this.multiselectActions;this.actionsPopup=null;this._setUpListeners()},freeViews:function(){_.each(this.views,function(f){f.off()});this.views=[];return this},_setUpListeners:function(){this.off();this.on("error",function(g,j,f,i,h){console.error(g,j,f,i,h)},this);this.on("loading",function(){this._showLoadingIndicator("loading...",40)},this);this.on("loading-done",function(){this._hideLoadingIndicator(40)},this);this.once("rendered",function(){this.trigger("rendered:initial",this)},this);if(this.logger){this.on("all",function(f){this.log(this+"",arguments)},this)}this._setUpCollectionListeners();this._setUpViewListeners();return this},_setUpCollectionListeners:function(){this.log(this+"._setUpCollectionListeners",this.collection);this.collection.off();this.collection.on("error",function(g,j,f,i,h){this.trigger("error",g,j,f,i,h)},this);this.collection.on("reset",function(){this.renderItems()},this);this.collection.on("add",this.addItemView,this);this.collection.on("remove",this.removeItemView,this);if(this.logger){this.collection.on("all",function(f){this.info(this+"(collection)",arguments)},this)}return this},_setUpViewListeners:function(){this.log(this+"._setUpViewListeners");this.on("view:selected",function(f,g){if(g&&g.shiftKey&&this.lastSelected){var h=this.viewFromModelId(this.lastSelected);if(h){this.selectRange(f,h)}}else{if(g&&g.altKey&&!this.selecting){this.showSelectors()}}this.selected.push(f.model.id);this.lastSelected=f.model.id},this);this.on("view:de-selected",function(f,g){this.selected=_.without(this.selected,f.model.id)},this)},render:function(g){this.log(this+".render",g);var f=this._buildNewRender();this._setUpBehaviors(f);this._queueNewRender(f,g);return this},_buildNewRender:function(){this.debug(this+"(ListPanel)._buildNewRender");var f=$(this.templates.el({},this));this._renderControls(f);this._renderTitle(f);this._renderSubtitle(f);this._renderSearch(f);this.renderItems(f);return f},_renderControls:function(g){this.debug(this+"(ListPanel)._renderControls");var f=$(this.templates.controls({},this));g.find(".controls").replaceWith(f);return f},_renderTitle:function(f){},_renderSubtitle:function(f){},_queueNewRender:function(g,h){h=(h===undefined)?(this.fxSpeed):(h);var f=this;f.log("_queueNewRender:",g,h);$(f).queue("fx",[function(i){this.$el.fadeOut(h,i)},function(i){f._swapNewRender(g);i()},function(i){this.$el.fadeIn(h,i)},function(i){f.trigger("rendered",f);i()}])},_swapNewRender:function(f){this.$el.empty().attr("class",this.className).append(f.children());if(this.selecting){this.showSelectors(0)}return this},_setUpBehaviors:function(f){f=f||this.$el;f.find(".controls [title]").tooltip({placement:"bottom"});return this},$scrollContainer:function(){return this.$el.parent().parent()},$list:function(f){return(f||this.$el).find("> .list-items")},$messages:function(f){return(f||this.$el).find("> .controls .messages")},$emptyMessage:function(f){return(f||this.$el).find("> .empty-message")},renderItems:function(h){h=h||this.$el;var f=this;f.log(this+".renderItems",h);var g=f.$list(h);f.views=f._filterCollection().map(function(i){return f._createItemView(i).render(0)});g.empty();if(f.views.length){f._attachItems(h);f.$emptyMessage(h).hide()}else{f._renderEmptyMessage(h).show()}return f.views},_filterCollection:function(){var f=this;return f.collection.filter(_.bind(f._filterItem,f))},_filterItem:function(g){var f=this;return(_.every(f.filters.map(function(h){return h.call(g)})))&&(!f.searchFor||g.matchesAll(f.searchFor))},_createItemView:function(h){var i=this._getItemViewClass(h),g=_.extend(this._getItemViewOptions(h),{model:h}),f=new i(g);this._setUpItemViewListeners(f);return f},_getItemViewClass:function(f){return this.viewClass},_getItemViewOptions:function(f){return{fxSpeed:this.fxSpeed,expanded:false,selectable:this.selecting,selected:_.contains(this.selected,f.id),draggable:this.dragItems}},_setUpItemViewListeners:function(g){var f=this;g.on("all",function(){var h=Array.prototype.slice.call(arguments,0);h[0]="view:"+h[0];f.trigger.apply(f,h)});g.on("draggable:dragstart",function(k,h){var i={},j=this.getSelectedModels();if(j.length){i=j.toJSON()}else{i=[h.model.toJSON()]}k.dataTransfer.setData("text",JSON.stringify(i))},this);return f},_attachItems:function(f){this.$list(f).append(this.views.map(function(g){return g.$el}));return this},_renderEmptyMessage:function(f){this.debug("_renderEmptyMessage",f,this.searchFor);var g=this.searchFor?this.noneFoundMsg:this.emptyMsg;return this.$emptyMessage(f).text(g)},expandAll:function(){_.each(this.views,function(f){f.expand()})},collapseAll:function(){_.each(this.views,function(f){f.collapse()})},addItemView:function(i,j,h){this.log(this+".addItemView:",i);var g=this;if(!g._filterItem(i)){return undefined}var f=g._createItemView(i);$(f).queue("fx",[function(k){g.$emptyMessage().fadeOut(g.fxSpeed,k)},function(k){g._attachView(f);k()}]);return f},_attachView:function(g){var f=this;f.views.push(g);f.$list().append(g.render(0).$el.hide());g.$el.slideDown(f.fxSpeed)},removeItemView:function(i,j,h){this.log(this+".removeItemView:",i);var g=this,f=g.viewFromModel(i);if(!f){return undefined}g.views=_.without(g.views,f);$({}).queue("fx",[function(k){f.$el.fadeOut(g.fxSpeed,k)},function(k){f.remove();if(!g.views.length){g._renderEmptyMessage().fadeIn(g.fxSpeed,k)}else{k()}}]);return f},viewFromModelId:function(g){for(var f=0;f<this.views.length;f++){if(this.views[f].model.id===g){return this.views[f]}}return undefined},viewFromModel:function(f){if(!f){return undefined}return this.viewFromModelId(f.id)},viewsWhereModel:function(f){return this.views.filter(function(g){var i=g.model.toJSON();for(var h in f){if(f.hasOwnProperty(h)){if(i[h]!==g.model.get(h)){return false}}}return true})},viewRange:function(i,h){if(i===h){return(i)?([i]):([])}var g=this.views.indexOf(i),f=this.views.indexOf(h);if(g===-1||f===-1){if(g===f){return[]}return(g===-1)?([h]):([i])}return(g<f)?this.views.slice(g,f+1):this.views.slice(f,g+1)},_renderSearch:function(f){f.find(".controls .search-input").searchInput({placeholder:this.searchPlaceholder,initialVal:this.searchFor,onfirstsearch:_.bind(this._firstSearch,this),onsearch:_.bind(this.searchItems,this),onclear:_.bind(this.clearSearch,this)});return f},_firstSearch:function(f){this.log("onFirstSearch",f);return this.searchItems(f)},searchItems:function(f){this.searchFor=f;this.trigger("search:searching",f,this);this.renderItems();this.$("> .controls .search-query").val(f);return this},clearSearch:function(f){this.searchFor="";this.trigger("search:clear",this);this.renderItems();this.$("> .controls .search-query").val("");return this},showSelectors:function(f){f=(f!==undefined)?(f):(this.fxSpeed);this.selecting=true;this.$(".list-actions").slideDown(f);_.each(this.views,function(g){g.showSelector(f)})},hideSelectors:function(f){f=(f!==undefined)?(f):(this.fxSpeed);this.selecting=false;this.$(".list-actions").slideUp(f);_.each(this.views,function(g){g.hideSelector(f)});this.selected=[];this.lastSelected=null},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAll:function(f){_.each(this.views,function(g){g.select(f)})},deselectAll:function(f){this.lastSelected=null;_.each(this.views,function(g){g.deselect(f)})},selectRange:function(h,g){var f=this.viewRange(h,g);_.each(f,function(i){i.select()});return f},getSelectedViews:function(){return _.filter(this.views,function(f){return f.selected})},getSelectedModels:function(){return new this.collection.constructor(_.map(this.getSelectedViews(),function(f){return f.model}))},_showLoadingIndicator:function(g,f,h){this.debug("_showLoadingIndicator",this.indicator,g,f,h);f=(f!==undefined)?(f):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent());this.debug("\t created",this.indicator)}if(!this.$el.is(":visible")){this.indicator.show(0,h)}else{this.$el.fadeOut(f);this.indicator.show(g,f,h)}},_hideLoadingIndicator:function(f,g){this.debug("_hideLoadingIndicator",this.indicator,f,g);f=(f!==undefined)?(f):(this.fxSpeed);if(this.indicator){this.indicator.hide(f,g)}},scrollPosition:function(){return this.$scrollContainer().scrollTop()},scrollTo:function(g,f){f=f||0;this.$scrollContainer().animate({scrollTop:g},f);return this},scrollToTop:function(f){return this.scrollTo(0,f)},scrollToItem:function(f,h){if(!f){return this}var g=f.$el.position().top;return this.scrollTo(g,h)},scrollToId:function(g,f){return this.scrollToItem(this.viewFromModelId(g),f)},events:{"click .select-all":"selectAll","click .deselect-all":"deselectAll"},toString:function(){return"ListPanel("+this.collection+")"}});e.prototype.templates=(function(){var g=b.wrapTemplate(["<div>",'<div class="controls"></div>','<div class="list-items"></div>','<div class="empty-message infomessagesmall"></div>',"</div>"]);var f=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= view.title %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return{el:g,controls:f}}());var a=e.extend({modelCollectionKey:"contents",initialize:function(f){e.prototype.initialize.call(this,f);this.selecting=(f.selecting!==undefined)?f.selecting:false;this.setModel(this.model,f)},setModel:function(g,f){f=f||{};this.debug(this+".setModel:",g,f);this.freeModel();this.freeViews();if(g){var h=this.model?this.model.get("id"):null;this.model=g;if(this.logger){this.model.logger=this.logger}this._setUpModelListeners();this.collection.off();this.collection=(this.model[this.modelCollectionKey])?this.model[this.modelCollectionKey]:(f.collection||(new this.collectionClass([])));this._setUpCollectionListeners();if(h&&g.get("id")!==h){this.trigger("new-model",this)}}return this},freeModel:function(){if(this.model){this.stopListening(this.model)}return this},_setUpModelListeners:function(){this.log(this+"._setUpModelListeners",this.model);this.model.on("error",function(){this.trigger.apply(panel,arguments)},this);return this},_renderControls:function(g){this.debug(this+"(ListPanel)._renderControls");var h=this.model?this.model.toJSON():{},f=$(this.templates.controls(h,this));g.find(".controls").replaceWith(f);return f},toString:function(){return"ModelListPanel("+this.model+")"}});a.prototype.templates=(function(){var f=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= model.name %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return _.extend(_.clone(e.prototype.templates),{controls:f})}());return{ListPanel:e,ModelListPanel:a}});
\ No newline at end of file
+define(["mvc/list/list-item","jq-plugins/ui/loading-indicator","mvc/base-mvc","utils/localization","jq-plugins/ui/search-input"],function(d,f,b,c){var e=Backbone.View.extend(b.LoggableMixin).extend({viewClass:d.ListItemView,collectionClass:Backbone.Collection,tagName:"div",className:"list-panel",fxSpeed:"fast",emptyMsg:c("This list is empty"),noneFoundMsg:c("No matching items found"),searchPlaceholder:c("search"),multiselectActions:[],initialize:function(g,h){g=g||{};if(g.logger){this.logger=g.logger}this.log(this+".initialize:",g);this.fxSpeed=_.has(g,"fxSpeed")?(g.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor=g.searchFor||"";this.indicator=new f(this.$el);this.selecting=(g.selecting!==undefined)?g.selecting:true;this.selected=g.selected||[];this.lastSelected=null;this.dragItems=g.dragItems||false;this.viewClass=g.viewClass||this.viewClass;this.views=[];this.collection=g.collection||(new this.collectionClass([]));this.filters=g.filters||[];this.$scrollContainer=g.$scrollContainer||this.$scrollContainer;this.title=g.title||"";this.subtitle=g.subtitle||"";this.multiselectActions=g.multiselectActions||this.multiselectActions;this.actionsPopup=null;this._setUpListeners()},freeViews:function(){_.each(this.views,function(g){g.off()});this.views=[];return this},_setUpListeners:function(){this.off();this.on("error",function(h,k,g,j,i){console.error(h,k,g,j,i)},this);this.on("loading",function(){this._showLoadingIndicator("loading...",40)},this);this.on("loading-done",function(){this._hideLoadingIndicator(40)},this);this.once("rendered",function(){this.trigger("rendered:initial",this)},this);if(this.logger){this.on("all",function(g){this.log(this+"",arguments)},this)}this._setUpCollectionListeners();this._setUpViewListeners();return this},_setUpCollectionListeners:function(){this.log(this+"._setUpCollectionListeners",this.collection);this.collection.off();this.collection.on("error",function(h,k,g,j,i){this.trigger("error",h,k,g,j,i)},this);this.collection.on("reset",function(){this.renderItems()},this);this.collection.on("add",this.addItemView,this);this.collection.on("remove",this.removeItemView,this);if(this.logger){this.collection.on("all",function(g){this.info(this+"(collection)",arguments)},this)}return this},_setUpViewListeners:function(){this.log(this+"._setUpViewListeners");this.on("view:selected",function(g,h){if(h&&h.shiftKey&&this.lastSelected){var i=this.viewFromModelId(this.lastSelected);if(i){this.selectRange(g,i)}}else{if(h&&h.altKey&&!this.selecting){this.showSelectors()}}this.selected.push(g.model.id);this.lastSelected=g.model.id},this);this.on("view:de-selected",function(g,h){this.selected=_.without(this.selected,g.model.id)},this)},render:function(h){this.log(this+".render",h);var g=this._buildNewRender();this._setUpBehaviors(g);this._queueNewRender(g,h);return this},_buildNewRender:function(){this.debug(this+"(ListPanel)._buildNewRender");var g=$(this.templates.el({},this));this._renderControls(g);this._renderTitle(g);this._renderSubtitle(g);this._renderSearch(g);this.renderItems(g);return g},_renderControls:function(h){this.debug(this+"(ListPanel)._renderControls");var g=$(this.templates.controls({},this));h.find(".controls").replaceWith(g);return g},_renderTitle:function(g){},_renderSubtitle:function(g){},_queueNewRender:function(h,i){i=(i===undefined)?(this.fxSpeed):(i);var g=this;g.log("_queueNewRender:",h,i);$(g).queue("fx",[function(j){this.$el.fadeOut(i,j)},function(j){g._swapNewRender(h);j()},function(j){this.$el.fadeIn(i,j)},function(j){g.trigger("rendered",g);j()}])},_swapNewRender:function(g){this.$el.empty().attr("class",this.className).append(g.children());if(this.selecting){this.showSelectors(0)}return this},_setUpBehaviors:function(g){g=g||this.$el;g.find(".controls [title]").tooltip({placement:"bottom"});return this},$scrollContainer:function(){return this.$el.parent().parent()},$list:function(g){return(g||this.$el).find("> .list-items")},$messages:function(g){return(g||this.$el).find("> .controls .messages")},$emptyMessage:function(g){return(g||this.$el).find("> .empty-message")},renderItems:function(i){i=i||this.$el;var g=this;g.log(this+".renderItems",i);var h=g.$list(i);g.views=g._filterCollection().map(function(j){return g._createItemView(j).render(0)});h.empty();if(g.views.length){g._attachItems(i);g.$emptyMessage(i).hide()}else{g._renderEmptyMessage(i).show()}return g.views},_filterCollection:function(){var g=this;return g.collection.filter(_.bind(g._filterItem,g))},_filterItem:function(h){var g=this;return(_.every(g.filters.map(function(i){return i.call(h)})))&&(!g.searchFor||h.matchesAll(g.searchFor))},_createItemView:function(i){var j=this._getItemViewClass(i),h=_.extend(this._getItemViewOptions(i),{model:i}),g=new j(h);this._setUpItemViewListeners(g);return g},_getItemViewClass:function(g){return this.viewClass},_getItemViewOptions:function(g){return{fxSpeed:this.fxSpeed,expanded:false,selectable:this.selecting,selected:_.contains(this.selected,g.id),draggable:this.dragItems}},_setUpItemViewListeners:function(h){var g=this;h.on("all",function(){var i=Array.prototype.slice.call(arguments,0);i[0]="view:"+i[0];g.trigger.apply(g,i)});h.on("draggable:dragstart",function(l,i){var j={},k=this.getSelectedModels();if(k.length){j=k.toJSON()}else{j=[i.model.toJSON()]}l.dataTransfer.setData("text",JSON.stringify(j))},this);return g},_attachItems:function(g){this.$list(g).append(this.views.map(function(h){return h.$el}));return this},_renderEmptyMessage:function(g){this.debug("_renderEmptyMessage",g,this.searchFor);var h=this.searchFor?this.noneFoundMsg:this.emptyMsg;return this.$emptyMessage(g).text(h)},expandAll:function(){_.each(this.views,function(g){g.expand()})},collapseAll:function(){_.each(this.views,function(g){g.collapse()})},addItemView:function(j,k,i){this.log(this+".addItemView:",j);var h=this;if(!h._filterItem(j)){return undefined}var g=h._createItemView(j);$(g).queue("fx",[function(l){h.$emptyMessage().fadeOut(h.fxSpeed,l)},function(l){h._attachView(g);l()}]);return g},_attachView:function(h){var g=this;g.views.push(h);g.$list().append(h.render(0).$el.hide());h.$el.slideDown(g.fxSpeed)},removeItemView:function(j,k,i){this.log(this+".removeItemView:",j);var h=this,g=h.viewFromModel(j);if(!g){return undefined}h.views=_.without(h.views,g);$({}).queue("fx",[function(l){g.$el.fadeOut(h.fxSpeed,l)},function(l){g.remove();if(!h.views.length){h._renderEmptyMessage().fadeIn(h.fxSpeed,l)}else{l()}}]);return g},viewFromModelId:function(h){for(var g=0;g<this.views.length;g++){if(this.views[g].model.id===h){return this.views[g]}}return undefined},viewFromModel:function(g){if(!g){return undefined}return this.viewFromModelId(g.id)},viewsWhereModel:function(g){return this.views.filter(function(h){var j=h.model.toJSON();for(var i in g){if(g.hasOwnProperty(i)){if(j[i]!==h.model.get(i)){return false}}}return true})},viewRange:function(j,i){if(j===i){return(j)?([j]):([])}var h=this.views.indexOf(j),g=this.views.indexOf(i);if(h===-1||g===-1){if(h===g){return[]}return(h===-1)?([i]):([j])}return(h<g)?this.views.slice(h,g+1):this.views.slice(g,h+1)},_renderSearch:function(g){g.find(".controls .search-input").searchInput({placeholder:this.searchPlaceholder,initialVal:this.searchFor,onfirstsearch:_.bind(this._firstSearch,this),onsearch:_.bind(this.searchItems,this),onclear:_.bind(this.clearSearch,this)});return g},_firstSearch:function(g){this.log("onFirstSearch",g);return this.searchItems(g)},searchItems:function(g){this.searchFor=g;this.trigger("search:searching",g,this);this.renderItems();this.$("> .controls .search-query").val(g);return this},clearSearch:function(g){this.searchFor="";this.trigger("search:clear",this);this.renderItems();this.$("> .controls .search-query").val("");return this},showSelectors:function(g){g=(g!==undefined)?(g):(this.fxSpeed);this.selecting=true;this.$(".list-actions").slideDown(g);_.each(this.views,function(h){h.showSelector(g)})},hideSelectors:function(g){g=(g!==undefined)?(g):(this.fxSpeed);this.selecting=false;this.$(".list-actions").slideUp(g);_.each(this.views,function(h){h.hideSelector(g)});this.selected=[];this.lastSelected=null},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAll:function(g){_.each(this.views,function(h){h.select(g)})},deselectAll:function(g){this.lastSelected=null;_.each(this.views,function(h){h.deselect(g)})},selectRange:function(i,h){var g=this.viewRange(i,h);_.each(g,function(j){j.select()});return g},getSelectedViews:function(){return _.filter(this.views,function(g){return g.selected})},getSelectedModels:function(){return new this.collection.constructor(_.map(this.getSelectedViews(),function(g){return g.model}))},_showLoadingIndicator:function(h,g,i){this.debug("_showLoadingIndicator",this.indicator,h,g,i);g=(g!==undefined)?(g):(this.fxSpeed);if(!this.indicator){this.indicator=new f(this.$el,this.$el.parent());this.debug("\t created",this.indicator)}if(!this.$el.is(":visible")){this.indicator.show(0,i)}else{this.$el.fadeOut(g);this.indicator.show(h,g,i)}},_hideLoadingIndicator:function(g,h){this.debug("_hideLoadingIndicator",this.indicator,g,h);g=(g!==undefined)?(g):(this.fxSpeed);if(this.indicator){this.indicator.hide(g,h)}},scrollPosition:function(){return this.$scrollContainer().scrollTop()},scrollTo:function(h,g){g=g||0;this.$scrollContainer().animate({scrollTop:h},g);return this},scrollToTop:function(g){return this.scrollTo(0,g)},scrollToItem:function(g,i){if(!g){return this}var h=g.$el.position().top;return this.scrollTo(h,i)},scrollToId:function(h,g){return this.scrollToItem(this.viewFromModelId(h),g)},events:{"click .select-all":"selectAll","click .deselect-all":"deselectAll"},toString:function(){return"ListPanel("+this.collection+")"}});e.prototype.templates=(function(){var h=b.wrapTemplate(["<div>",'<div class="controls"></div>','<div class="list-items"></div>','<div class="empty-message infomessagesmall"></div>',"</div>"]);var g=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= view.title %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return{el:h,controls:g}}());var a=e.extend({modelCollectionKey:"contents",initialize:function(g){e.prototype.initialize.call(this,g);this.selecting=(g.selecting!==undefined)?g.selecting:false;this.setModel(this.model,g)},setModel:function(h,g){g=g||{};this.debug(this+".setModel:",h,g);this.freeModel();this.freeViews();if(h){var i=this.model?this.model.get("id"):null;this.model=h;if(this.logger){this.model.logger=this.logger}this._setUpModelListeners();this.collection.off();this.collection=(this.model[this.modelCollectionKey])?this.model[this.modelCollectionKey]:(g.collection||(new this.collectionClass([])));this._setUpCollectionListeners();if(i&&h.get("id")!==i){this.trigger("new-model",this)}}return this},freeModel:function(){if(this.model){this.stopListening(this.model)}return this},_setUpModelListeners:function(){this.log(this+"._setUpModelListeners",this.model);this.model.on("error",function(){this.trigger.apply(panel,arguments)},this);return this},_renderControls:function(h){this.debug(this+"(ListPanel)._renderControls");var i=this.model?this.model.toJSON():{},g=$(this.templates.controls(i,this));h.find(".controls").replaceWith(g);return g},toString:function(){return"ModelListPanel("+this.model+")"}});a.prototype.templates=(function(){var g=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= model.name %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return _.extend(_.clone(e.prototype.templates),{controls:g})}());return{ListPanel:e,ModelListPanel:a}});
\ No newline at end of file
diff -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 -r 558cfd39bb3fc40486c894b77b55143785c0a0b6 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";a.parent().find(".loading-indicator").remove();b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b};
\ No newline at end of file
+var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/bce30adc75e9/
Changeset: bce30adc75e9
Branch: next-stable
User: carlfeberhard
Date: 2014-12-09 17:18:31+00:00
Summary: Apply stable 782cf1a to next-stable
Affected #: 1 file
diff -r 59d5d556b6647c245fc26f331eb01e9d597c698a -r bce30adc75e94c99fc8fd53f3dee75a26b6c8e86 templates/webapps/galaxy/galaxy.masthead.mako
--- a/templates/webapps/galaxy/galaxy.masthead.mako
+++ b/templates/webapps/galaxy/galaxy.masthead.mako
@@ -1,4 +1,4 @@
-<%namespace file="/galaxy_client_app.mako" import="get_user_json" />
+<%namespace file="/galaxy_client_app.mako" import="get_user_dict" />
## masthead head generator
<%def name="load(active_view = None)">
@@ -34,7 +34,7 @@
'requests' : bool(trans.user and (trans.user.requests or trans.app.security_agent.get_accessible_request_types(trans, trans.user))),
'email' : trans.user.email if (trans.user) else "",
'valid' : bool(trans.user != None),
- 'json' : get_user_json()
+ 'json' : get_user_dict()
}
}
%>
https://bitbucket.org/galaxy/galaxy-central/commits/be3f185f9e75/
Changeset: be3f185f9e75
User: carlfeberhard
Date: 2014-12-09 17:18:44+00:00
Summary: merge
Affected #: 1 file
diff -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 -r be3f185f9e75c4a7fc8ecf689ad0d26b98275026 templates/webapps/galaxy/galaxy.masthead.mako
--- a/templates/webapps/galaxy/galaxy.masthead.mako
+++ b/templates/webapps/galaxy/galaxy.masthead.mako
@@ -1,4 +1,4 @@
-<%namespace file="/galaxy_client_app.mako" import="get_user_json" />
+<%namespace file="/galaxy_client_app.mako" import="get_user_dict" />
## masthead head generator
<%def name="load(active_view = None)">
@@ -34,7 +34,7 @@
'requests' : bool(trans.user and (trans.user.requests or trans.app.security_agent.get_accessible_request_types(trans, trans.user))),
'email' : trans.user.email if (trans.user) else "",
'valid' : bool(trans.user != None),
- 'json' : get_user_json()
+ 'json' : get_user_dict()
}
}
%>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: Client build: modularize search input plugin from ui.js
by commits-noreply@bitbucket.org 09 Dec '14
by commits-noreply@bitbucket.org 09 Dec '14
09 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/33f1bf5be91b/
Changeset: 33f1bf5be91b
User: carlfeberhard
Date: 2014-12-09 17:16:01+00:00
Summary: Client build: modularize search input plugin from ui.js
Affected #: 19 files
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 client/galaxy/scripts/jq-plugins/ui/search-input.js
--- /dev/null
+++ b/client/galaxy/scripts/jq-plugins/ui/search-input.js
@@ -0,0 +1,159 @@
+// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
+// Uses AMD or browser globals to create a jQuery plugin.
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
+ // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
+ // relying on jquery being loaded globally* in order to preserve plugins.
+ define([], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+
+}(function () {
+ var _l = window._l || function( s ){ return s; };
+
+ /** searchInput: (jQuery plugin)
+ * Creates a search input, a clear button, and loading indicator
+ * within the selected node.
+ *
+ * When the user either presses return or enters some minimal number
+ * of characters, a callback is called. Pressing ESC when the input
+ * is focused will clear the input and call a separate callback.
+ */
+ function searchInput( parentNode, options ){
+//TODO: consolidate with tool menu functionality, use there
+ var KEYCODE_ESC = 27,
+ KEYCODE_RETURN = 13,
+ $parentNode = $( parentNode ),
+ firstSearch = true,
+ defaults = {
+ initialVal : '',
+ name : 'search',
+ placeholder : 'search',
+ classes : '',
+ onclear : function(){},
+ onfirstsearch : null,
+ onsearch : function( inputVal ){},
+ minSearchLen : 0,
+ escWillClear : true,
+ oninit : function(){}
+ };
+
+ // .................................................................... input rendering and events
+ // visually clear the search, trigger an event, and call the callback
+ function clearSearchInput( event ){
+ var $input = $( this ).parent().children( 'input' );
+ //console.debug( this, 'clear', $input );
+ $input.focus().val( '' ).trigger( 'clear:searchInput' );
+ options.onclear();
+ }
+
+ // search for searchTerms, trigger an event, call the appropo callback (based on whether this is the first)
+ function search( event, searchTerms ){
+ //console.debug( this, 'searching', searchTerms );
+ //TODO: I don't think this is classic jq custom event form? search.searchInput?
+ $( this ).trigger( 'search:searchInput', searchTerms );
+ if( typeof options.onfirstsearch === 'function' && firstSearch ){
+ firstSearch = false;
+ options.onfirstsearch( searchTerms );
+ } else {
+ options.onsearch( searchTerms );
+ }
+ }
+
+ // .................................................................... input rendering and events
+ function inputTemplate(){
+ // class search-query is bootstrap 2.3 style that now lives in base.less
+ return [ '<input type="text" name="', options.name, '" placeholder="', options.placeholder, '" ',
+ 'class="search-query ', options.classes, '" ', '/>' ].join( '' );
+ }
+
+ // the search input that responds to keyboard events and displays the search value
+ function $input(){
+ return $( inputTemplate() )
+ // select all text on a focus
+ .focus( function( event ){
+ $( this ).select();
+ })
+ // attach behaviors to esc, return if desired, search on some min len string
+ .keyup( function( event ){
+ event.preventDefault();
+ event.stopPropagation();
+//TODO: doesn't work
+ if( !$( this ).val() ){ $( this ).blur(); }
+
+ // esc key will clear if desired
+ if( event.which === KEYCODE_ESC && options.escWillClear ){
+ clearSearchInput.call( this, event );
+
+ } else {
+ var searchTerms = $( this ).val();
+ // return key or the search string len > minSearchLen (if not 0) triggers search
+ if( ( event.which === KEYCODE_RETURN )
+ || ( options.minSearchLen && searchTerms.length >= options.minSearchLen ) ){
+ search.call( this, event, searchTerms );
+ } else if( !searchTerms.length ){
+ clearSearchInput.call( this, event );
+ }
+ }
+ })
+ .on( 'change', function( event ){
+ search.call( this, event, $( this ).val() );
+ })
+ .val( options.initialVal );
+ }
+
+ // .................................................................... clear button rendering and events
+ // a button for clearing the search bar, placed on the right hand side
+ function $clearBtn(){
+ return $([ '<span class="search-clear fa fa-times-circle" ',
+ 'title="', _l( 'clear search (esc)' ), '"></span>' ].join('') )
+ .tooltip({ placement: 'bottom' })
+ .click( function( event ){
+ clearSearchInput.call( this, event );
+ });
+ }
+
+ // .................................................................... loadingIndicator rendering
+ // a button for clearing the search bar, placed on the right hand side
+ function $loadingIndicator(){
+ return $([ '<span class="search-loading fa fa-spinner fa-spin" ',
+ 'title="', _l( 'loading...' ), '"></span>' ].join('') )
+ .hide().tooltip({ placement: 'bottom' });
+ }
+
+ // .................................................................... commands
+ // visually swap the load, clear buttons
+ function toggleLoadingIndicator(){
+ $parentNode.find( '.search-loading' ).toggle();
+ $parentNode.find( '.search-clear' ).toggle();
+ }
+
+ // .................................................................... init
+ // string command (not constructor)
+ if( jQuery.type( options ) === 'string' ){
+ if( options === 'toggle-loading' ){
+ toggleLoadingIndicator();
+ }
+ return $parentNode;
+ }
+
+ // initial render
+ if( jQuery.type( options ) === 'object' ){
+ options = jQuery.extend( true, {}, defaults, options );
+ }
+ //NOTE: prepended
+ return $parentNode.addClass( 'search-input' ).prepend([ $input(), $clearBtn(), $loadingIndicator() ]);
+ }
+
+ // as jq plugin
+ jQuery.fn.extend({
+ searchInput : function $searchInput( options ){
+ return this.each( function(){
+ return searchInput( this, options );
+ });
+ }
+ });
+}));
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 client/galaxy/scripts/mvc/history/history-panel.js
--- a/client/galaxy/scripts/mvc/history/history-panel.js
+++ b/client/galaxy/scripts/mvc/history/history-panel.js
@@ -7,7 +7,8 @@
"mvc/collection/collection-panel",
"mvc/user/user-model",
"mvc/base-mvc",
- "utils/localization"
+ "utils/localization",
+ "jq-plugins/ui/search-input"
], function(
LIST_PANEL,
HISTORY_MODEL,
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 client/galaxy/scripts/mvc/history/multi-panel.js
--- a/client/galaxy/scripts/mvc/history/multi-panel.js
+++ b/client/galaxy/scripts/mvc/history/multi-panel.js
@@ -3,7 +3,8 @@
"mvc/history/history-panel-edit",
"mvc/base-mvc",
"utils/ajax-queue",
- "jq-plugins/ui/mode-button"
+ "jq-plugins/ui/mode-button",
+ "jq-plugins/ui/search-input"
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
window.HISTORY_MODEL = HISTORY_MODEL;
//==============================================================================
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 client/galaxy/scripts/mvc/list/list-panel.js
--- a/client/galaxy/scripts/mvc/list/list-panel.js
+++ b/client/galaxy/scripts/mvc/list/list-panel.js
@@ -1,7 +1,8 @@
define([
"mvc/list/list-item",
"mvc/base-mvc",
- "utils/localization"
+ "utils/localization",
+ "jq-plugins/ui/search-input"
], function( LIST_ITEM, BASE_MVC, _l ){
/* ============================================================================
TODO:
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 client/galaxy/scripts/mvc/ui.js
--- a/client/galaxy/scripts/mvc/ui.js
+++ b/client/galaxy/scripts/mvc/ui.js
@@ -601,151 +601,3 @@
};
return self;
}
-
-//==============================================================================
-(function(){
- /** searchInput: (jQuery plugin)
- * Creates a search input, a clear button, and loading indicator
- * within the selected node.
- *
- * When the user either presses return or enters some minimal number
- * of characters, a callback is called. Pressing ESC when the input
- * is focused will clear the input and call a separate callback.
- */
- var _l = window._l || function( s ){ return s; };
-
- // contructor
- function searchInput( parentNode, options ){
-//TODO: consolidate with tool menu functionality, use there
- var KEYCODE_ESC = 27,
- KEYCODE_RETURN = 13,
- $parentNode = $( parentNode ),
- firstSearch = true,
- defaults = {
- initialVal : '',
- name : 'search',
- placeholder : 'search',
- classes : '',
- onclear : function(){},
- onfirstsearch : null,
- onsearch : function( inputVal ){},
- minSearchLen : 0,
- escWillClear : true,
- oninit : function(){}
- };
-
- // .................................................................... input rendering and events
- // visually clear the search, trigger an event, and call the callback
- function clearSearchInput( event ){
- var $input = $( this ).parent().children( 'input' );
- //console.debug( this, 'clear', $input );
- $input.focus().val( '' ).trigger( 'clear:searchInput' );
- options.onclear();
- }
-
- // search for searchTerms, trigger an event, call the appropo callback (based on whether this is the first)
- function search( event, searchTerms ){
- //console.debug( this, 'searching', searchTerms );
- $( this ).trigger( 'search:searchInput', searchTerms );
- if( typeof options.onfirstsearch === 'function' && firstSearch ){
- firstSearch = false;
- options.onfirstsearch( searchTerms );
- } else {
- options.onsearch( searchTerms );
- }
- }
-
- // .................................................................... input rendering and events
- function inputTemplate(){
- // class search-query is bootstrap 2.3 style that now lives in base.less
- return [ '<input type="text" name="', options.name, '" placeholder="', options.placeholder, '" ',
- 'class="search-query ', options.classes, '" ', '/>' ].join( '' );
- }
-
- // the search input that responds to keyboard events and displays the search value
- function $input(){
- return $( inputTemplate() )
- // select all text on a focus
- .focus( function( event ){
- $( this ).select();
- })
- // attach behaviors to esc, return if desired, search on some min len string
- .keyup( function( event ){
- event.preventDefault();
- event.stopPropagation();
-//TODO: doesn't work
- if( !$( this ).val() ){ $( this ).blur(); }
-
- // esc key will clear if desired
- if( event.which === KEYCODE_ESC && options.escWillClear ){
- clearSearchInput.call( this, event );
-
- } else {
- var searchTerms = $( this ).val();
- // return key or the search string len > minSearchLen (if not 0) triggers search
- if( ( event.which === KEYCODE_RETURN )
- || ( options.minSearchLen && searchTerms.length >= options.minSearchLen ) ){
- search.call( this, event, searchTerms );
- } else if( !searchTerms.length ){
- clearSearchInput.call( this, event );
- }
- }
- })
- .on( 'change', function( event ){
- search.call( this, event, $( this ).val() );
- })
- .val( options.initialVal );
- }
-
- // .................................................................... clear button rendering and events
- // a button for clearing the search bar, placed on the right hand side
- function $clearBtn(){
- return $([ '<span class="search-clear fa fa-times-circle" ',
- 'title="', _l( 'clear search (esc)' ), '"></span>' ].join('') )
- .tooltip({ placement: 'bottom' })
- .click( function( event ){
- clearSearchInput.call( this, event );
- });
- }
-
- // .................................................................... loadingIndicator rendering
- // a button for clearing the search bar, placed on the right hand side
- function $loadingIndicator(){
- return $([ '<span class="search-loading fa fa-spinner fa-spin" ',
- 'title="', _l( 'loading...' ), '"></span>' ].join('') )
- .hide().tooltip({ placement: 'bottom' });
- }
-
- // .................................................................... commands
- // visually swap the load, clear buttons
- function toggleLoadingIndicator(){
- $parentNode.find( '.search-loading' ).toggle();
- $parentNode.find( '.search-clear' ).toggle();
- }
-
- // .................................................................... init
- // string command (not constructor)
- if( jQuery.type( options ) === 'string' ){
- if( options === 'toggle-loading' ){
- toggleLoadingIndicator();
- }
- return $parentNode;
- }
-
- // initial render
- if( jQuery.type( options ) === 'object' ){
- options = jQuery.extend( true, {}, defaults, options );
- }
- //NOTE: prepended
- return $parentNode.addClass( 'search-input' ).prepend([ $input(), $clearBtn(), $loadingIndicator() ]);
- }
-
- // as jq plugin
- jQuery.fn.extend({
- searchInput : function $searchInput( options ){
- return this.each( function(){
- return searchInput( this, options );
- });
- }
- });
-}());
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/jq-plugins/ui/search-input.js
--- /dev/null
+++ b/static/scripts/jq-plugins/ui/search-input.js
@@ -0,0 +1,159 @@
+// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js
+// Uses AMD or browser globals to create a jQuery plugin.
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ //TODO: So...this turns out to be an all or nothing thing. If I load jQuery in the define below, it will
+ // (of course) wipe the old jquery *and all the plugins loaded into it*. So the define below *is still
+ // relying on jquery being loaded globally* in order to preserve plugins.
+ define([], factory);
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+
+}(function () {
+ var _l = window._l || function( s ){ return s; };
+
+ /** searchInput: (jQuery plugin)
+ * Creates a search input, a clear button, and loading indicator
+ * within the selected node.
+ *
+ * When the user either presses return or enters some minimal number
+ * of characters, a callback is called. Pressing ESC when the input
+ * is focused will clear the input and call a separate callback.
+ */
+ function searchInput( parentNode, options ){
+//TODO: consolidate with tool menu functionality, use there
+ var KEYCODE_ESC = 27,
+ KEYCODE_RETURN = 13,
+ $parentNode = $( parentNode ),
+ firstSearch = true,
+ defaults = {
+ initialVal : '',
+ name : 'search',
+ placeholder : 'search',
+ classes : '',
+ onclear : function(){},
+ onfirstsearch : null,
+ onsearch : function( inputVal ){},
+ minSearchLen : 0,
+ escWillClear : true,
+ oninit : function(){}
+ };
+
+ // .................................................................... input rendering and events
+ // visually clear the search, trigger an event, and call the callback
+ function clearSearchInput( event ){
+ var $input = $( this ).parent().children( 'input' );
+ //console.debug( this, 'clear', $input );
+ $input.focus().val( '' ).trigger( 'clear:searchInput' );
+ options.onclear();
+ }
+
+ // search for searchTerms, trigger an event, call the appropo callback (based on whether this is the first)
+ function search( event, searchTerms ){
+ //console.debug( this, 'searching', searchTerms );
+ //TODO: I don't think this is classic jq custom event form? search.searchInput?
+ $( this ).trigger( 'search:searchInput', searchTerms );
+ if( typeof options.onfirstsearch === 'function' && firstSearch ){
+ firstSearch = false;
+ options.onfirstsearch( searchTerms );
+ } else {
+ options.onsearch( searchTerms );
+ }
+ }
+
+ // .................................................................... input rendering and events
+ function inputTemplate(){
+ // class search-query is bootstrap 2.3 style that now lives in base.less
+ return [ '<input type="text" name="', options.name, '" placeholder="', options.placeholder, '" ',
+ 'class="search-query ', options.classes, '" ', '/>' ].join( '' );
+ }
+
+ // the search input that responds to keyboard events and displays the search value
+ function $input(){
+ return $( inputTemplate() )
+ // select all text on a focus
+ .focus( function( event ){
+ $( this ).select();
+ })
+ // attach behaviors to esc, return if desired, search on some min len string
+ .keyup( function( event ){
+ event.preventDefault();
+ event.stopPropagation();
+//TODO: doesn't work
+ if( !$( this ).val() ){ $( this ).blur(); }
+
+ // esc key will clear if desired
+ if( event.which === KEYCODE_ESC && options.escWillClear ){
+ clearSearchInput.call( this, event );
+
+ } else {
+ var searchTerms = $( this ).val();
+ // return key or the search string len > minSearchLen (if not 0) triggers search
+ if( ( event.which === KEYCODE_RETURN )
+ || ( options.minSearchLen && searchTerms.length >= options.minSearchLen ) ){
+ search.call( this, event, searchTerms );
+ } else if( !searchTerms.length ){
+ clearSearchInput.call( this, event );
+ }
+ }
+ })
+ .on( 'change', function( event ){
+ search.call( this, event, $( this ).val() );
+ })
+ .val( options.initialVal );
+ }
+
+ // .................................................................... clear button rendering and events
+ // a button for clearing the search bar, placed on the right hand side
+ function $clearBtn(){
+ return $([ '<span class="search-clear fa fa-times-circle" ',
+ 'title="', _l( 'clear search (esc)' ), '"></span>' ].join('') )
+ .tooltip({ placement: 'bottom' })
+ .click( function( event ){
+ clearSearchInput.call( this, event );
+ });
+ }
+
+ // .................................................................... loadingIndicator rendering
+ // a button for clearing the search bar, placed on the right hand side
+ function $loadingIndicator(){
+ return $([ '<span class="search-loading fa fa-spinner fa-spin" ',
+ 'title="', _l( 'loading...' ), '"></span>' ].join('') )
+ .hide().tooltip({ placement: 'bottom' });
+ }
+
+ // .................................................................... commands
+ // visually swap the load, clear buttons
+ function toggleLoadingIndicator(){
+ $parentNode.find( '.search-loading' ).toggle();
+ $parentNode.find( '.search-clear' ).toggle();
+ }
+
+ // .................................................................... init
+ // string command (not constructor)
+ if( jQuery.type( options ) === 'string' ){
+ if( options === 'toggle-loading' ){
+ toggleLoadingIndicator();
+ }
+ return $parentNode;
+ }
+
+ // initial render
+ if( jQuery.type( options ) === 'object' ){
+ options = jQuery.extend( true, {}, defaults, options );
+ }
+ //NOTE: prepended
+ return $parentNode.addClass( 'search-input' ).prepend([ $input(), $clearBtn(), $loadingIndicator() ]);
+ }
+
+ // as jq plugin
+ jQuery.fn.extend({
+ searchInput : function $searchInput( options ){
+ return this.each( function(){
+ return searchInput( this, options );
+ });
+ }
+ });
+}));
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/mvc/history/history-panel.js
--- a/static/scripts/mvc/history/history-panel.js
+++ b/static/scripts/mvc/history/history-panel.js
@@ -7,7 +7,8 @@
"mvc/collection/collection-panel",
"mvc/user/user-model",
"mvc/base-mvc",
- "utils/localization"
+ "utils/localization",
+ "jq-plugins/ui/search-input"
], function(
LIST_PANEL,
HISTORY_MODEL,
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/mvc/history/multi-panel.js
--- a/static/scripts/mvc/history/multi-panel.js
+++ b/static/scripts/mvc/history/multi-panel.js
@@ -3,7 +3,8 @@
"mvc/history/history-panel-edit",
"mvc/base-mvc",
"utils/ajax-queue",
- "jq-plugins/ui/mode-button"
+ "jq-plugins/ui/mode-button",
+ "jq-plugins/ui/search-input"
], function( HISTORY_MODEL, HPANEL_EDIT, baseMVC, ajaxQueue ){
window.HISTORY_MODEL = HISTORY_MODEL;
//==============================================================================
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/mvc/list/list-panel.js
--- a/static/scripts/mvc/list/list-panel.js
+++ b/static/scripts/mvc/list/list-panel.js
@@ -1,7 +1,8 @@
define([
"mvc/list/list-item",
"mvc/base-mvc",
- "utils/localization"
+ "utils/localization",
+ "jq-plugins/ui/search-input"
], function( LIST_ITEM, BASE_MVC, _l ){
/* ============================================================================
TODO:
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -601,151 +601,3 @@
};
return self;
}
-
-//==============================================================================
-(function(){
- /** searchInput: (jQuery plugin)
- * Creates a search input, a clear button, and loading indicator
- * within the selected node.
- *
- * When the user either presses return or enters some minimal number
- * of characters, a callback is called. Pressing ESC when the input
- * is focused will clear the input and call a separate callback.
- */
- var _l = window._l || function( s ){ return s; };
-
- // contructor
- function searchInput( parentNode, options ){
-//TODO: consolidate with tool menu functionality, use there
- var KEYCODE_ESC = 27,
- KEYCODE_RETURN = 13,
- $parentNode = $( parentNode ),
- firstSearch = true,
- defaults = {
- initialVal : '',
- name : 'search',
- placeholder : 'search',
- classes : '',
- onclear : function(){},
- onfirstsearch : null,
- onsearch : function( inputVal ){},
- minSearchLen : 0,
- escWillClear : true,
- oninit : function(){}
- };
-
- // .................................................................... input rendering and events
- // visually clear the search, trigger an event, and call the callback
- function clearSearchInput( event ){
- var $input = $( this ).parent().children( 'input' );
- //console.debug( this, 'clear', $input );
- $input.focus().val( '' ).trigger( 'clear:searchInput' );
- options.onclear();
- }
-
- // search for searchTerms, trigger an event, call the appropo callback (based on whether this is the first)
- function search( event, searchTerms ){
- //console.debug( this, 'searching', searchTerms );
- $( this ).trigger( 'search:searchInput', searchTerms );
- if( typeof options.onfirstsearch === 'function' && firstSearch ){
- firstSearch = false;
- options.onfirstsearch( searchTerms );
- } else {
- options.onsearch( searchTerms );
- }
- }
-
- // .................................................................... input rendering and events
- function inputTemplate(){
- // class search-query is bootstrap 2.3 style that now lives in base.less
- return [ '<input type="text" name="', options.name, '" placeholder="', options.placeholder, '" ',
- 'class="search-query ', options.classes, '" ', '/>' ].join( '' );
- }
-
- // the search input that responds to keyboard events and displays the search value
- function $input(){
- return $( inputTemplate() )
- // select all text on a focus
- .focus( function( event ){
- $( this ).select();
- })
- // attach behaviors to esc, return if desired, search on some min len string
- .keyup( function( event ){
- event.preventDefault();
- event.stopPropagation();
-//TODO: doesn't work
- if( !$( this ).val() ){ $( this ).blur(); }
-
- // esc key will clear if desired
- if( event.which === KEYCODE_ESC && options.escWillClear ){
- clearSearchInput.call( this, event );
-
- } else {
- var searchTerms = $( this ).val();
- // return key or the search string len > minSearchLen (if not 0) triggers search
- if( ( event.which === KEYCODE_RETURN )
- || ( options.minSearchLen && searchTerms.length >= options.minSearchLen ) ){
- search.call( this, event, searchTerms );
- } else if( !searchTerms.length ){
- clearSearchInput.call( this, event );
- }
- }
- })
- .on( 'change', function( event ){
- search.call( this, event, $( this ).val() );
- })
- .val( options.initialVal );
- }
-
- // .................................................................... clear button rendering and events
- // a button for clearing the search bar, placed on the right hand side
- function $clearBtn(){
- return $([ '<span class="search-clear fa fa-times-circle" ',
- 'title="', _l( 'clear search (esc)' ), '"></span>' ].join('') )
- .tooltip({ placement: 'bottom' })
- .click( function( event ){
- clearSearchInput.call( this, event );
- });
- }
-
- // .................................................................... loadingIndicator rendering
- // a button for clearing the search bar, placed on the right hand side
- function $loadingIndicator(){
- return $([ '<span class="search-loading fa fa-spinner fa-spin" ',
- 'title="', _l( 'loading...' ), '"></span>' ].join('') )
- .hide().tooltip({ placement: 'bottom' });
- }
-
- // .................................................................... commands
- // visually swap the load, clear buttons
- function toggleLoadingIndicator(){
- $parentNode.find( '.search-loading' ).toggle();
- $parentNode.find( '.search-clear' ).toggle();
- }
-
- // .................................................................... init
- // string command (not constructor)
- if( jQuery.type( options ) === 'string' ){
- if( options === 'toggle-loading' ){
- toggleLoadingIndicator();
- }
- return $parentNode;
- }
-
- // initial render
- if( jQuery.type( options ) === 'object' ){
- options = jQuery.extend( true, {}, defaults, options );
- }
- //NOTE: prepended
- return $parentNode.addClass( 'search-input' ).prepend([ $input(), $clearBtn(), $loadingIndicator() ]);
- }
-
- // as jq plugin
- jQuery.fn.extend({
- searchInput : function $searchInput( options ){
- return this.each( function(){
- return searchInput( this, options );
- });
- }
- });
-}());
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/packed/jq-plugins/ui/search-input.js
--- /dev/null
+++ b/static/scripts/packed/jq-plugins/ui/search-input.js
@@ -0,0 +1,1 @@
+(function(a){if(typeof define==="function"&&define.amd){define([],a)}else{a(jQuery)}}(function(){var b=window._l||function(d){return d};function a(k,q){var e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function j(r){var s=$(this).parent().children("input");s.focus().val("").trigger("clear:searchInput");q.onclear()}function p(s,r){$(this).trigger("search:searchInput",r);if(typeof q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function g(){return['<input type="text" name="',q.name,'" placeholder="',q.placeholder,'" ','class="search-query ',q.classes,'" ',"/>"].join("")}function m(){return $(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).on("change",function(r){p.call(this,r,$(this).val())}).val(q.initialVal)}function l(){return $(['<span class="search-clear fa fa-times-circle" ','title="',b("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function o(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function c(d){return this.each(function(){return a(this,d)})}})}));
\ No newline at end of file
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/packed/mvc/history/history-panel.js
--- a/static/scripts/packed/mvc/history/history-panel.js
+++ b/static/scripts/packed/mvc/history/history-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/list/list-panel","mvc/history/history-model","mvc/history/history-contents","mvc/history/hda-li","mvc/history/hdca-li","mvc/collection/collection-panel","mvc/user/user-model","mvc/base-mvc","utils/localization"],function(d,f,l,b,a,m,g,o,e){var j=o.SessionStorageModel.extend({defaults:{expandedIds:{},show_deleted:false,show_hidden:false},addExpanded:function(p){var q="expandedIds";this.save(q,_.extend(this.get(q),_.object([p.id],[p.get("id")])))},removeExpanded:function(p){var q="expandedIds";this.save(q,_.omit(this.get(q),p.id))},toString:function(){return"HistoryPrefs("+this.id+")"}});j.storageKeyPrefix="history:";j.historyStorageKey=function h(p){if(!p){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+p)}return(j.storageKeyPrefix+p)};j.get=function c(p){return new j({id:j.historyStorageKey(p)})};j.clearAll=function i(q){for(var p in sessionStorage){if(p.indexOf(j.storageKeyPrefix)===0){sessionStorage.removeItem(p)}}};var n=d.ModelListPanel;var k=n.extend({HDAViewClass:b.HDAListItemView,HDCAViewClass:a.HDCAListItemView,collectionClass:l.HistoryContents,modelCollectionKey:"contents",tagName:"div",className:n.prototype.className+" history-panel",emptyMsg:e("This history is empty"),noneFoundMsg:e("No matching datasets found"),searchPlaceholder:e("search datasets"),initialize:function(p){n.prototype.initialize.call(this,p);this.linkTarget=p.linkTarget||"_blank"},freeModel:function(){n.prototype.freeModel.call(this);if(this.model){this.model.clearUpdateTimeout()}return this},_setUpListeners:function(){n.prototype._setUpListeners.call(this);this.on("error",function(q,t,p,s,r){this.errorHandler(q,t,p,s,r)});this.on("loading-done",function(){if(!this.views.length){this.trigger("empty-history",this)}})},loadHistoryWithDetails:function(s,r,q,t){this.info("loadHistoryWithDetails:",s,r,q,t);var p=function(u){return _.values(j.get(u.id).get("expandedIds"))};return this.loadHistory(s,r,q,t,p)},loadHistory:function(t,s,r,u,p){this.info("loadHistory:",t,s,r,u,p);var q=this;s=s||{};q.trigger("loading",q);var v=f.History.getHistoryData(t,{historyFn:r,contentsFn:u,detailIdsFn:s.initiallyExpanded||p});return q._loadHistoryFromXHR(v,s).fail(function(y,w,x){q.trigger("error",q,y,s,e("An error was encountered while "+w),{historyId:t,history:x||{}})}).always(function(){q.trigger("loading-done",q)})},_loadHistoryFromXHR:function(r,q){var p=this;r.then(function(s,t){p.JSONToModel(s,t,q);p.render()});r.fail(function(t,s){p.render()});return r},refreshContents:function(q,p){if(this.model){return this.model.refresh(q,p)}return $.when()},JSONToModel:function(s,p,q){this.log("JSONToModel:",s,p,q);q=q||{};var r=new f.History(s,p,q);this.setModel(r);return r},setModel:function(q,p){p=p||{};n.prototype.setModel.call(this,q,p);if(this.model){this._setUpWebStorage(p.initiallyExpanded,p.show_deleted,p.show_hidden)}},_setUpWebStorage:function(q,p,r){if(this.storage){this.stopListening(this.storage)}this.storage=new j({id:j.historyStorageKey(this.model.get("id"))});if(_.isObject(q)){this.storage.set("expandedIds",q)}if(_.isBoolean(p)){this.storage.set("show_deleted",p)}if(_.isBoolean(r)){this.storage.set("show_hidden",r)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());this.listenTo(this.storage,{"change:show_deleted":function(s,t){this.showDeleted=t},"change:show_hidden":function(s,t){this.showHidden=t}},this);this.showDeleted=(p!==undefined)?p:this.storage.get("show_deleted");this.showHidden=(r!==undefined)?r:this.storage.get("show_hidden");return this},_buildNewRender:function(){var p=n.prototype._buildNewRender.call(this);if(this.multiselectActions.length){p.find(".controls .actions").prepend(this._renderSelectButton())}return p},_renderSelectButton:function(p){return faIconButton({title:e("Operations on multiple datasets"),classes:"show-selectors-btn",faIcon:"fa-check-square-o"})},_getItemViewClass:function(p){var q=p.get("history_content_type");switch(q){case"dataset":return this.HDAViewClass;case"dataset_collection":return this.HDCAViewClass}throw new TypeError("Unknown history_content_type: "+q)},_filterItem:function(q){var p=this;return(n.prototype._filterItem.call(p,q)&&(!q.hidden()||p.showHidden)&&(!q.isDeletedOrPurged()||p.showDeleted))},_getItemViewOptions:function(q){var p=n.prototype._getItemViewOptions.call(this,q);return _.extend(p,{linkTarget:this.linkTarget,expanded:!!this.storage.get("expandedIds")[q.id],hasUser:this.model.ownedByCurrUser()})},_setUpItemViewListeners:function(q){var p=this;n.prototype._setUpItemViewListeners.call(p,q);q.on("expanded",function(r){p.storage.addExpanded(r.model)});q.on("collapsed",function(r){p.storage.removeExpanded(r.model)});return this},getSelectedModels:function(){var p=n.prototype.getSelectedModels.call(this);p.historyId=this.collection.historyId;return p},events:_.extend(_.clone(n.prototype.events),{"click .show-selectors-btn":"toggleSelectors"}),toggleShowDeleted:function(p,q){p=(p!==undefined)?(p):(!this.showDeleted);q=(q!==undefined)?(q):(true);this.showDeleted=p;if(q){this.storage.set("show_deleted",p)}this.trigger("show-hidden",p);this.renderItems();return this.showDeleted},toggleShowHidden:function(p,q){p=(p!==undefined)?(p):(!this.showHidden);q=(q!==undefined)?(q):(true);this.showHidden=p;if(q){this.storage.set("show_hidden",p)}this.trigger("show-hidden",p);this.renderItems();return this.showHidden},_firstSearch:function(p){var q=this,r=".history-search-input";this.log("onFirstSearch",p);if(q.model.contents.haveDetails()){q.searchItems(p);return}q.$el.find(r).searchInput("toggle-loading");q.model.contents.fetchAllDetails({silent:true}).always(function(){q.$el.find(r).searchInput("toggle-loading")}).done(function(){q.searchItems(p)})},errorHandler:function(r,u,q,t,s){this.error(r,u,q,t,s);if(u&&u.status===0&&u.readyState===0){}else{if(u&&u.status===502){}else{var p=this._parseErrorMessage(r,u,q,t,s);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",p.message,p.details)})}else{this.displayMessage("error",p.message,p.details)}}}},_parseErrorMessage:function(t,w,x,r,p,u){var s=Galaxy.currUser,v={message:this._bePolite(r),details:{message:r,raven:(window.Raven&&_.isFunction(Raven.lastEventId))?(Raven.lastEventId()):(undefined),agent:navigator.userAgent,url:(window.Galaxy)?(Galaxy.lastAjax.url):(undefined),data:(window.Galaxy)?(Galaxy.lastAjax.data):(undefined),options:(w)?(_.omit(x,"xhr")):(x),xhr:w,source:(_.isFunction(t.toJSON))?(t.toJSON()):(t+""),user:(s instanceof g.User)?(s.toJSON()):(s+"")}};_.extend(v.details,p||{});if(w&&_.isFunction(w.getAllResponseHeaders)){var q=w.getAllResponseHeaders();q=_.compact(q.split("\n"));q=_.map(q,function(y){return y.split(": ")});v.details.xhr.responseHeaders=_.object(q)}return v},_bePolite:function(p){p=p||e("An error occurred while getting updates from the server");return p+". "+e("Please contact a Galaxy administrator if the problem persists")+"."},displayMessage:function(u,v,t){var r=this;this.scrollToTop();var s=this.$messages(),p=$("<div/>").addClass(u+"message").html(v);if(!_.isEmpty(t)){var q=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(r._messageToModalOptions(u,v,t));return false});p.append(" ",q)}return s.html(p)},_messageToModalOptions:function(s,v,r){var p=this,q={title:"Details"};if(_.isObject(r)){r=_.omit(r,_.functions(r));var u=JSON.stringify(r,null," "),t=$("<pre/>").text(u);q.body=$("<div/>").append(t)}else{q.body=$("<div/>").html(r)}q.buttons={Ok:function(){Galaxy.modal.hide();p.clearMessages()}};return q},clearMessages:function(p){$(p.currentTarget).fadeOut(this.fxSpeed,function(){$(this).remove()});return this},scrollToHid:function(p){return this.scrollToItem(_.first(this.viewsWhereModel({hid:p})))},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});k.prototype.templates=(function(){var p=o.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= history.name %></div>',"</div>",'<div class="subtitle"></div>','<div class="history-size"><%= history.nice_size %></div>','<div class="actions"></div>','<div class="messages">',"<% if( history.deleted ){ %>",'<div class="deleted-msg warningmessagesmall">',e("This history has been deleted"),"</div>","<% } %>","<% if( history.message ){ %>",'<div class="<%= history.message.level || "info" %>messagesmall">',"<%= history.message.text %>","</div>","<% } %>","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',e("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',e("None"),"</button>","</div>",'<button class="list-action-popup-btn btn btn-default">',e("For all selected"),"...</button>","</div>","</div>"],"history");return _.extend(_.clone(n.prototype.templates),{controls:p})}());return{HistoryPanel:k}});
\ No newline at end of file
+define(["mvc/list/list-panel","mvc/history/history-model","mvc/history/history-contents","mvc/history/hda-li","mvc/history/hdca-li","mvc/collection/collection-panel","mvc/user/user-model","mvc/base-mvc","utils/localization","jq-plugins/ui/search-input"],function(d,f,l,b,a,m,g,o,e){var j=o.SessionStorageModel.extend({defaults:{expandedIds:{},show_deleted:false,show_hidden:false},addExpanded:function(p){var q="expandedIds";this.save(q,_.extend(this.get(q),_.object([p.id],[p.get("id")])))},removeExpanded:function(p){var q="expandedIds";this.save(q,_.omit(this.get(q),p.id))},toString:function(){return"HistoryPrefs("+this.id+")"}});j.storageKeyPrefix="history:";j.historyStorageKey=function h(p){if(!p){throw new Error("HistoryPrefs.historyStorageKey needs valid id: "+p)}return(j.storageKeyPrefix+p)};j.get=function c(p){return new j({id:j.historyStorageKey(p)})};j.clearAll=function i(q){for(var p in sessionStorage){if(p.indexOf(j.storageKeyPrefix)===0){sessionStorage.removeItem(p)}}};var n=d.ModelListPanel;var k=n.extend({HDAViewClass:b.HDAListItemView,HDCAViewClass:a.HDCAListItemView,collectionClass:l.HistoryContents,modelCollectionKey:"contents",tagName:"div",className:n.prototype.className+" history-panel",emptyMsg:e("This history is empty"),noneFoundMsg:e("No matching datasets found"),searchPlaceholder:e("search datasets"),initialize:function(p){n.prototype.initialize.call(this,p);this.linkTarget=p.linkTarget||"_blank"},freeModel:function(){n.prototype.freeModel.call(this);if(this.model){this.model.clearUpdateTimeout()}return this},_setUpListeners:function(){n.prototype._setUpListeners.call(this);this.on("error",function(q,t,p,s,r){this.errorHandler(q,t,p,s,r)});this.on("loading-done",function(){if(!this.views.length){this.trigger("empty-history",this)}})},loadHistoryWithDetails:function(s,r,q,t){this.info("loadHistoryWithDetails:",s,r,q,t);var p=function(u){return _.values(j.get(u.id).get("expandedIds"))};return this.loadHistory(s,r,q,t,p)},loadHistory:function(t,s,r,u,p){this.info("loadHistory:",t,s,r,u,p);var q=this;s=s||{};q.trigger("loading",q);var v=f.History.getHistoryData(t,{historyFn:r,contentsFn:u,detailIdsFn:s.initiallyExpanded||p});return q._loadHistoryFromXHR(v,s).fail(function(y,w,x){q.trigger("error",q,y,s,e("An error was encountered while "+w),{historyId:t,history:x||{}})}).always(function(){q.trigger("loading-done",q)})},_loadHistoryFromXHR:function(r,q){var p=this;r.then(function(s,t){p.JSONToModel(s,t,q);p.render()});r.fail(function(t,s){p.render()});return r},refreshContents:function(q,p){if(this.model){return this.model.refresh(q,p)}return $.when()},JSONToModel:function(s,p,q){this.log("JSONToModel:",s,p,q);q=q||{};var r=new f.History(s,p,q);this.setModel(r);return r},setModel:function(q,p){p=p||{};n.prototype.setModel.call(this,q,p);if(this.model){this._setUpWebStorage(p.initiallyExpanded,p.show_deleted,p.show_hidden)}},_setUpWebStorage:function(q,p,r){if(this.storage){this.stopListening(this.storage)}this.storage=new j({id:j.historyStorageKey(this.model.get("id"))});if(_.isObject(q)){this.storage.set("expandedIds",q)}if(_.isBoolean(p)){this.storage.set("show_deleted",p)}if(_.isBoolean(r)){this.storage.set("show_hidden",r)}this.trigger("new-storage",this.storage,this);this.log(this+" (init'd) storage:",this.storage.get());this.listenTo(this.storage,{"change:show_deleted":function(s,t){this.showDeleted=t},"change:show_hidden":function(s,t){this.showHidden=t}},this);this.showDeleted=(p!==undefined)?p:this.storage.get("show_deleted");this.showHidden=(r!==undefined)?r:this.storage.get("show_hidden");return this},_buildNewRender:function(){var p=n.prototype._buildNewRender.call(this);if(this.multiselectActions.length){p.find(".controls .actions").prepend(this._renderSelectButton())}return p},_renderSelectButton:function(p){return faIconButton({title:e("Operations on multiple datasets"),classes:"show-selectors-btn",faIcon:"fa-check-square-o"})},_getItemViewClass:function(p){var q=p.get("history_content_type");switch(q){case"dataset":return this.HDAViewClass;case"dataset_collection":return this.HDCAViewClass}throw new TypeError("Unknown history_content_type: "+q)},_filterItem:function(q){var p=this;return(n.prototype._filterItem.call(p,q)&&(!q.hidden()||p.showHidden)&&(!q.isDeletedOrPurged()||p.showDeleted))},_getItemViewOptions:function(q){var p=n.prototype._getItemViewOptions.call(this,q);return _.extend(p,{linkTarget:this.linkTarget,expanded:!!this.storage.get("expandedIds")[q.id],hasUser:this.model.ownedByCurrUser()})},_setUpItemViewListeners:function(q){var p=this;n.prototype._setUpItemViewListeners.call(p,q);q.on("expanded",function(r){p.storage.addExpanded(r.model)});q.on("collapsed",function(r){p.storage.removeExpanded(r.model)});return this},getSelectedModels:function(){var p=n.prototype.getSelectedModels.call(this);p.historyId=this.collection.historyId;return p},events:_.extend(_.clone(n.prototype.events),{"click .show-selectors-btn":"toggleSelectors"}),toggleShowDeleted:function(p,q){p=(p!==undefined)?(p):(!this.showDeleted);q=(q!==undefined)?(q):(true);this.showDeleted=p;if(q){this.storage.set("show_deleted",p)}this.trigger("show-hidden",p);this.renderItems();return this.showDeleted},toggleShowHidden:function(p,q){p=(p!==undefined)?(p):(!this.showHidden);q=(q!==undefined)?(q):(true);this.showHidden=p;if(q){this.storage.set("show_hidden",p)}this.trigger("show-hidden",p);this.renderItems();return this.showHidden},_firstSearch:function(p){var q=this,r=".history-search-input";this.log("onFirstSearch",p);if(q.model.contents.haveDetails()){q.searchItems(p);return}q.$el.find(r).searchInput("toggle-loading");q.model.contents.fetchAllDetails({silent:true}).always(function(){q.$el.find(r).searchInput("toggle-loading")}).done(function(){q.searchItems(p)})},errorHandler:function(r,u,q,t,s){this.error(r,u,q,t,s);if(u&&u.status===0&&u.readyState===0){}else{if(u&&u.status===502){}else{var p=this._parseErrorMessage(r,u,q,t,s);if(!this.$messages().is(":visible")){this.once("rendered",function(){this.displayMessage("error",p.message,p.details)})}else{this.displayMessage("error",p.message,p.details)}}}},_parseErrorMessage:function(t,w,x,r,p,u){var s=Galaxy.currUser,v={message:this._bePolite(r),details:{message:r,raven:(window.Raven&&_.isFunction(Raven.lastEventId))?(Raven.lastEventId()):(undefined),agent:navigator.userAgent,url:(window.Galaxy)?(Galaxy.lastAjax.url):(undefined),data:(window.Galaxy)?(Galaxy.lastAjax.data):(undefined),options:(w)?(_.omit(x,"xhr")):(x),xhr:w,source:(_.isFunction(t.toJSON))?(t.toJSON()):(t+""),user:(s instanceof g.User)?(s.toJSON()):(s+"")}};_.extend(v.details,p||{});if(w&&_.isFunction(w.getAllResponseHeaders)){var q=w.getAllResponseHeaders();q=_.compact(q.split("\n"));q=_.map(q,function(y){return y.split(": ")});v.details.xhr.responseHeaders=_.object(q)}return v},_bePolite:function(p){p=p||e("An error occurred while getting updates from the server");return p+". "+e("Please contact a Galaxy administrator if the problem persists")+"."},displayMessage:function(u,v,t){var r=this;this.scrollToTop();var s=this.$messages(),p=$("<div/>").addClass(u+"message").html(v);if(!_.isEmpty(t)){var q=$('<a href="javascript:void(0)">Details</a>').click(function(){Galaxy.modal.show(r._messageToModalOptions(u,v,t));return false});p.append(" ",q)}return s.html(p)},_messageToModalOptions:function(s,v,r){var p=this,q={title:"Details"};if(_.isObject(r)){r=_.omit(r,_.functions(r));var u=JSON.stringify(r,null," "),t=$("<pre/>").text(u);q.body=$("<div/>").append(t)}else{q.body=$("<div/>").html(r)}q.buttons={Ok:function(){Galaxy.modal.hide();p.clearMessages()}};return q},clearMessages:function(p){$(p.currentTarget).fadeOut(this.fxSpeed,function(){$(this).remove()});return this},scrollToHid:function(p){return this.scrollToItem(_.first(this.viewsWhereModel({hid:p})))},toString:function(){return"HistoryPanel("+((this.model)?(this.model.get("name")):(""))+")"}});k.prototype.templates=(function(){var p=o.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= history.name %></div>',"</div>",'<div class="subtitle"></div>','<div class="history-size"><%= history.nice_size %></div>','<div class="actions"></div>','<div class="messages">',"<% if( history.deleted ){ %>",'<div class="deleted-msg warningmessagesmall">',e("This history has been deleted"),"</div>","<% } %>","<% if( history.message ){ %>",'<div class="<%= history.message.level || "info" %>messagesmall">',"<%= history.message.text %>","</div>","<% } %>","</div>",'<div class="tags-display"></div>','<div class="annotation-display"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',e("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',e("None"),"</button>","</div>",'<button class="list-action-popup-btn btn btn-default">',e("For all selected"),"...</button>","</div>","</div>"],"history");return _.extend(_.clone(n.prototype.templates),{controls:p})}());return{HistoryPanel:k}});
\ No newline at end of file
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/packed/mvc/history/multi-panel.js
--- a/static/scripts/packed/mvc/history/multi-panel.js
+++ b/static/scripts/packed/mvc/history/multi-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","jq-plugins/ui/mode-button"],function(d,l,z,a){window.HISTORY_MODEL=d;function g(H,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return H.copy()}var F=H.get("name"),C="Copy of '"+F+"'";function D(J){if(!J){if(!Galaxy.modal.$("#invalid-title").size()){var I=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(I)}return false}return J}function G(I){var J=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(J);H.copy(true,I).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:function(){var I=Galaxy.modal.$("#copy-modal-title").val();if(!D(I)){return}G(I)}}},E));$("#copy-modal-title").focus().select()}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(D){D=D||{};var C=['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate(),'<div class="pull-right">','<button class="delete-history btn btn-default">',D.deleted?_l("Undelete"):_l("Delete"),"</button>",'<button class="copy-history btn btn-default">',_l("Copy"),"</button>","</div>","</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',D.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join("");return $(C)},controlsLeftTemplate:function(){return(this.currentHistory)?['<div class="pull-left">','<button class="create-new btn btn-default">',_l("Create new"),"</button> ","</div>"].join(""):['<div class="pull-left">','<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","</div>"].join("")},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history.btn":function(){var C=this,D;if(this.model.get("deleted")){D=this.model.undelete()}else{D=this.model._delete()}D.fail(function(G,E,F){alert(_l("Could not delete the history")+":\n"+F)}).done(function(E){C.render()})},"click .copy-history.btn":"copy"},copy:function s(){g(this.model)},toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({initialize:function c(C){C=C||{};this.log(this+".init",C);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){C=C||this.order;var E=this.currentHistoryId;switch(C){case"name":this.collection.comparator=function(F){return[F.id!==E,F.get("name").toLowerCase()]};break;case"size":this.collection.comparator=function(F){return[F.id!==E,F.get("size")]};break;default:this.collection.comparator=function(F){return[F.id!==E,Date(F.get("update_time"))]}}this.collection.sort(D);return this.collection},setOrder:function(C){if(["update","name","size"].indexOf(C)===-1){C="update"}this.order=C;this.sortCollection();return this},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(C){var D=this;D.listenTo(C,{"in-view":D.queueHdaFetch});D.listenTo(C.panel,{"view:draggable:dragstart":function(H,F,E,G){D._dropData=JSON.parse(H.dataTransfer.getData("text"));D.currentColumnDropTargetOn()},"view:draggable:dragend":function(H,F,E,G){D._dropData=null;D.currentColumnDropTargetOff()},"droptarget:drop":function(G,H,F){var I=D._dropData.filter(function(J){return(_.isObject(J)&&J.id&&J.model_class==="HistoryDatasetAssociation")});D._dropData=null;var E=new a.NamedAjaxQueue();I.forEach(function(J){E.add({name:"copy-"+J.id,fn:function(){return F.model.contents.copy(J.id)}})});E.start();E.done(function(J){F.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.template(C.options));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},template:function w(C){C=C||{};var D=[];if(this.options.headerHeight){D=D.concat(['<div class="loading-overlay flex-row"><div class="loading-overlay-message">loading...</div></div>','<div class="header flex-column-container">','<div class="header-control header-control-left flex-column">','<button class="done btn btn-default">',_l("Done"),"</button>",'<button class="include-deleted btn btn-default"></button>','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+'... <span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">','<li><a href="javascript:void(0);" class="order-update">',_l("Time of last update"),"</a></li>",'<li><a href="javascript:void(0);" class="order-name">',_l("Name"),"</a></li>",'<li><a href="javascript:void(0);" class="order-size">',_l("Size"),"</a></li>","</ul>","</div>",'<div id="search-histories" class="header-search"></div>',"</div>",'<div class="header-control header-control-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="header-control header-control-right flex-column">','<div id="search-datasets" class="header-search"></div>','<button id="toggle-deleted" class="btn btn-default">',_l("Include deleted datasets"),"</button>",'<button id="toggle-hidden" class="btn btn-default">',_l("Include hidden datasets"),"</button>","</div>","</div>"])}D=D.concat(['<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"]);return $(D.join(""))},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){this.$(".header .header-info").text(C)},events:{"click .done.btn":function(){window.location="/"},"click .create-new.btn":"create","click .order .order-update":function(C){this.setOrder("update")},"click .order .order-name":function(C){this.setOrder("name")},"click .order .order-size":function(C){this.setOrder("size")}},includeDeletedHistories:function(){window.location+=(/\?/.test(window.location.toString()))?("&"):("?")+"include_deleted_histories=True"},excludeDeletedHistories:function(){window.location=window.location.toString().replace(/[&\?]include_deleted_histories=True/g,"")},setUpBehaviors:function(){var D=this;D.$(".include-deleted").modeButton({initialMode:this.collection.includeDeleted?"exclude":"include",switchModesOnClick:false,modes:[{mode:"include",html:_l("Include deleted histories"),onclick:_.bind(D.includeDeletedHistories,D)},{mode:"exclude",html:_l("Exclude deleted histories"),onclick:_.bind(D.excludeDeletedHistories,D)}]});D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});D.$("#toggle-deleted").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude deleted datasets")},{mode:"include",html:_l("Include deleted datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowDeleted(E,false)},F*200)})});D.$("#toggle-hidden").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude hidden datasets")},{mode:"include",html:_l("Include hidden datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowHidden(E,false)},F*200)})});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTargetOff()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"}});return{MultiPanelColumns:m}});
\ No newline at end of file
+define(["mvc/history/history-model","mvc/history/history-panel-edit","mvc/base-mvc","utils/ajax-queue","jq-plugins/ui/mode-button","jq-plugins/ui/search-input"],function(d,l,z,a){window.HISTORY_MODEL=d;function g(H,E){E=E||{};if(!(Galaxy&&Galaxy.modal)){return H.copy()}var F=H.get("name"),C="Copy of '"+F+"'";function D(J){if(!J){if(!Galaxy.modal.$("#invalid-title").size()){var I=$("<p/>").attr("id","invalid-title").css({color:"red","margin-top":"8px"}).addClass("bg-danger").text(_l("Please enter a valid history title"));Galaxy.modal.$(".modal-body").append(I)}return false}return J}function G(I){var J=$('<p><span class="fa fa-spinner fa-spin"></span> Copying history...</p>').css("margin-top","8px");Galaxy.modal.$(".modal-body").append(J);H.copy(true,I).fail(function(){alert(_l("History could not be copied. Please contact a Galaxy administrator"))}).always(function(){Galaxy.modal.hide()})}Galaxy.modal.show(_.extend({title:_l("Copying history")+' "'+F+'"',body:$(['<label for="copy-modal-title">',_l("Enter a title for the copied history"),":","</label><br />",'<input id="copy-modal-title" class="form-control" style="width: 100%" value="',C,'" />'].join("")),buttons:{Cancel:function(){Galaxy.modal.hide()},Copy:function(){var I=Galaxy.modal.$("#copy-modal-title").val();if(!D(I)){return}G(I)}}},E));$("#copy-modal-title").focus().select()}var B=Backbone.View.extend(z.LoggableMixin).extend({tagName:"div",className:"history-column flex-column flex-row-container",id:function q(){if(!this.model){return""}return"history-column-"+this.model.get("id")},initialize:function c(C){C=C||{};this.panel=C.panel||this.createPanel(C);this.setUpListeners()},createPanel:function u(D){D=_.extend({model:this.model,dragItems:true},D);var C=new l.HistoryPanelEdit(D);C._renderEmptyMessage=this.__patch_renderEmptyMessage;return C},__patch_renderEmptyMessage:function(E){var D=this,F=_.chain(this.model.get("state_ids")).values().flatten().value().length,C=D.$emptyMessage(E);if(!_.isEmpty(D.hdaViews)){C.hide()}else{if(F&&!this.model.contents.length){C.empty().append($('<span class="fa fa-spinner fa-spin"></span><i>loading datasets...</i>')).show()}else{if(D.searchFor){C.text(D.noneFoundMsg).show()}else{C.text(D.emptyMsg).show()}}}return C},setUpListeners:function f(){var C=this;this.once("rendered",function(){C.trigger("rendered:initial",C)});this.setUpPanelListeners()},setUpPanelListeners:function k(){var C=this;this.listenTo(this.panel,{rendered:function(){C.trigger("rendered",C)}},this)},inView:function(C,D){var F=this.$el.offset().left,E=F+this.$el.width();if(E<C){return false}if(F>D){return false}return true},$panel:function e(){return this.$(".history-panel")},render:function A(D){D=(D!==undefined)?(D):("fast");var C=this.model?this.model.toJSON():{};this.$el.html(this.template(C));this.renderPanel(D);this.setUpBehaviors();return this},setUpBehaviors:function v(){},template:function w(D){D=D||{};var C=['<div class="panel-controls clear flex-row">',this.controlsLeftTemplate(),'<div class="pull-right">','<button class="delete-history btn btn-default">',D.deleted?_l("Undelete"):_l("Delete"),"</button>",'<button class="copy-history btn btn-default">',_l("Copy"),"</button>","</div>","</div>",'<div class="inner flex-row flex-column-container">','<div id="history-',D.id,'" class="history-column history-panel flex-column"></div>',"</div>"].join("");return $(C)},controlsLeftTemplate:function(){return(this.currentHistory)?['<div class="pull-left">','<button class="create-new btn btn-default">',_l("Create new"),"</button> ","</div>"].join(""):['<div class="pull-left">','<button class="switch-to btn btn-default">',_l("Switch to"),"</button>","</div>"].join("")},renderPanel:function h(C){C=(C!==undefined)?(C):("fast");this.panel.setElement(this.$panel()).render(C);return this},events:{"click .switch-to.btn":function(){this.model.setAsCurrent()},"click .delete-history.btn":function(){var C=this,D;if(this.model.get("deleted")){D=this.model.undelete()}else{D=this.model._delete()}D.fail(function(G,E,F){alert(_l("Could not delete the history")+":\n"+F)}).done(function(E){C.render()})},"click .copy-history.btn":"copy"},copy:function s(){g(this.model)},toString:function(){return"HistoryPanelColumn("+(this.panel?this.panel:"")+")"}});var m=Backbone.View.extend(z.LoggableMixin).extend({initialize:function c(C){C=C||{};this.log(this+".init",C);if(!C.currentHistoryId){throw new Error(this+" requires a currentHistoryId in the options")}this.currentHistoryId=C.currentHistoryId;this.options={columnWidth:312,borderWidth:1,columnGap:8,headerHeight:29,footerHeight:0,controlsHeight:20};this.order=C.order||"update";this.hdaQueue=new a.NamedAjaxQueue([],false);this.collection=null;this.setCollection(C.histories||[]);this.columnMap={};this.createColumns(C.columnOptions);this.setUpListeners()},setUpListeners:function f(){},setCollection:function y(D){var C=this;C.stopListening(C.collection);C.collection=D;C.sortCollection(C.order,{silent:true});C.setUpCollectionListeners();C.trigger("new-collection",C);return C},setUpCollectionListeners:function(){var C=this,D=C.collection;C.listenTo(D,{add:C.addAsCurrentColumn,"set-as-current":C.setCurrentHistory,"change:deleted":C.handleDeletedHistory,sort:function(){C.renderColumns(0)}})},setCurrentHistory:function p(D){var C=this.columnMap[this.currentHistoryId];if(C){C.currentHistory=false;C.$el.height("")}this.currentHistoryId=D.id;var E=this.columnMap[this.currentHistoryId];E.currentHistory=true;this.sortCollection();multipanel._recalcFirstColumnHeight();return E},handleDeletedHistory:function b(D){if(D.get("deleted")){this.log("handleDeletedHistory",this.collection.includeDeleted,D);var C=this;column=C.columnMap[D.id];if(!column){return}if(column.model.id===this.currentHistoryId){}else{if(!C.collection.includeDeleted){C.removeColumn(column)}}}},sortCollection:function(C,D){C=C||this.order;var E=this.currentHistoryId;switch(C){case"name":this.collection.comparator=function(F){return[F.id!==E,F.get("name").toLowerCase()]};break;case"size":this.collection.comparator=function(F){return[F.id!==E,F.get("size")]};break;default:this.collection.comparator=function(F){return[F.id!==E,Date(F.get("update_time"))]}}this.collection.sort(D);return this.collection},setOrder:function(C){if(["update","name","size"].indexOf(C)===-1){C="update"}this.order=C;this.sortCollection();return this},create:function(C){return this.collection.create({current:true})},createColumns:function r(D){D=D||{};var C=this;this.columnMap={};C.collection.each(function(E,F){var G=C.createColumn(E,D);C.columnMap[E.id]=G})},createColumn:function t(E,C){C=_.extend({},C,{model:E});var D=new B(C);if(E.id===this.currentHistoryId){D.currentHistory=true}this.setUpColumnListeners(D);return D},sortedFilteredColumns:function(C){C=C||this.filters;if(!C||!C.length){return this.sortedColumns()}var D=this;return D.sortedColumns().filter(function(G,F){var E=G.currentHistory||_.every(C.map(function(H){return H.call(G)}));return E})},sortedColumns:function(){var D=this;var C=this.collection.map(function(F,E){return D.columnMap[F.id]});return C},addColumn:function o(E,C){C=C!==undefined?C:true;var D=this.createColumn(E);this.columnMap[E.id]=D;if(C){this.renderColumns()}return D},addAsCurrentColumn:function o(E){var D=this,C=this.addColumn(E,false);this.setCurrentHistory(E);C.once("rendered",function(){D.queueHdaFetch(C)});return C},removeColumn:function x(E,D){D=D!==undefined?D:true;this.log("removeColumn",E);if(!E){return}var F=this,C=this.options.columnWidth+this.options.columnGap;E.$el.fadeOut("fast",function(){if(D){$(this).remove();F.$(".middle").width(F.$(".middle").width()-C);F.checkColumnsInView();F._recalcFirstColumnHeight()}F.stopListening(E.panel);F.stopListening(E);delete F.columnMap[E.model.id];E.remove()})},setUpColumnListeners:function n(C){var D=this;D.listenTo(C,{"in-view":D.queueHdaFetch});D.listenTo(C.panel,{"view:draggable:dragstart":function(H,F,E,G){D._dropData=JSON.parse(H.dataTransfer.getData("text"));D.currentColumnDropTargetOn()},"view:draggable:dragend":function(H,F,E,G){D._dropData=null;D.currentColumnDropTargetOff()},"droptarget:drop":function(G,H,F){var I=D._dropData.filter(function(J){return(_.isObject(J)&&J.id&&J.model_class==="HistoryDatasetAssociation")});D._dropData=null;var E=new a.NamedAjaxQueue();I.forEach(function(J){E.add({name:"copy-"+J.id,fn:function(){return F.model.contents.copy(J.id)}})});E.start();E.done(function(J){F.model.fetch()})}})},columnMapLength:function(){return Object.keys(this.columnMap).length},render:function A(D){D=D!==undefined?D:this.fxSpeed;var C=this;C.log(C+".render");C.$el.html(C.template(C.options));C.renderColumns(D);C.setUpBehaviors();C.trigger("rendered",C);return C},template:function w(C){C=C||{};var D=[];if(this.options.headerHeight){D=D.concat(['<div class="loading-overlay flex-row"><div class="loading-overlay-message">loading...</div></div>','<div class="header flex-column-container">','<div class="header-control header-control-left flex-column">','<button class="done btn btn-default">',_l("Done"),"</button>",'<button class="include-deleted btn btn-default"></button>','<div class="order btn-group">','<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">',_l("Order histories by")+'... <span class="caret"></span>',"</button>",'<ul class="dropdown-menu" role="menu">','<li><a href="javascript:void(0);" class="order-update">',_l("Time of last update"),"</a></li>",'<li><a href="javascript:void(0);" class="order-name">',_l("Name"),"</a></li>",'<li><a href="javascript:void(0);" class="order-size">',_l("Size"),"</a></li>","</ul>","</div>",'<div id="search-histories" class="header-search"></div>',"</div>",'<div class="header-control header-control-center flex-column">','<div class="header-info">',"</div>","</div>",'<div class="header-control header-control-right flex-column">','<div id="search-datasets" class="header-search"></div>','<button id="toggle-deleted" class="btn btn-default">',_l("Include deleted datasets"),"</button>",'<button id="toggle-hidden" class="btn btn-default">',_l("Include hidden datasets"),"</button>","</div>","</div>"])}D=D.concat(['<div class="outer-middle flex-row flex-row-container">','<div class="middle flex-column-container flex-row"></div>',"</div>",'<div class="footer flex-column-container">',"</div>"]);return $(D.join(""))},renderColumns:function j(F){F=F!==undefined?F:this.fxSpeed;var E=this,C=E.sortedFilteredColumns();E.$(".middle").width(C.length*(this.options.columnWidth+this.options.columnGap)+this.options.columnGap+16);var D=E.$(".middle");D.empty();C.forEach(function(H,G){H.$el.appendTo(D);H.delegateEvents();E.renderColumn(H,F)});if(this.searchFor&&C.length<=1){}else{E.checkColumnsInView();this._recalcFirstColumnHeight()}return C},renderColumn:function(C,D){D=D!==undefined?D:this.fxSpeed;return C.render(D)},queueHdaFetch:function i(E){if(E.model.contents.length===0&&!E.model.get("empty")){var C={},D=_.values(E.panel.storage.get("expandedIds")).join();if(D){C.dataset_details=D}this.hdaQueue.add({name:E.model.id,fn:function(){var F=E.model.contents.fetch({data:C,silent:true});return F.done(function(G){E.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},queueHdaFetchDetails:function(C){if((C.model.contents.length===0&&!C.model.get("empty"))||(!C.model.contents.haveDetails())){this.hdaQueue.add({name:C.model.id,fn:function(){var D=C.model.contents.fetch({data:{details:"all"},silent:true});return D.done(function(E){C.panel.renderItems()})}});if(!this.hdaQueue.running){this.hdaQueue.start()}}},renderInfo:function(C){this.$(".header .header-info").text(C)},events:{"click .done.btn":function(){window.location="/"},"click .create-new.btn":"create","click .order .order-update":function(C){this.setOrder("update")},"click .order .order-name":function(C){this.setOrder("name")},"click .order .order-size":function(C){this.setOrder("size")}},includeDeletedHistories:function(){window.location+=(/\?/.test(window.location.toString()))?("&"):("?")+"include_deleted_histories=True"},excludeDeletedHistories:function(){window.location=window.location.toString().replace(/[&\?]include_deleted_histories=True/g,"")},setUpBehaviors:function(){var D=this;D.$(".include-deleted").modeButton({initialMode:this.collection.includeDeleted?"exclude":"include",switchModesOnClick:false,modes:[{mode:"include",html:_l("Include deleted histories"),onclick:_.bind(D.includeDeletedHistories,D)},{mode:"exclude",html:_l("Exclude deleted histories"),onclick:_.bind(D.excludeDeletedHistories,D)}]});D.$("#search-histories").searchInput({name:"search-histories",placeholder:_l("search histories"),onsearch:function(E){D.searchFor=E;D.filters=[function(){return this.model.matchesAll(D.searchFor)}];D.renderColumns(0)},onclear:function(E){D.searchFor=null;D.filters=[];D.renderColumns(0)}});D.$("#search-datasets").searchInput({name:"search-datasets",placeholder:_l("search all datasets"),onfirstsearch:function(E){D.hdaQueue.clear();D.$("#search-datasets").searchInput("toggle-loading");D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E);D.queueHdaFetchDetails(F)});D.hdaQueue.progress(function(F){D.renderInfo([_l("searching"),(F.curr+1),_l("of"),F.total].join(" "))});D.hdaQueue.deferred.done(function(){D.renderInfo("");D.$("#search-datasets").searchInput("toggle-loading")})},onsearch:function(E){D.searchFor=E;D.sortedFilteredColumns().forEach(function(F){F.panel.searchItems(E)})},onclear:function(E){D.searchFor=null;D.sortedFilteredColumns().forEach(function(F){F.panel.clearSearch()})}});D.$("#toggle-deleted").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude deleted datasets")},{mode:"include",html:_l("Include deleted datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowDeleted(E,false)},F*200)})});D.$("#toggle-hidden").modeButton({initialMode:"include",modes:[{mode:"exclude",html:_l("Exclude hidden datasets")},{mode:"include",html:_l("Include hidden datasets")}]}).click(function(){var E=$(this).modeButton("getMode").mode==="exclude";D.sortedFilteredColumns().forEach(function(G,F){_.delay(function(){G.panel.toggleShowHidden(E,false)},F*200)})});$(window).resize(function(){D._recalcFirstColumnHeight()});var C=_.debounce(_.bind(this.checkColumnsInView,this),100);this.$(".middle").parent().scroll(C)},_recalcFirstColumnHeight:function(){var C=this.$(".history-column").first(),E=this.$(".middle").height(),D=C.find(".panel-controls").height();C.height(E).find(".inner").height(E-D)},_viewport:function(){var C=this.$(".middle").parent().offset().left;return{left:C,right:C+this.$(".middle").parent().width()}},columnsInView:function(){var C=this._viewport();return this.sortedFilteredColumns().filter(function(D){return D.currentHistory||D.inView(C.left,C.right)})},checkColumnsInView:function(){this.columnsInView().forEach(function(C){C.trigger("in-view",C)})},currentColumnDropTargetOn:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=function(D){};C.panel.dropTargetOn()},currentColumnDropTargetOff:function(){var C=this.columnMap[this.currentHistoryId];if(!C){return}C.panel.dataDropped=l.HistoryPanelEdit.prototype.dataDrop;C.panel.dropTargetOff()},toString:function(){return"MultiPanelColumns("+(this.columns?this.columns.length:0)+")"}});return{MultiPanelColumns:m}});
\ No newline at end of file
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/packed/mvc/list/list-panel.js
--- a/static/scripts/packed/mvc/list/list-panel.js
+++ b/static/scripts/packed/mvc/list/list-panel.js
@@ -1,1 +1,1 @@
-define(["mvc/list/list-item","mvc/base-mvc","utils/localization"],function(d,b,c){var e=Backbone.View.extend(b.LoggableMixin).extend({viewClass:d.ListItemView,collectionClass:Backbone.Collection,tagName:"div",className:"list-panel",fxSpeed:"fast",emptyMsg:c("This list is empty"),noneFoundMsg:c("No matching items found"),searchPlaceholder:c("search"),multiselectActions:[],initialize:function(f,g){f=f||{};if(f.logger){this.logger=f.logger}this.log(this+".initialize:",f);this.fxSpeed=_.has(f,"fxSpeed")?(f.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor=f.searchFor||"";this.indicator=new LoadingIndicator(this.$el);this.selecting=(f.selecting!==undefined)?f.selecting:true;this.selected=f.selected||[];this.lastSelected=null;this.dragItems=f.dragItems||false;this.viewClass=f.viewClass||this.viewClass;this.views=[];this.collection=f.collection||(new this.collectionClass([]));this.filters=f.filters||[];this.$scrollContainer=f.$scrollContainer||this.$scrollContainer;this.title=f.title||"";this.subtitle=f.subtitle||"";this.multiselectActions=f.multiselectActions||this.multiselectActions;this.actionsPopup=null;this._setUpListeners()},freeViews:function(){_.each(this.views,function(f){f.off()});this.views=[];return this},_setUpListeners:function(){this.off();this.on("error",function(g,j,f,i,h){console.error(g,j,f,i,h)},this);this.on("loading",function(){this._showLoadingIndicator("loading...",40)},this);this.on("loading-done",function(){this._hideLoadingIndicator(40)},this);this.once("rendered",function(){this.trigger("rendered:initial",this)},this);if(this.logger){this.on("all",function(f){this.log(this+"",arguments)},this)}this._setUpCollectionListeners();this._setUpViewListeners();return this},_setUpCollectionListeners:function(){this.log(this+"._setUpCollectionListeners",this.collection);this.collection.off();this.collection.on("error",function(g,j,f,i,h){this.trigger("error",g,j,f,i,h)},this);this.collection.on("reset",function(){this.renderItems()},this);this.collection.on("add",this.addItemView,this);this.collection.on("remove",this.removeItemView,this);if(this.logger){this.collection.on("all",function(f){this.info(this+"(collection)",arguments)},this)}return this},_setUpViewListeners:function(){this.log(this+"._setUpViewListeners");this.on("view:selected",function(f,g){if(g&&g.shiftKey&&this.lastSelected){var h=this.viewFromModelId(this.lastSelected);if(h){this.selectRange(f,h)}}else{if(g&&g.altKey&&!this.selecting){this.showSelectors()}}this.selected.push(f.model.id);this.lastSelected=f.model.id},this);this.on("view:de-selected",function(f,g){this.selected=_.without(this.selected,f.model.id)},this)},render:function(g){this.log(this+".render",g);var f=this._buildNewRender();this._setUpBehaviors(f);this._queueNewRender(f,g);return this},_buildNewRender:function(){this.debug(this+"(ListPanel)._buildNewRender");var f=$(this.templates.el({},this));this._renderControls(f);this._renderTitle(f);this._renderSubtitle(f);this._renderSearch(f);this.renderItems(f);return f},_renderControls:function(g){this.debug(this+"(ListPanel)._renderControls");var f=$(this.templates.controls({},this));g.find(".controls").replaceWith(f);return f},_renderTitle:function(f){},_renderSubtitle:function(f){},_queueNewRender:function(g,h){h=(h===undefined)?(this.fxSpeed):(h);var f=this;f.log("_queueNewRender:",g,h);$(f).queue("fx",[function(i){this.$el.fadeOut(h,i)},function(i){f._swapNewRender(g);i()},function(i){this.$el.fadeIn(h,i)},function(i){f.trigger("rendered",f);i()}])},_swapNewRender:function(f){this.$el.empty().attr("class",this.className).append(f.children());if(this.selecting){this.showSelectors(0)}return this},_setUpBehaviors:function(f){f=f||this.$el;f.find(".controls [title]").tooltip({placement:"bottom"});return this},$scrollContainer:function(){return this.$el.parent().parent()},$list:function(f){return(f||this.$el).find("> .list-items")},$messages:function(f){return(f||this.$el).find("> .controls .messages")},$emptyMessage:function(f){return(f||this.$el).find("> .empty-message")},renderItems:function(h){h=h||this.$el;var f=this;f.log(this+".renderItems",h);var g=f.$list(h);f.views=f._filterCollection().map(function(i){return f._createItemView(i).render(0)});g.empty();if(f.views.length){f._attachItems(h);f.$emptyMessage(h).hide()}else{f._renderEmptyMessage(h).show()}return f.views},_filterCollection:function(){var f=this;return f.collection.filter(_.bind(f._filterItem,f))},_filterItem:function(g){var f=this;return(_.every(f.filters.map(function(h){return h.call(g)})))&&(!f.searchFor||g.matchesAll(f.searchFor))},_createItemView:function(h){var i=this._getItemViewClass(h),g=_.extend(this._getItemViewOptions(h),{model:h}),f=new i(g);this._setUpItemViewListeners(f);return f},_getItemViewClass:function(f){return this.viewClass},_getItemViewOptions:function(f){return{fxSpeed:this.fxSpeed,expanded:false,selectable:this.selecting,selected:_.contains(this.selected,f.id),draggable:this.dragItems}},_setUpItemViewListeners:function(g){var f=this;g.on("all",function(){var h=Array.prototype.slice.call(arguments,0);h[0]="view:"+h[0];f.trigger.apply(f,h)});g.on("draggable:dragstart",function(k,h){var i={},j=this.getSelectedModels();if(j.length){i=j.toJSON()}else{i=[h.model.toJSON()]}k.dataTransfer.setData("text",JSON.stringify(i))},this);return f},_attachItems:function(f){this.$list(f).append(this.views.map(function(g){return g.$el}));return this},_renderEmptyMessage:function(f){this.debug("_renderEmptyMessage",f,this.searchFor);var g=this.searchFor?this.noneFoundMsg:this.emptyMsg;return this.$emptyMessage(f).text(g)},expandAll:function(){_.each(this.views,function(f){f.expand()})},collapseAll:function(){_.each(this.views,function(f){f.collapse()})},addItemView:function(i,j,h){this.log(this+".addItemView:",i);var g=this;if(!g._filterItem(i)){return undefined}var f=g._createItemView(i);$(f).queue("fx",[function(k){g.$emptyMessage().fadeOut(g.fxSpeed,k)},function(k){g._attachView(f);k()}]);return f},_attachView:function(g){var f=this;f.views.push(g);f.$list().append(g.render(0).$el.hide());g.$el.slideDown(f.fxSpeed)},removeItemView:function(i,j,h){this.log(this+".removeItemView:",i);var g=this,f=g.viewFromModel(i);if(!f){return undefined}g.views=_.without(g.views,f);$({}).queue("fx",[function(k){f.$el.fadeOut(g.fxSpeed,k)},function(k){f.remove();if(!g.views.length){g._renderEmptyMessage().fadeIn(g.fxSpeed,k)}else{k()}}]);return f},viewFromModelId:function(g){for(var f=0;f<this.views.length;f++){if(this.views[f].model.id===g){return this.views[f]}}return undefined},viewFromModel:function(f){if(!f){return undefined}return this.viewFromModelId(f.id)},viewsWhereModel:function(f){return this.views.filter(function(g){var i=g.model.toJSON();for(var h in f){if(f.hasOwnProperty(h)){if(i[h]!==g.model.get(h)){return false}}}return true})},viewRange:function(i,h){if(i===h){return(i)?([i]):([])}var g=this.views.indexOf(i),f=this.views.indexOf(h);if(g===-1||f===-1){if(g===f){return[]}return(g===-1)?([h]):([i])}return(g<f)?this.views.slice(g,f+1):this.views.slice(f,g+1)},_renderSearch:function(f){f.find(".controls .search-input").searchInput({placeholder:this.searchPlaceholder,initialVal:this.searchFor,onfirstsearch:_.bind(this._firstSearch,this),onsearch:_.bind(this.searchItems,this),onclear:_.bind(this.clearSearch,this)});return f},_firstSearch:function(f){this.log("onFirstSearch",f);return this.searchItems(f)},searchItems:function(f){this.searchFor=f;this.trigger("search:searching",f,this);this.renderItems();this.$("> .controls .search-query").val(f);return this},clearSearch:function(f){this.searchFor="";this.trigger("search:clear",this);this.renderItems();this.$("> .controls .search-query").val("");return this},showSelectors:function(f){f=(f!==undefined)?(f):(this.fxSpeed);this.selecting=true;this.$(".list-actions").slideDown(f);_.each(this.views,function(g){g.showSelector(f)})},hideSelectors:function(f){f=(f!==undefined)?(f):(this.fxSpeed);this.selecting=false;this.$(".list-actions").slideUp(f);_.each(this.views,function(g){g.hideSelector(f)});this.selected=[];this.lastSelected=null},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAll:function(f){_.each(this.views,function(g){g.select(f)})},deselectAll:function(f){this.lastSelected=null;_.each(this.views,function(g){g.deselect(f)})},selectRange:function(h,g){var f=this.viewRange(h,g);_.each(f,function(i){i.select()});return f},getSelectedViews:function(){return _.filter(this.views,function(f){return f.selected})},getSelectedModels:function(){return new this.collection.constructor(_.map(this.getSelectedViews(),function(f){return f.model}))},_showLoadingIndicator:function(g,f,h){this.debug("_showLoadingIndicator",this.indicator,g,f,h);f=(f!==undefined)?(f):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent());this.debug("\t created",this.indicator)}if(!this.$el.is(":visible")){this.indicator.show(0,h)}else{this.$el.fadeOut(f);this.indicator.show(g,f,h)}},_hideLoadingIndicator:function(f,g){this.debug("_hideLoadingIndicator",this.indicator,f,g);f=(f!==undefined)?(f):(this.fxSpeed);if(this.indicator){this.indicator.hide(f,g)}},scrollPosition:function(){return this.$scrollContainer().scrollTop()},scrollTo:function(g,f){f=f||0;this.$scrollContainer().animate({scrollTop:g},f);return this},scrollToTop:function(f){return this.scrollTo(0,f)},scrollToItem:function(f,h){if(!f){return this}var g=f.$el.position().top;return this.scrollTo(g,h)},scrollToId:function(g,f){return this.scrollToItem(this.viewFromModelId(g),f)},events:{"click .select-all":"selectAll","click .deselect-all":"deselectAll"},toString:function(){return"ListPanel("+this.collection+")"}});e.prototype.templates=(function(){var g=b.wrapTemplate(["<div>",'<div class="controls"></div>','<div class="list-items"></div>','<div class="empty-message infomessagesmall"></div>',"</div>"]);var f=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= view.title %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return{el:g,controls:f}}());var a=e.extend({modelCollectionKey:"contents",initialize:function(f){e.prototype.initialize.call(this,f);this.selecting=(f.selecting!==undefined)?f.selecting:false;this.setModel(this.model,f)},setModel:function(g,f){f=f||{};this.debug(this+".setModel:",g,f);this.freeModel();this.freeViews();if(g){var h=this.model?this.model.get("id"):null;this.model=g;if(this.logger){this.model.logger=this.logger}this._setUpModelListeners();this.collection.off();this.collection=(this.model[this.modelCollectionKey])?this.model[this.modelCollectionKey]:(f.collection||(new this.collectionClass([])));this._setUpCollectionListeners();if(h&&g.get("id")!==h){this.trigger("new-model",this)}}return this},freeModel:function(){if(this.model){this.stopListening(this.model)}return this},_setUpModelListeners:function(){this.log(this+"._setUpModelListeners",this.model);this.model.on("error",function(){this.trigger.apply(panel,arguments)},this);return this},_renderControls:function(g){this.debug(this+"(ListPanel)._renderControls");var h=this.model?this.model.toJSON():{},f=$(this.templates.controls(h,this));g.find(".controls").replaceWith(f);return f},toString:function(){return"ModelListPanel("+this.model+")"}});a.prototype.templates=(function(){var f=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= model.name %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return _.extend(_.clone(e.prototype.templates),{controls:f})}());return{ListPanel:e,ModelListPanel:a}});
\ No newline at end of file
+define(["mvc/list/list-item","mvc/base-mvc","utils/localization","jq-plugins/ui/search-input"],function(d,b,c){var e=Backbone.View.extend(b.LoggableMixin).extend({viewClass:d.ListItemView,collectionClass:Backbone.Collection,tagName:"div",className:"list-panel",fxSpeed:"fast",emptyMsg:c("This list is empty"),noneFoundMsg:c("No matching items found"),searchPlaceholder:c("search"),multiselectActions:[],initialize:function(f,g){f=f||{};if(f.logger){this.logger=f.logger}this.log(this+".initialize:",f);this.fxSpeed=_.has(f,"fxSpeed")?(f.fxSpeed):(this.fxSpeed);this.filters=[];this.searchFor=f.searchFor||"";this.indicator=new LoadingIndicator(this.$el);this.selecting=(f.selecting!==undefined)?f.selecting:true;this.selected=f.selected||[];this.lastSelected=null;this.dragItems=f.dragItems||false;this.viewClass=f.viewClass||this.viewClass;this.views=[];this.collection=f.collection||(new this.collectionClass([]));this.filters=f.filters||[];this.$scrollContainer=f.$scrollContainer||this.$scrollContainer;this.title=f.title||"";this.subtitle=f.subtitle||"";this.multiselectActions=f.multiselectActions||this.multiselectActions;this.actionsPopup=null;this._setUpListeners()},freeViews:function(){_.each(this.views,function(f){f.off()});this.views=[];return this},_setUpListeners:function(){this.off();this.on("error",function(g,j,f,i,h){console.error(g,j,f,i,h)},this);this.on("loading",function(){this._showLoadingIndicator("loading...",40)},this);this.on("loading-done",function(){this._hideLoadingIndicator(40)},this);this.once("rendered",function(){this.trigger("rendered:initial",this)},this);if(this.logger){this.on("all",function(f){this.log(this+"",arguments)},this)}this._setUpCollectionListeners();this._setUpViewListeners();return this},_setUpCollectionListeners:function(){this.log(this+"._setUpCollectionListeners",this.collection);this.collection.off();this.collection.on("error",function(g,j,f,i,h){this.trigger("error",g,j,f,i,h)},this);this.collection.on("reset",function(){this.renderItems()},this);this.collection.on("add",this.addItemView,this);this.collection.on("remove",this.removeItemView,this);if(this.logger){this.collection.on("all",function(f){this.info(this+"(collection)",arguments)},this)}return this},_setUpViewListeners:function(){this.log(this+"._setUpViewListeners");this.on("view:selected",function(f,g){if(g&&g.shiftKey&&this.lastSelected){var h=this.viewFromModelId(this.lastSelected);if(h){this.selectRange(f,h)}}else{if(g&&g.altKey&&!this.selecting){this.showSelectors()}}this.selected.push(f.model.id);this.lastSelected=f.model.id},this);this.on("view:de-selected",function(f,g){this.selected=_.without(this.selected,f.model.id)},this)},render:function(g){this.log(this+".render",g);var f=this._buildNewRender();this._setUpBehaviors(f);this._queueNewRender(f,g);return this},_buildNewRender:function(){this.debug(this+"(ListPanel)._buildNewRender");var f=$(this.templates.el({},this));this._renderControls(f);this._renderTitle(f);this._renderSubtitle(f);this._renderSearch(f);this.renderItems(f);return f},_renderControls:function(g){this.debug(this+"(ListPanel)._renderControls");var f=$(this.templates.controls({},this));g.find(".controls").replaceWith(f);return f},_renderTitle:function(f){},_renderSubtitle:function(f){},_queueNewRender:function(g,h){h=(h===undefined)?(this.fxSpeed):(h);var f=this;f.log("_queueNewRender:",g,h);$(f).queue("fx",[function(i){this.$el.fadeOut(h,i)},function(i){f._swapNewRender(g);i()},function(i){this.$el.fadeIn(h,i)},function(i){f.trigger("rendered",f);i()}])},_swapNewRender:function(f){this.$el.empty().attr("class",this.className).append(f.children());if(this.selecting){this.showSelectors(0)}return this},_setUpBehaviors:function(f){f=f||this.$el;f.find(".controls [title]").tooltip({placement:"bottom"});return this},$scrollContainer:function(){return this.$el.parent().parent()},$list:function(f){return(f||this.$el).find("> .list-items")},$messages:function(f){return(f||this.$el).find("> .controls .messages")},$emptyMessage:function(f){return(f||this.$el).find("> .empty-message")},renderItems:function(h){h=h||this.$el;var f=this;f.log(this+".renderItems",h);var g=f.$list(h);f.views=f._filterCollection().map(function(i){return f._createItemView(i).render(0)});g.empty();if(f.views.length){f._attachItems(h);f.$emptyMessage(h).hide()}else{f._renderEmptyMessage(h).show()}return f.views},_filterCollection:function(){var f=this;return f.collection.filter(_.bind(f._filterItem,f))},_filterItem:function(g){var f=this;return(_.every(f.filters.map(function(h){return h.call(g)})))&&(!f.searchFor||g.matchesAll(f.searchFor))},_createItemView:function(h){var i=this._getItemViewClass(h),g=_.extend(this._getItemViewOptions(h),{model:h}),f=new i(g);this._setUpItemViewListeners(f);return f},_getItemViewClass:function(f){return this.viewClass},_getItemViewOptions:function(f){return{fxSpeed:this.fxSpeed,expanded:false,selectable:this.selecting,selected:_.contains(this.selected,f.id),draggable:this.dragItems}},_setUpItemViewListeners:function(g){var f=this;g.on("all",function(){var h=Array.prototype.slice.call(arguments,0);h[0]="view:"+h[0];f.trigger.apply(f,h)});g.on("draggable:dragstart",function(k,h){var i={},j=this.getSelectedModels();if(j.length){i=j.toJSON()}else{i=[h.model.toJSON()]}k.dataTransfer.setData("text",JSON.stringify(i))},this);return f},_attachItems:function(f){this.$list(f).append(this.views.map(function(g){return g.$el}));return this},_renderEmptyMessage:function(f){this.debug("_renderEmptyMessage",f,this.searchFor);var g=this.searchFor?this.noneFoundMsg:this.emptyMsg;return this.$emptyMessage(f).text(g)},expandAll:function(){_.each(this.views,function(f){f.expand()})},collapseAll:function(){_.each(this.views,function(f){f.collapse()})},addItemView:function(i,j,h){this.log(this+".addItemView:",i);var g=this;if(!g._filterItem(i)){return undefined}var f=g._createItemView(i);$(f).queue("fx",[function(k){g.$emptyMessage().fadeOut(g.fxSpeed,k)},function(k){g._attachView(f);k()}]);return f},_attachView:function(g){var f=this;f.views.push(g);f.$list().append(g.render(0).$el.hide());g.$el.slideDown(f.fxSpeed)},removeItemView:function(i,j,h){this.log(this+".removeItemView:",i);var g=this,f=g.viewFromModel(i);if(!f){return undefined}g.views=_.without(g.views,f);$({}).queue("fx",[function(k){f.$el.fadeOut(g.fxSpeed,k)},function(k){f.remove();if(!g.views.length){g._renderEmptyMessage().fadeIn(g.fxSpeed,k)}else{k()}}]);return f},viewFromModelId:function(g){for(var f=0;f<this.views.length;f++){if(this.views[f].model.id===g){return this.views[f]}}return undefined},viewFromModel:function(f){if(!f){return undefined}return this.viewFromModelId(f.id)},viewsWhereModel:function(f){return this.views.filter(function(g){var i=g.model.toJSON();for(var h in f){if(f.hasOwnProperty(h)){if(i[h]!==g.model.get(h)){return false}}}return true})},viewRange:function(i,h){if(i===h){return(i)?([i]):([])}var g=this.views.indexOf(i),f=this.views.indexOf(h);if(g===-1||f===-1){if(g===f){return[]}return(g===-1)?([h]):([i])}return(g<f)?this.views.slice(g,f+1):this.views.slice(f,g+1)},_renderSearch:function(f){f.find(".controls .search-input").searchInput({placeholder:this.searchPlaceholder,initialVal:this.searchFor,onfirstsearch:_.bind(this._firstSearch,this),onsearch:_.bind(this.searchItems,this),onclear:_.bind(this.clearSearch,this)});return f},_firstSearch:function(f){this.log("onFirstSearch",f);return this.searchItems(f)},searchItems:function(f){this.searchFor=f;this.trigger("search:searching",f,this);this.renderItems();this.$("> .controls .search-query").val(f);return this},clearSearch:function(f){this.searchFor="";this.trigger("search:clear",this);this.renderItems();this.$("> .controls .search-query").val("");return this},showSelectors:function(f){f=(f!==undefined)?(f):(this.fxSpeed);this.selecting=true;this.$(".list-actions").slideDown(f);_.each(this.views,function(g){g.showSelector(f)})},hideSelectors:function(f){f=(f!==undefined)?(f):(this.fxSpeed);this.selecting=false;this.$(".list-actions").slideUp(f);_.each(this.views,function(g){g.hideSelector(f)});this.selected=[];this.lastSelected=null},toggleSelectors:function(){if(!this.selecting){this.showSelectors()}else{this.hideSelectors()}},selectAll:function(f){_.each(this.views,function(g){g.select(f)})},deselectAll:function(f){this.lastSelected=null;_.each(this.views,function(g){g.deselect(f)})},selectRange:function(h,g){var f=this.viewRange(h,g);_.each(f,function(i){i.select()});return f},getSelectedViews:function(){return _.filter(this.views,function(f){return f.selected})},getSelectedModels:function(){return new this.collection.constructor(_.map(this.getSelectedViews(),function(f){return f.model}))},_showLoadingIndicator:function(g,f,h){this.debug("_showLoadingIndicator",this.indicator,g,f,h);f=(f!==undefined)?(f):(this.fxSpeed);if(!this.indicator){this.indicator=new LoadingIndicator(this.$el,this.$el.parent());this.debug("\t created",this.indicator)}if(!this.$el.is(":visible")){this.indicator.show(0,h)}else{this.$el.fadeOut(f);this.indicator.show(g,f,h)}},_hideLoadingIndicator:function(f,g){this.debug("_hideLoadingIndicator",this.indicator,f,g);f=(f!==undefined)?(f):(this.fxSpeed);if(this.indicator){this.indicator.hide(f,g)}},scrollPosition:function(){return this.$scrollContainer().scrollTop()},scrollTo:function(g,f){f=f||0;this.$scrollContainer().animate({scrollTop:g},f);return this},scrollToTop:function(f){return this.scrollTo(0,f)},scrollToItem:function(f,h){if(!f){return this}var g=f.$el.position().top;return this.scrollTo(g,h)},scrollToId:function(g,f){return this.scrollToItem(this.viewFromModelId(g),f)},events:{"click .select-all":"selectAll","click .deselect-all":"deselectAll"},toString:function(){return"ListPanel("+this.collection+")"}});e.prototype.templates=(function(){var g=b.wrapTemplate(["<div>",'<div class="controls"></div>','<div class="list-items"></div>','<div class="empty-message infomessagesmall"></div>',"</div>"]);var f=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= view.title %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return{el:g,controls:f}}());var a=e.extend({modelCollectionKey:"contents",initialize:function(f){e.prototype.initialize.call(this,f);this.selecting=(f.selecting!==undefined)?f.selecting:false;this.setModel(this.model,f)},setModel:function(g,f){f=f||{};this.debug(this+".setModel:",g,f);this.freeModel();this.freeViews();if(g){var h=this.model?this.model.get("id"):null;this.model=g;if(this.logger){this.model.logger=this.logger}this._setUpModelListeners();this.collection.off();this.collection=(this.model[this.modelCollectionKey])?this.model[this.modelCollectionKey]:(f.collection||(new this.collectionClass([])));this._setUpCollectionListeners();if(h&&g.get("id")!==h){this.trigger("new-model",this)}}return this},freeModel:function(){if(this.model){this.stopListening(this.model)}return this},_setUpModelListeners:function(){this.log(this+"._setUpModelListeners",this.model);this.model.on("error",function(){this.trigger.apply(panel,arguments)},this);return this},_renderControls:function(g){this.debug(this+"(ListPanel)._renderControls");var h=this.model?this.model.toJSON():{},f=$(this.templates.controls(h,this));g.find(".controls").replaceWith(f);return f},toString:function(){return"ModelListPanel("+this.model+")"}});a.prototype.templates=(function(){var f=b.wrapTemplate(['<div class="controls">','<div class="title">','<div class="name"><%= model.name %></div>',"</div>",'<div class="subtitle"><%= view.subtitle %></div>','<div class="actions"></div>','<div class="messages"></div>','<div class="search">','<div class="search-input"></div>',"</div>",'<div class="list-actions">','<div class="btn-group">','<button class="select-all btn btn-default"','data-mode="select">',c("All"),"</button>",'<button class="deselect-all btn btn-default"','data-mode="select">',c("None"),"</button>","</div>","</div>","</div>"]);return _.extend(_.clone(e.prototype.templates),{controls:f})}());return{ListPanel:e,ModelListPanel:a}});
\ No newline at end of file
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/scripts/packed/mvc/ui.js
--- a/static/scripts/packed/mvc/ui.js
+++ b/static/scripts/packed/mvc/ui.js
@@ -1,1 +1,1 @@
-var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";a.parent().find(".loading-indicator").remove();b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b}(function(){var b=window._l||function(d){return d};function a(k,q){var e=27,n=13,d=$(k),f=true,h={initialVal:"",name:"search",placeholder:"search",classes:"",onclear:function(){},onfirstsearch:null,onsearch:function(r){},minSearchLen:0,escWillClear:true,oninit:function(){}};function j(r){var s=$(this).parent().children("input");s.focus().val("").trigger("clear:searchInput");q.onclear()}function p(s,r){$(this).trigger("search:searchInput",r);if(typeof q.onfirstsearch==="function"&&f){f=false;q.onfirstsearch(r)}else{q.onsearch(r)}}function g(){return['<input type="text" name="',q.name,'" placeholder="',q.placeholder,'" ','class="search-query ',q.classes,'" ',"/>"].join("")}function m(){return $(g()).focus(function(r){$(this).select()}).keyup(function(s){s.preventDefault();s.stopPropagation();if(!$(this).val()){$(this).blur()}if(s.which===e&&q.escWillClear){j.call(this,s)}else{var r=$(this).val();if((s.which===n)||(q.minSearchLen&&r.length>=q.minSearchLen)){p.call(this,s,r)}else{if(!r.length){j.call(this,s)}}}}).on("change",function(r){p.call(this,r,$(this).val())}).val(q.initialVal)}function l(){return $(['<span class="search-clear fa fa-times-circle" ','title="',b("clear search (esc)"),'"></span>'].join("")).tooltip({placement:"bottom"}).click(function(r){j.call(this,r)})}function o(){return $(['<span class="search-loading fa fa-spinner fa-spin" ','title="',b("loading..."),'"></span>'].join("")).hide().tooltip({placement:"bottom"})}function i(){d.find(".search-loading").toggle();d.find(".search-clear").toggle()}if(jQuery.type(q)==="string"){if(q==="toggle-loading"){i()}return d}if(jQuery.type(q)==="object"){q=jQuery.extend(true,{},h,q)}return d.addClass("search-input").prepend([m(),l(),o()])}jQuery.fn.extend({searchInput:function c(d){return this.each(function(){return a(this,d)})}})}());
\ No newline at end of file
+var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.toJSON());a.tooltip(this.model.get("tooltip_config"));this.$el.replaceWith(a);this.setElement(a);return this},events:{click:"click"},click:function(a){if(_.isFunction(this.model.get("on_click"))){this.model.get("on_click")(a);return false}return true},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b;if(!this.$button.size()){this.$button=$("<div/>")}this.options=a||[];var c=this;this.$button.click(function(d){$(".popmenu-wrapper").remove();c._renderAndShow(d);return false})},_renderAndShow:function(a){this.render();this.$el.appendTo("body").css(this._getShownPosition(a)).show();this._setUpCloseBehavior()},render:function(){this.$el.addClass("popmenu-wrapper").hide().css({position:"absolute"}).html(this.template(this.$button.attr("id"),this.options));if(this.options.length){var a=this;this.$el.find("li").each(function(c,b){var d=a.options[c];if(d.func){$(this).children("a.popupmenu-option").click(function(e){d.func.call(a,e,d)})}})}return this},template:function(b,a){return['<ul id="',b,'-menu" class="dropdown-menu">',this._templateOptions(a),"</ul>"].join("")},_templateOptions:function(a){if(!a.length){return"<li>(no options)</li>"}return _.map(a,function(d){if(d.divider){return'<li class="divider"></li>'}else{if(d.header){return['<li class="head"><a href="javascript:void(0);">',d.html,"</a></li>"].join("")}}var c=d.href||"javascript:void(0);",e=(d.target)?(' target="'+d.target+'"'):(""),b=(d.checked)?('<span class="fa fa-check"></span>'):("");return['<li><a class="popupmenu-option" href="',c,'"',e,">",b,d.html,"</a></li>"].join("")}).join("")},_getShownPosition:function(b){var c=this.$el.width();var a=b.pageX-c/2;a=Math.min(a,$(document).scrollLeft()+$(window).width()-c-5);a=Math.max(a,$(document).scrollLeft()+5);return{top:b.pageY,left:a}},_setUpCloseBehavior:function(){var c=this;function a(e){$(document).off("click.close_popup");if(window.parent!==window){try{$(window.parent.document).off("click.close_popup")}catch(d){}}else{try{$("iframe#galaxy_main").contents().off("click.close_popup")}catch(d){}}c.remove()}$("html").one("click.close_popup",a);if(window.parent!==window){try{$(window.parent.document).find("html").one("click.close_popup",a)}catch(b){}}else{try{$("iframe#galaxy_main").contents().one("click.close_popup",a)}catch(b){}}},addItem:function(b,a){a=(a>=0)?a:this.options.length;this.options.splice(a,0,b);return this},removeItem:function(a){if(a>=0){this.options.splice(a,1)}return this},findIndexByHtml:function(b){for(var a=0;a<this.options.length;a++){if(_.has(this.options[a],"html")&&(this.options[a].html===b)){return a}}return null},findItemByHtml:function(a){return this.options[(this.findIndexByHtml(a))]},toString:function(){return"PopupMenu"}});PopupMenu.create=function _create(b,a){return new PopupMenu(b,a)};PopupMenu.make_popupmenu=function(b,c){var a=[];_.each(c,function(f,d){var e={html:d};if(f===null){e.header=true}else{if(jQuery.type(f)==="function"){e.func=f}}a.push(e)});return new PopupMenu($(b),a)};PopupMenu.convertLinksToOptions=function(c,a){c=$(c);a=a||"a";var b=[];c.find(a).each(function(g,e){var f={},d=$(g);f.html=d.text();if(d.attr("href")){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;default:window.location=j}}}b.push(f)});return b};PopupMenu.fromExistingDom=function(d,c,a){d=$(d);c=$(c);var b=PopupMenu.convertLinksToOptions(c,a);c.remove();return new PopupMenu(d,b)};PopupMenu.make_popup_menus=function(c,b,d){c=c||document;b=b||"div[popupmenu]";d=d||function(e,f){return"#"+e.attr("popupmenu")};var a=[];$(c).find(b).each(function(){var e=$(this),f=$(c).find(d(e,c));a.push(PopupMenu.fromDom(f,e));f.addClass("popup")});return a};var faIconButton=function(a){a=a||{};a.tooltipConfig=a.tooltipConfig||{placement:"bottom"};a.classes=["icon-btn"].concat(a.classes||[]);if(a.disabled){a.classes.push("disabled")}var b=['<a class="',a.classes.join(" "),'"',((a.title)?(' title="'+a.title+'"'):("")),((!a.disabled&&a.target)?(' target="'+a.target+'"'):("")),' href="',((!a.disabled&&a.href)?(a.href):("javascript:void(0);")),'">','<span class="fa ',a.faIcon,'"></span>',"</a>"].join("");var c=$(b).tooltip(a.tooltipConfig);if(_.isFunction(a.onclick)){c.click(a.onclick)}return c};function LoadingIndicator(a,c){var b=this;c=jQuery.extend({cover:false},c||{});function d(){var e=['<div class="loading-indicator">','<div class="loading-indicator-text">','<span class="fa fa-spinner fa-spin fa-lg"></span>','<span class="loading-indicator-message">loading...</span>',"</div>","</div>"].join("\n");var g=$(e).hide().css(c.css||{position:"fixed"}),f=g.children(".loading-indicator-text");if(c.cover){g.css({"z-index":2,top:a.css("top"),bottom:a.css("bottom"),left:a.css("left"),right:a.css("right"),opacity:0.5,"background-color":"white","text-align":"center"});f=g.children(".loading-indicator-text").css({"margin-top":"20px"})}else{f=g.children(".loading-indicator-text").css({margin:"12px 0px 0px 10px",opacity:"0.85",color:"grey"});f.children(".loading-indicator-message").css({margin:"0px 8px 0px 0px","font-style":"italic"})}return g}b.show=function(f,e,g){f=f||"loading...";e=e||"fast";a.parent().find(".loading-indicator").remove();b.$indicator=d().insertBefore(a);b.message(f);b.$indicator.fadeIn(e,g);return b};b.message=function(e){b.$indicator.find("i").text(e)};b.hide=function(e,f){e=e||"fast";if(b.$indicator&&b.$indicator.size()){b.$indicator.fadeOut(e,function(){b.$indicator.remove();if(f){f()}})}else{if(f){f()}}return b};return b};
\ No newline at end of file
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1584,7 +1584,6 @@
.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}
.jstree-default-large.jstree-rtl .jstree-last{background:transparent}
@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white} #jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px} #jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("../images/jstree/40px.png");background-position:0 -200px;background-size:120px 240px} #jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("../images/jstree/40px.png");background-position:-40px -200px;background-size:120px 240px} #jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive{} .jstree-default-responsive .jstree-icon{background-image:url("../images/jstree/40px.png")} .jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap} .jstree-default-responsive .jstree-anchor{line-height:40px;height:40px} .jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px} .jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0} .jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px} .jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0} .jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px} .jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0px !important} .jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important} .jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important} .jstree-default-responsive .jstree-themeicon{background-position:-40px -40px} .jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px} .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px} .jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px} .jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white} .jstree-default-responsive>.jstree-striped{background:transparent} .jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px} .jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9} .jstree-default-responsive .jstree-wholerow-clicked{background:#beebff} .jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666} .jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666;border-top:0} .jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none} .jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("../images/jstree/40px.png");background-size:120px 240px} .jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y} .jstree-default-responsive .jstree-last{background:transparent} .jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px} .jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px} .jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0} .jstree-default-responsive .jstree-file{background:url("../images/jstree/40px.png") 0 -160px no-repeat;background-size:120px 240px} .jstree-default-responsive .jstree-folder{background:url("../images/jstree/40px.png") -40px -40px no-repeat;background-size:120px 240px}}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}
-.select2-minwidth{min-width:256px}
.unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}
.parent-width{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;*width:90%}
.clear:before,.clear:after{content:" ";display:table;}
@@ -1878,9 +1877,6 @@
.list-panel .empty-message{display:none;margin:0px}
.list-item .details .list-panel{margin-top:8px;border-radius:3px;background:white;padding:4px}.list-item .details .list-panel .list-items{border:1px solid #bfbfbf;border-radius:3px}.list-item .details .list-panel .list-items .list-item:first-child{border-top-width:0px;border-radius:3px 3px 0px 0px}
.list-item .details .list-panel .list-items .list-item:last-child{border-bottom-width:0px;border-radius:0px 0px 3px 3px}
-.search-input .search-query{width:100%;padding-right:24px}
-.search-input .search-clear,.search-input .search-loading{position:relative;display:inline-block;float:right;margin-top:-24px;margin-right:4px;font-size:1.4em;line-height:23px;color:grey}
-.search-input .search-clear:hover{color:#303030}
.history-panel-header .panel-header-button{display:inline-block;height:22px;width:22px;text-align:center;line-height:19px;font-size:1.2em;padding:0px}
.state-icon{font-family:FontAwesome;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;margin-right:4px;vertical-align:middle;width:16px;height:16px;line-height:16px;text-align:center;font-size:16px}
.state-icon-running{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)} 100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)} 100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)} 100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)} 100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)} 100%{transform:rotate(359deg)}}.state-icon-running:before{content:"\f110"}
@@ -2081,6 +2077,9 @@
.collection-creator .footer .attributes .collection-name-prompt.validation-warning:before{content:'(required)';margin-right:4px;color:red}
.collection-creator .footer .attributes .collection-name{width:50%}.collection-creator .footer .attributes .collection-name.validation-warning{border-color:red}
.collection-creator .footer .actions .other-options>*{display:none;margin-left:4px}
+.search-input .search-query{width:100%;padding-right:24px}
+.search-input .search-clear,.search-input .search-loading{position:relative;display:inline-block;float:right;margin-top:-24px;margin-right:4px;font-size:1.4em;line-height:23px;color:grey}
+.search-input .search-clear:hover{color:#303030}
.dataset-choice{border:1px solid lightgrey;border-radius:3px;overflow:hidden;padding:10px 8px 8px 8px}.dataset-choice:hover{border-color:black;cursor:pointer}.dataset-choice:hover>*{cursor:pointer}
.dataset-choice .prompt{margin-right:8px}.dataset-choice .prompt:after{content:':'}
.dataset-choice .prompt:empty{display:none}
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/style/src/less/base.less
--- a/static/style/src/less/base.less
+++ b/static/style/src/less/base.less
@@ -15,11 +15,11 @@
}
@import "select2.less";
-
/* fix for zero width select2 - remove when fixed there */
.select2-minwidth {
min-width: 256px;
}
+
// galaxy sub-components
@import "frame.less";
@import "upload.less";
@@ -30,12 +30,6 @@
// Mixins
-
-/* fix for zero width select2 - remove when fixed there */
-.select2-minwidth {
- min-width: 256px;
-}
-
.unselectable {
.user-select(none);
}
@@ -1457,6 +1451,7 @@
@import "ui/paired-collection-creator.less";
+@import "ui/search-input.less";
@import "ui/dataset-choice.less";
@import "ui/peek-column-selector.less";
@import "ui/pagination.less";
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/style/src/less/history.less
--- a/static/style/src/less/history.less
+++ b/static/style/src/less/history.less
@@ -1,29 +1,3 @@
-// ---------------------------------------------------------------------------- search bar
-.search-input {
- .search-query {
- width : 100%;
- padding-right : 24px;
- }
- .search-clear,
- .search-loading {
- // it places the icons on the right of the bar (and puts the lotion on its skin)
- position : relative;
- display : inline-block;
-
- float : right;
- margin-top : -24px;
- margin-right : 4px;
-
- font-size : 1.4em;
- line-height : 23px;
- color : grey;
- }
-
- .search-clear:hover {
- color : @link-color;
- }
-}
-
// ---------------------------------------------------------------------------- panel header buttons
.history-panel-header {
.panel-header-button {
diff -r b51b59a29c9025290c572ecd6b842518a90a2b50 -r 33f1bf5be91b6aee2ff0a42d4315b43da0a5da33 static/style/src/less/ui/search-input.less
--- /dev/null
+++ b/static/style/src/less/ui/search-input.less
@@ -0,0 +1,26 @@
+// search bar, see: scripts/jq-plugins/ui/search-input.js
+.search-input {
+ .search-query {
+ width : 100%;
+ padding-right : 24px;
+ }
+ .search-clear,
+ .search-loading {
+ // it places the icons on the right of the bar (and puts the lotion on its skin)
+ position : relative;
+ display : inline-block;
+
+ float : right;
+ margin-top : -24px;
+ margin-right : 4px;
+
+ font-size : 1.4em;
+ line-height : 23px;
+ color : grey;
+ }
+
+ .search-clear:hover {
+ color : @link-color;
+ }
+}
+
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/59d5d556b664/
Changeset: 59d5d556b664
Branch: next-stable
User: jmchilton
Date: 2014-12-09 14:33:35+00:00
Summary: Merge stable.
Affected #: 11 files
diff -r ac30ccd5cd1e285390706592a0b005f79456cbac -r 59d5d556b6647c245fc26f331eb01e9d597c698a templates/refresh_frames.mako
--- a/templates/refresh_frames.mako
+++ b/templates/refresh_frames.mako
@@ -21,7 +21,7 @@
## Refresh masthead == user changes (backward compatibility)
if ( parent.user_changed ) {
%if trans.user:
- parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
+ parent.user_changed( "${trans.user.email | h }", ${int( app.config.is_admin_user( trans.user ) )} );
%else:
parent.user_changed( null, false );
%endif
https://bitbucket.org/galaxy/galaxy-central/commits/b51b59a29c90/
Changeset: b51b59a29c90
User: jmchilton
Date: 2014-12-09 14:33:49+00:00
Summary: Merge next-stable.
Affected #: 11 files
diff -r 511fbb67b820735128ee02e526fb6873beaa961e -r b51b59a29c9025290c572ecd6b842518a90a2b50 templates/refresh_frames.mako
--- a/templates/refresh_frames.mako
+++ b/templates/refresh_frames.mako
@@ -21,7 +21,7 @@
## Refresh masthead == user changes (backward compatibility)
if ( parent.user_changed ) {
%if trans.user:
- parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} );
+ parent.user_changed( "${trans.user.email | h }", ${int( app.config.is_admin_user( trans.user ) )} );
%else:
parent.user_changed( null, false );
%endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0