commit/galaxy-central: 2 new changesets
2 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/6d7e637883b7/ changeset: 6d7e637883b7 user: carlfeberhard date: 2012-12-07 19:56:53 summary: ui: adding PopupMenu view as alternate to make_popup_menu and allow changing option text, adding/removing options, and adding checkmarks for togglable options; index.mako: use PopupMenu for history-options-button; history panel: use alternate_history.mako to add 'collapse all', 'Include hidden datasets'(toggle), 'Include deleted datasets'(toggle) to history-options-button; alternate_history.mako: include better system for debugging js when changing source directly is problematic (main/test); pack_scripts; affected #: 19 files diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 lib/galaxy/webapps/galaxy/controllers/root.py --- a/lib/galaxy/webapps/galaxy/controllers/root.py +++ b/lib/galaxy/webapps/galaxy/controllers/root.py @@ -98,7 +98,6 @@ return trans.fill_template_mako( "/my_data.mako" ) @web.expose - #def history( self, trans, as_xml=False, show_deleted=False, show_hidden=False, hda_id=None, **kwd ): def history( self, trans, as_xml=False, show_deleted=None, show_hidden=None, hda_id=None, **kwd ): """ Display the current history, creating a new history if necessary. diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/mvc/base-mvc.js --- a/static/scripts/mvc/base-mvc.js +++ b/static/scripts/mvc/base-mvc.js @@ -288,7 +288,7 @@ }, /** String representation. */ - toString : function(){ return 'PersistantStorage(' + data + ')'; } + toString : function(){ return 'PersistantStorage(' + storageKey + ')'; } }); return returnedStorage; diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/mvc/dataset/hda-base.js --- a/static/scripts/mvc/dataset/hda-base.js +++ b/static/scripts/mvc/dataset/hda-base.js @@ -28,6 +28,7 @@ * @see Backbone.View#initialize */ initialize : function( attributes ){ + if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; } this.log( this + '.initialize:', attributes ); /** list of rendering functions for the default, primary icon-buttons. */ @@ -334,6 +335,8 @@ //TODO: not a fan of this dispatch switch( this.model.get( 'state' ) ){ + case HistoryDatasetAssociation.STATES.NEW : + break; case HistoryDatasetAssociation.STATES.NOT_VIEWABLE : this._render_body_not_viewable( body ); break; diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/mvc/dataset/hda-model.js --- a/static/scripts/mvc/dataset/hda-model.js +++ b/static/scripts/mvc/dataset/hda-model.js @@ -130,8 +130,7 @@ //TODO: to list inclusion test //TODO: class level readyStates list return ( - ( state === HistoryDatasetAssociation.STATES.NEW ) - || ( state === HistoryDatasetAssociation.STATES.OK ) + ( state === HistoryDatasetAssociation.STATES.OK ) || ( state === HistoryDatasetAssociation.STATES.EMPTY ) || ( state === HistoryDatasetAssociation.STATES.FAILED_METADATA ) || ( state === HistoryDatasetAssociation.STATES.NOT_VIEWABLE ) diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/mvc/history/history-panel.js --- a/static/scripts/mvc/history/history-panel.js +++ b/static/scripts/mvc/history/history-panel.js @@ -140,6 +140,8 @@ * @see Backbone.View#initialize */ initialize : function( attributes ){ + // set the logger if requested + if( attributes.logger ){ this.logger = this.model.logger = attributes.logger; } this.log( this + '.initialize:', attributes ); // set up url templates @@ -203,7 +205,7 @@ show_deleted : false, show_hidden : false }); - this.log( 'this.storage:', this.storage.get() ); + this.log( this + ' (prev) storage:', JSON.stringify( this.storage.get(), null, 2 ) ); // expanded Hdas is a map of hda.ids -> a boolean rep'ing whether this hda's body is expanded // store any pre-expanded ids passed in @@ -226,7 +228,7 @@ this.show_deleted = this.storage.get( 'show_deleted' ); this.show_hidden = this.storage.get( 'show_hidden' ); //this.log( 'this.show_deleted:', this.show_deleted, 'show_hidden', this.show_hidden ); - this.log( '(init\'d) this.storage:', this.storage.get() ); + this.log( this + ' (init\'d) storage:', this.storage.get() ); }, /** Add an hda to this history's collection @@ -351,7 +353,8 @@ historyView.hdaViews[ hdaId ] = new historyView.HDAView({ model : hda, expanded : expanded, - urlTemplates : historyView.hdaUrlTemplates + urlTemplates : historyView.hdaUrlTemplates, + logger : historyView.logger }); historyView._setUpHdaListeners( historyView.hdaViews[ hdaId ] ); @@ -432,19 +435,23 @@ /** Handle the user toggling the deleted visibility by: * (1) storing the new value in the persistant storage * (2) re-rendering the history + * @returns {Boolean} new show_deleted setting */ toggleShowDeleted : function(){ this.storage.set( 'show_deleted', !this.storage.get( 'show_deleted' ) ); this.render(); + return this.storage.get( 'show_deleted' ); }, /** Handle the user toggling the deleted visibility by: * (1) storing the new value in the persistant storage * (2) re-rendering the history + * @returns {Boolean} new show_hidden setting */ toggleShowHidden : function(){ this.storage.set( 'show_hidden', !this.storage.get( 'show_hidden' ) ); this.render(); + return this.storage.get( 'show_hidden' ); }, /** Collapse all hda bodies and clear expandedHdas in the storage diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/mvc/ui.js --- a/static/scripts/mvc/ui.js +++ b/static/scripts/mvc/ui.js @@ -76,11 +76,11 @@ iconButton : Handlebars.partials.iconButton }; - var IconButtonCollection = Backbone.Collection.extend({ model: IconButton }); + //------------------------------------------------------------------------------ /** * Menu with multiple icon buttons. Views are not needed nor used for individual buttons. @@ -166,15 +166,319 @@ }); +// ============================================================================= +/** @class View for a popup menu + * @name PopupMenu + * + * @constructs + */ +var PopupMenu = Backbone.View.extend( +/** @lends PopupMenu.prototype */{ + /* TODO: + add submenus + add hrefs + test various html keys + add make_popupmenus style + get template inside this file somehow + */ + /** 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. + */ + //TODO: include docs on special option keys (divider, checked, etc.) + initialize : function( $button, options ){ + // default settings + this.$button = $button || $( '<div/>' ); + this.options = options || []; + //console.debug( this + '.initialize, button:', $button, ', options:', options ); + // set up button click -> open menu behavior + var menu = this; + this.$button.click( function( event ){ + menu._renderAndShow( event ); + //event.stopPropagation(); + return false; + }); + // attach this view as a data object on the button - for later access + //TODO:?? memleak? + this.$button.data( 'PopupMenu', this ); + // template loading is problematic - ui is loaded in base.mako + // and the template (prev.) needed to be loaded before ui + if( !this.templates.wrapper ){ + this.templates.wrapper = Handlebars.templates[ 'template-popupmenu-wrapper' ]; + } + }, + /** Render the menu. NOTE: doesn't attach itself to the DOM. + * @see PopupMenu#_renderAndShow + */ + render : function(){ + var menu = this; + // render the menu body + this.$el.addClass( 'popmenu-wrapper' ) + .css({ + position: 'absolute', + display: 'none' + }); + //BUG: anchors within a.popupmenu-option render OUTSIDE the a.popupmenu-option!? + this.$el.html( PopupMenu.templates.menu({ + options : this.options, + // sets menu div id to '{{ id }}-menu' + id : this.$button.attr( 'id' ) + })); + //console.debug( this.$el, ':', this.$el.html() ); + // set up behavior on each link/anchor elem + if( this.options.length ){ + this.$el.find( 'li' ).each( function( i, li ){ + var $li = $( li ), + $anchor = $li.children( 'a.popupmenu-option' ), + menuFunc = menu.options[ i ].func; + //console.debug( 'setting up behavior:', i, menu.options[ i ], $li, $anchor ); + if( $anchor.length && menuFunc ){ + $anchor.click( function( event ){ + menuFunc( event, menu.options[ i ] ); + }); + } + // cache the anchor as a jq obj within the options obj + menu.options[ i ].$li = $li; + }); + } + return this; + }, + /** Get the absolute position/offset for the menu + */ + _getShownPosition : function( clickEvent ){ + var menuWidth = this.$el.width(), + // display menu horiz. centered on click... + x = clickEvent.pageX - menuWidth / 2 ; + // ...but adjust that 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 + }; + }, + + /** 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' ); + this.$el.css( this._getShownPosition( clickEvent ) ); + this._setUpCloseBehavior(); + this.$el.show(); + }, + + /** Bind an event handler to all available frames so that when anything is clicked + * * the menu is removed from the DOM + * * The event handler unbinds itself + */ + _setUpCloseBehavior : function(){ + var menu = this, + // function to close popup and unbind itself + closePopupWhenClicked = function( $elClicked ){ + $elClicked.bind( "click.close_popup", function(){ + menu.remove(); + $elClicked.unbind( "click.close_popup" ); + }); + }; + + // bind to current, parent, and sibling frames + //TODO: (Assuming for now that this is the best way to do this...) + closePopupWhenClicked( $( window.document ) ); + closePopupWhenClicked( $( window.top.document ) ); + _.each( window.top.frames, function( siblingFrame ){ + closePopupWhenClicked( $( siblingFrame.document ) ); + }); + }, + + /** 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 it's 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 it's html + */ + findItemByHtml : function( html ){ + return this.options[( this.findIndexByHtml( html ) )]; + }, + + /** String representation. */ + toString : function(){ + return 'PopupMenu'; + } +}); +PopupMenu.templates = { + menu : Handlebars.templates[ 'template-popupmenu-menu' ] +}; + +// ----------------------------------------------------------------------------- +// 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( linkHref ){ + 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: + var f; + switch( linkTarget ){ + // relocate the center panel + case '_parent': + window.parent.location = linkHref; + break; + + // relocate the entire window + case '_top': + window.top.location = linkHref; + break; + + // Http request target is a window named demolocal on the local box + //TODO: I still don't understand this option (where the hell does f get set? confirm?) + case 'demo': + if( f === undefined || f.closed ){ + f = window.open( linkHref, linkTarget ); + f.creator = self; + } + 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 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/packed/mvc/base-mvc.js --- a/static/scripts/packed/mvc/base-mvc.js +++ b/static/scripts/packed/mvc/base-mvc.js @@ -1,1 +1,1 @@ -var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){return this.logger.log.apply(this.logger,arguments)}return undefined}};var GalaxyLocalization=jQuery.extend({},{ALIAS_NAME:"_l",localizedStrings:{},setLocalizedString:function(b,a){var c=this;var d=function(f,e){if(f!==e){c.localizedStrings[f]=e}};if(jQuery.type(b)==="string"){d(b,a)}else{if(jQuery.type(b)==="object"){jQuery.each(b,function(e,f){d(e,f)})}else{throw ("Localization.setLocalizedString needs either a string or object as the first argument, given: "+b)}}},localize:function(a){return this.localizedStrings[a]||a},toString:function(){return"GalaxyLocalization"}});window[GalaxyLocalization.ALIAS_NAME]=function(a){return GalaxyLocalization.localize(a)};var PersistantStorage=function(g,d){if(!g){throw ("PersistantStorage needs storageKey argument")}d=d||{};var b=jQuery.jStorage.get,c=jQuery.jStorage.set,a=jQuery.jStorage.deleteKey;function e(i,h){i=i||{};h=h||null;return{get:function(j){if(j===undefined){return i}else{if(i.hasOwnProperty(j)){return(jQuery.type(i[j])==="object")?(new e(i[j],this)):(i[j])}}return undefined},set:function(j,k){i[j]=k;this._save();return this},deleteKey:function(j){delete i[j];this._save();return this},_save:function(){return h._save()},toString:function(){return("StorageRecursionHelper("+i+")")}}}var f={};data=b(g);if(data===null){data=jQuery.extend(true,{},d);c(g,data)}f=new e(data);jQuery.extend(f,{_save:function(h){return c(g,f.get())},destroy:function(){return a(g)},toString:function(){return"PersistantStorage("+data+")"}});return f}; \ No newline at end of file +var BaseModel=Backbone.RelationalModel.extend({defaults:{name:null,hidden:false},show:function(){this.set("hidden",false)},hide:function(){this.set("hidden",true)},is_visible:function(){return !this.attributes.hidden}});var BaseView=Backbone.View.extend({initialize:function(){this.model.on("change:hidden",this.update_visible,this);this.update_visible()},update_visible:function(){if(this.model.attributes.hidden){this.$el.hide()}else{this.$el.show()}}});var LoggableMixin={logger:null,log:function(){if(this.logger){return this.logger.log.apply(this.logger,arguments)}return undefined}};var GalaxyLocalization=jQuery.extend({},{ALIAS_NAME:"_l",localizedStrings:{},setLocalizedString:function(b,a){var c=this;var d=function(f,e){if(f!==e){c.localizedStrings[f]=e}};if(jQuery.type(b)==="string"){d(b,a)}else{if(jQuery.type(b)==="object"){jQuery.each(b,function(e,f){d(e,f)})}else{throw ("Localization.setLocalizedString needs either a string or object as the first argument, given: "+b)}}},localize:function(a){return this.localizedStrings[a]||a},toString:function(){return"GalaxyLocalization"}});window[GalaxyLocalization.ALIAS_NAME]=function(a){return GalaxyLocalization.localize(a)};var PersistantStorage=function(g,d){if(!g){throw ("PersistantStorage needs storageKey argument")}d=d||{};var b=jQuery.jStorage.get,c=jQuery.jStorage.set,a=jQuery.jStorage.deleteKey;function e(i,h){i=i||{};h=h||null;return{get:function(j){if(j===undefined){return i}else{if(i.hasOwnProperty(j)){return(jQuery.type(i[j])==="object")?(new e(i[j],this)):(i[j])}}return undefined},set:function(j,k){i[j]=k;this._save();return this},deleteKey:function(j){delete i[j];this._save();return this},_save:function(){return h._save()},toString:function(){return("StorageRecursionHelper("+i+")")}}}var f={};data=b(g);if(data===null){data=jQuery.extend(true,{},d);c(g,data)}f=new e(data);jQuery.extend(f,{_save:function(h){return c(g,f.get())},destroy:function(){return a(g)},toString:function(){return"PersistantStorage("+g+")"}});return f}; \ No newline at end of file diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/packed/mvc/dataset/hda-base.js --- a/static/scripts/packed/mvc/dataset/hda-base.js +++ b/static/scripts/packed/mvc/dataset/hda-base.js @@ -1,1 +1,1 @@ -var HDABaseView=BaseView.extend(LoggableMixin).extend({tagName:"div",className:"historyItemContainer",initialize:function(a){this.log(this+".initialize:",a);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];if(!a.urlTemplates){throw ("HDAView needs urlTemplates on initialize")}this.urlTemplates=a.urlTemplates;this.expanded=a.expanded||false;this.model.bind("change",this.render,this)},render:function(){var b=this,e=this.model.get("id"),c=this.model.get("state"),a=$("<div/>").attr("id","historyItem-"+e),d=(this.$el.children().size()===0);this.$el.attr("id","historyItemContainer-"+e);this.urls=this._renderUrls(this.urlTemplates,this.model.toJSON());a.addClass("historyItemWrapper").addClass("historyItem").addClass("historyItem-"+c);a.append(this._render_warnings());a.append(this._render_titleBar());this.body=$(this._render_body());a.append(this.body);make_popup_menus(a);a.find(".tooltip").tooltip({placement:"bottom"});this.$el.fadeOut("fast",function(){b.$el.children().remove();b.$el.append(a).fadeIn("fast",function(){b.log(b+" rendered:",b.$el);var f="rendered";if(d){f+=":initial"}else{if(b.model.inReadyState()){f+=":ready"}}b.trigger(f)})});return this},_renderUrls:function(d,a){var b=this,c={};_.each(d,function(e,f){if(_.isObject(e)){c[f]=b._renderUrls(e,a)}else{if(f==="meta_download"){c[f]=b._renderMetaDownloadUrls(e,a)}else{try{c[f]=_.template(e,a)}catch(g){throw (b+"._renderUrls error: "+g+"\n rendering:"+e+"\n with "+JSON.stringify(a))}}}});return c},_renderMetaDownloadUrls:function(b,a){return _.map(a.meta_files,function(c){return{url:_.template(b,{id:a.id,file_type:c.file_type}),file_type:c.file_type}})},_render_warnings:function(){return $(jQuery.trim(HDABaseView.templates.messages(this.model.toJSON())))},_render_titleBar:function(){var a=$('<div class="historyItemTitleBar" style="overflow: hidden"></div>');a.append(this._render_titleButtons());a.append('<span class="state-icon"></span>');a.append(this._render_titleLink());return a},_render_titleButtons:function(){var a=$('<div class="historyItemButtons"></div>');a.append(this._render_displayButton());return a},_render_displayButton:function(){if((!this.model.inReadyState())||(this.model.get("state")===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.displayButton=null;return null}var a={icon_class:"display",target:"galaxy_main"};if(this.model.get("purged")){a.enabled=false;a.title=_l("Cannot display datasets removed from disk")}else{a.title=_l("Display data in browser");a.href=this.urls.display}this.displayButton=new IconButtonView({model:new IconButton(a)});return this.displayButton.render().$el},_render_titleLink:function(){return $(jQuery.trim(HDABaseView.templates.titleLink(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_hdaSummary:function(){var a=_.extend(this.model.toJSON(),{urls:this.urls});return HDABaseView.templates.hdaSummary(a)},_render_primaryActionButtons:function(c){var a=this,b=$("<div/>").attr("id","primary-actions-"+this.model.get("id"));_.each(c,function(d){b.append(d.call(a))});return b},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var a=HDABaseView.templates.downloadLinks(_.extend(this.model.toJSON(),{urls:this.urls}));return $(a)},_render_showParamsButton:function(){this.showParamsButton=new IconButtonView({model:new IconButton({title:_l("View details"),href:this.urls.show_params,target:"galaxy_main",icon_class:"information"})});return this.showParamsButton.render().$el},_render_displayApps:function(){if(!this.model.hasData()){return null}var a=$("<div/>").addClass("display-apps");if(!_.isEmpty(this.model.get("display_types"))){a.append(HDABaseView.templates.displayApps({displayApps:this.model.get("display_types")}))}if(!_.isEmpty(this.model.get("display_apps"))){a.append(HDABaseView.templates.displayApps({displayApps:this.model.get("display_apps")}))}return a},_render_peek:function(){if(!this.model.get("peek")){return null}return $("<div/>").append($("<pre/>").attr("id","peek"+this.model.get("id")).addClass("peek").append(this.model.get("peek")))},_render_body:function(){var a=$("<div/>").attr("id","info-"+this.model.get("id")).addClass("historyItemBody").attr("style","display: block");switch(this.model.get("state")){case HistoryDatasetAssociation.STATES.NOT_VIEWABLE:this._render_body_not_viewable(a);break;case HistoryDatasetAssociation.STATES.UPLOAD:this._render_body_uploading(a);break;case HistoryDatasetAssociation.STATES.PAUSED:this._render_body_paused(a);break;case HistoryDatasetAssociation.STATES.QUEUED:this._render_body_queued(a);break;case HistoryDatasetAssociation.STATES.RUNNING:this._render_body_running(a);break;case HistoryDatasetAssociation.STATES.ERROR:this._render_body_error(a);break;case HistoryDatasetAssociation.STATES.DISCARDED:this._render_body_discarded(a);break;case HistoryDatasetAssociation.STATES.SETTING_METADATA:this._render_body_setting_metadata(a);break;case HistoryDatasetAssociation.STATES.EMPTY:this._render_body_empty(a);break;case HistoryDatasetAssociation.STATES.FAILED_METADATA:this._render_body_failed_metadata(a);break;case HistoryDatasetAssociation.STATES.OK:this._render_body_ok(a);break;default:a.append($('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'))}a.append('<div style="clear: both"></div>');if(this.expanded){a.show()}else{a.hide()}return a},_render_body_not_viewable:function(a){a.append($("<div>"+_l("You do not have permission to view dataset")+".</div>"))},_render_body_uploading:function(a){a.append($("<div>"+_l("Dataset is uploading")+"</div>"))},_render_body_queued:function(a){a.append($("<div>"+_l("Job is waiting to run")+".</div>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_paused:function(a){a.append($("<div>"+_l("Job is paused. Use the history menu to unpause")+".</div>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_running:function(a){a.append("<div>"+_l("Job is currently running")+".</div>");a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_error:function(a){if(!this.model.get("purged")){a.append($("<div>"+this.model.get("misc_blurb")+"</div>"))}a.append((_l("An error occurred running this job")+": <i>"+$.trim(this.model.get("misc_info"))+"</i>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers.concat([this._render_downloadButton])))},_render_body_discarded:function(a){a.append("<div>"+_l("The job creating this dataset was cancelled before completion")+".</div>");a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_setting_metadata:function(a){a.append($("<div>"+_l("Metadata is being auto-detected")+".</div>"))},_render_body_empty:function(a){a.append($("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_failed_metadata:function(a){a.append($(HDABaseView.templates.failedMetadata(this.model.toJSON())));this._render_body_ok(a)},_render_body_ok:function(a){a.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));return}a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));a.append('<div class="clear"/>');a.append(this._render_displayApps());a.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility"},toggleBodyVisibility:function(c,a){var b=this,d=this.$el.find(".historyItemBody");a=(a===undefined)?(!d.is(":visible")):(a);if(a){d.slideDown("fast",function(){b.trigger("body-expanded",b.model.get("id"))})}else{d.slideUp("fast",function(){b.trigger("body-collapsed",b.model.get("id"))})}},remove:function(){},toString:function(){var a=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+a+")"}});HDABaseView.templates={warningMsg:Handlebars.templates["template-warningmessagesmall"],messages:Handlebars.templates["template-hda-warning-messages"],titleLink:Handlebars.templates["template-hda-titleLink"],hdaSummary:Handlebars.templates["template-hda-hdaSummary"],downloadLinks:Handlebars.templates["template-hda-downloadLinks"],failedMetadata:Handlebars.templates["template-hda-failedMetadata"],displayApps:Handlebars.templates["template-hda-displayApps"]}; \ No newline at end of file +var HDABaseView=BaseView.extend(LoggableMixin).extend({tagName:"div",className:"historyItemContainer",initialize:function(a){if(a.logger){this.logger=this.model.logger=a.logger}this.log(this+".initialize:",a);this.defaultPrimaryActionButtonRenderers=[this._render_showParamsButton];if(!a.urlTemplates){throw ("HDAView needs urlTemplates on initialize")}this.urlTemplates=a.urlTemplates;this.expanded=a.expanded||false;this.model.bind("change",this.render,this)},render:function(){var b=this,e=this.model.get("id"),c=this.model.get("state"),a=$("<div/>").attr("id","historyItem-"+e),d=(this.$el.children().size()===0);this.$el.attr("id","historyItemContainer-"+e);this.urls=this._renderUrls(this.urlTemplates,this.model.toJSON());a.addClass("historyItemWrapper").addClass("historyItem").addClass("historyItem-"+c);a.append(this._render_warnings());a.append(this._render_titleBar());this.body=$(this._render_body());a.append(this.body);make_popup_menus(a);a.find(".tooltip").tooltip({placement:"bottom"});this.$el.fadeOut("fast",function(){b.$el.children().remove();b.$el.append(a).fadeIn("fast",function(){b.log(b+" rendered:",b.$el);var f="rendered";if(d){f+=":initial"}else{if(b.model.inReadyState()){f+=":ready"}}b.trigger(f)})});return this},_renderUrls:function(d,a){var b=this,c={};_.each(d,function(e,f){if(_.isObject(e)){c[f]=b._renderUrls(e,a)}else{if(f==="meta_download"){c[f]=b._renderMetaDownloadUrls(e,a)}else{try{c[f]=_.template(e,a)}catch(g){throw (b+"._renderUrls error: "+g+"\n rendering:"+e+"\n with "+JSON.stringify(a))}}}});return c},_renderMetaDownloadUrls:function(b,a){return _.map(a.meta_files,function(c){return{url:_.template(b,{id:a.id,file_type:c.file_type}),file_type:c.file_type}})},_render_warnings:function(){return $(jQuery.trim(HDABaseView.templates.messages(this.model.toJSON())))},_render_titleBar:function(){var a=$('<div class="historyItemTitleBar" style="overflow: hidden"></div>');a.append(this._render_titleButtons());a.append('<span class="state-icon"></span>');a.append(this._render_titleLink());return a},_render_titleButtons:function(){var a=$('<div class="historyItemButtons"></div>');a.append(this._render_displayButton());return a},_render_displayButton:function(){if((!this.model.inReadyState())||(this.model.get("state")===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(!this.model.get("accessible"))){this.displayButton=null;return null}var a={icon_class:"display",target:"galaxy_main"};if(this.model.get("purged")){a.enabled=false;a.title=_l("Cannot display datasets removed from disk")}else{a.title=_l("Display data in browser");a.href=this.urls.display}this.displayButton=new IconButtonView({model:new IconButton(a)});return this.displayButton.render().$el},_render_titleLink:function(){return $(jQuery.trim(HDABaseView.templates.titleLink(_.extend(this.model.toJSON(),{urls:this.urls}))))},_render_hdaSummary:function(){var a=_.extend(this.model.toJSON(),{urls:this.urls});return HDABaseView.templates.hdaSummary(a)},_render_primaryActionButtons:function(c){var a=this,b=$("<div/>").attr("id","primary-actions-"+this.model.get("id"));_.each(c,function(d){b.append(d.call(a))});return b},_render_downloadButton:function(){if(this.model.get("purged")||!this.model.hasData()){return null}var a=HDABaseView.templates.downloadLinks(_.extend(this.model.toJSON(),{urls:this.urls}));return $(a)},_render_showParamsButton:function(){this.showParamsButton=new IconButtonView({model:new IconButton({title:_l("View details"),href:this.urls.show_params,target:"galaxy_main",icon_class:"information"})});return this.showParamsButton.render().$el},_render_displayApps:function(){if(!this.model.hasData()){return null}var a=$("<div/>").addClass("display-apps");if(!_.isEmpty(this.model.get("display_types"))){a.append(HDABaseView.templates.displayApps({displayApps:this.model.get("display_types")}))}if(!_.isEmpty(this.model.get("display_apps"))){a.append(HDABaseView.templates.displayApps({displayApps:this.model.get("display_apps")}))}return a},_render_peek:function(){if(!this.model.get("peek")){return null}return $("<div/>").append($("<pre/>").attr("id","peek"+this.model.get("id")).addClass("peek").append(this.model.get("peek")))},_render_body:function(){var a=$("<div/>").attr("id","info-"+this.model.get("id")).addClass("historyItemBody").attr("style","display: block");switch(this.model.get("state")){case HistoryDatasetAssociation.STATES.NEW:break;case HistoryDatasetAssociation.STATES.NOT_VIEWABLE:this._render_body_not_viewable(a);break;case HistoryDatasetAssociation.STATES.UPLOAD:this._render_body_uploading(a);break;case HistoryDatasetAssociation.STATES.PAUSED:this._render_body_paused(a);break;case HistoryDatasetAssociation.STATES.QUEUED:this._render_body_queued(a);break;case HistoryDatasetAssociation.STATES.RUNNING:this._render_body_running(a);break;case HistoryDatasetAssociation.STATES.ERROR:this._render_body_error(a);break;case HistoryDatasetAssociation.STATES.DISCARDED:this._render_body_discarded(a);break;case HistoryDatasetAssociation.STATES.SETTING_METADATA:this._render_body_setting_metadata(a);break;case HistoryDatasetAssociation.STATES.EMPTY:this._render_body_empty(a);break;case HistoryDatasetAssociation.STATES.FAILED_METADATA:this._render_body_failed_metadata(a);break;case HistoryDatasetAssociation.STATES.OK:this._render_body_ok(a);break;default:a.append($('<div>Error: unknown dataset state "'+this.model.get("state")+'".</div>'))}a.append('<div style="clear: both"></div>');if(this.expanded){a.show()}else{a.hide()}return a},_render_body_not_viewable:function(a){a.append($("<div>"+_l("You do not have permission to view dataset")+".</div>"))},_render_body_uploading:function(a){a.append($("<div>"+_l("Dataset is uploading")+"</div>"))},_render_body_queued:function(a){a.append($("<div>"+_l("Job is waiting to run")+".</div>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_paused:function(a){a.append($("<div>"+_l("Job is paused. Use the history menu to unpause")+".</div>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_running:function(a){a.append("<div>"+_l("Job is currently running")+".</div>");a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_error:function(a){if(!this.model.get("purged")){a.append($("<div>"+this.model.get("misc_blurb")+"</div>"))}a.append((_l("An error occurred running this job")+": <i>"+$.trim(this.model.get("misc_info"))+"</i>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers.concat([this._render_downloadButton])))},_render_body_discarded:function(a){a.append("<div>"+_l("The job creating this dataset was cancelled before completion")+".</div>");a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_setting_metadata:function(a){a.append($("<div>"+_l("Metadata is being auto-detected")+".</div>"))},_render_body_empty:function(a){a.append($("<div>"+_l("No data")+": <i>"+this.model.get("misc_blurb")+"</i></div>"));a.append(this._render_primaryActionButtons(this.defaultPrimaryActionButtonRenderers))},_render_body_failed_metadata:function(a){a.append($(HDABaseView.templates.failedMetadata(this.model.toJSON())));this._render_body_ok(a)},_render_body_ok:function(a){a.append(this._render_hdaSummary());if(this.model.isDeletedOrPurged()){a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));return}a.append(this._render_primaryActionButtons([this._render_downloadButton,this._render_showParamsButton]));a.append('<div class="clear"/>');a.append(this._render_displayApps());a.append(this._render_peek())},events:{"click .historyItemTitle":"toggleBodyVisibility"},toggleBodyVisibility:function(c,a){var b=this,d=this.$el.find(".historyItemBody");a=(a===undefined)?(!d.is(":visible")):(a);if(a){d.slideDown("fast",function(){b.trigger("body-expanded",b.model.get("id"))})}else{d.slideUp("fast",function(){b.trigger("body-collapsed",b.model.get("id"))})}},remove:function(){},toString:function(){var a=(this.model)?(this.model+""):("(no model)");return"HDABaseView("+a+")"}});HDABaseView.templates={warningMsg:Handlebars.templates["template-warningmessagesmall"],messages:Handlebars.templates["template-hda-warning-messages"],titleLink:Handlebars.templates["template-hda-titleLink"],hdaSummary:Handlebars.templates["template-hda-hdaSummary"],downloadLinks:Handlebars.templates["template-hda-downloadLinks"],failedMetadata:Handlebars.templates["template-hda-failedMetadata"],displayApps:Handlebars.templates["template-hda-displayApps"]}; \ No newline at end of file diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/packed/mvc/dataset/hda-model.js --- a/static/scripts/packed/mvc/dataset/hda-model.js +++ b/static/scripts/packed/mvc/dataset/hda-model.js @@ -1,1 +1,1 @@ -var HistoryDatasetAssociation=BaseModel.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"ok",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:false,accessible:true},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("history_id")+"/contents/"+this.get("id")},initialize:function(){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",HistoryDatasetAssociation.STATES.NOT_VIEWABLE)}this.on("change:state",function(b,a){this.log(this+" has changed state:",b,a);if(this.inReadyState()){this.trigger("state:ready",this.get("id"),a,this.previous("state"),b)}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(b,c){var a=true;if((!b)&&(this.get("deleted")||this.get("purged"))){a=false}if((!c)&&(!this.get("visible"))){a=false}return a},inReadyState:function(){var a=this.get("state");return((a===HistoryDatasetAssociation.STATES.NEW)||(a===HistoryDatasetAssociation.STATES.OK)||(a===HistoryDatasetAssociation.STATES.EMPTY)||(a===HistoryDatasetAssociation.STATES.FAILED_METADATA)||(a===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(a===HistoryDatasetAssociation.STATES.DISCARDED)||(a===HistoryDatasetAssociation.STATES.ERROR))},hasData:function(){return(this.get("file_size")>0)},toString:function(){var a=this.get("id")||"";if(this.get("name")){a+=':"'+this.get("name")+'"'}return"HistoryDatasetAssociation("+a+")"}});HistoryDatasetAssociation.STATES={UPLOAD:"upload",QUEUED:"queued",PAUSED:"paused",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};var HDACollection=Backbone.Collection.extend(LoggableMixin).extend({model:HistoryDatasetAssociation,initialize:function(){},ids:function(){return this.map(function(a){return a.id})},hidToCollectionIndex:function(a){if(!a){return this.models.length}var d=this.models.length-1;for(var b=d;b>=0;b--){var c=this.at(b).get("hid");if(c==a){return b}if(c<a){return b+1}}return null},getVisible:function(a,b){return this.filter(function(c){return c.isVisible(a,b)})},getStateLists:function(){var a={};_.each(_.values(HistoryDatasetAssociation.STATES),function(b){a[b]=[]});this.each(function(b){a[b.get("state")].push(b.get("id"))});return a},running:function(){var a=[];this.each(function(b){if(!b.inReadyState()){a.push(b.get("id"))}});return a},update:function(a){this.log(this+"update:",a);if(!(a&&a.length)){return[]}var c=this,b=null;_.each(a,function(f,d){var e=c.get(f);if(e){e.fetch();b.push(e)}});return b},toString:function(){return("HDACollection()")}}); \ No newline at end of file +var HistoryDatasetAssociation=BaseModel.extend(LoggableMixin).extend({defaults:{history_id:null,model_class:"HistoryDatasetAssociation",hid:0,id:null,name:"(unnamed dataset)",state:"ok",data_type:null,file_size:0,file_ext:"",meta_files:[],misc_blurb:"",misc_info:"",deleted:false,purged:false,visible:false,accessible:true},urlRoot:"api/histories/",url:function(){return"api/histories/"+this.get("history_id")+"/contents/"+this.get("id")},initialize:function(){this.log(this+".initialize",this.attributes);this.log("\tparent history_id: "+this.get("history_id"));if(!this.get("accessible")){this.set("state",HistoryDatasetAssociation.STATES.NOT_VIEWABLE)}this.on("change:state",function(b,a){this.log(this+" has changed state:",b,a);if(this.inReadyState()){this.trigger("state:ready",this.get("id"),a,this.previous("state"),b)}})},isDeletedOrPurged:function(){return(this.get("deleted")||this.get("purged"))},isVisible:function(b,c){var a=true;if((!b)&&(this.get("deleted")||this.get("purged"))){a=false}if((!c)&&(!this.get("visible"))){a=false}return a},inReadyState:function(){var a=this.get("state");return((a===HistoryDatasetAssociation.STATES.OK)||(a===HistoryDatasetAssociation.STATES.EMPTY)||(a===HistoryDatasetAssociation.STATES.FAILED_METADATA)||(a===HistoryDatasetAssociation.STATES.NOT_VIEWABLE)||(a===HistoryDatasetAssociation.STATES.DISCARDED)||(a===HistoryDatasetAssociation.STATES.ERROR))},hasData:function(){return(this.get("file_size")>0)},toString:function(){var a=this.get("id")||"";if(this.get("name")){a+=':"'+this.get("name")+'"'}return"HistoryDatasetAssociation("+a+")"}});HistoryDatasetAssociation.STATES={UPLOAD:"upload",QUEUED:"queued",PAUSED:"paused",RUNNING:"running",SETTING_METADATA:"setting_metadata",NEW:"new",EMPTY:"empty",OK:"ok",FAILED_METADATA:"failed_metadata",NOT_VIEWABLE:"noPermission",DISCARDED:"discarded",ERROR:"error"};var HDACollection=Backbone.Collection.extend(LoggableMixin).extend({model:HistoryDatasetAssociation,initialize:function(){},ids:function(){return this.map(function(a){return a.id})},hidToCollectionIndex:function(a){if(!a){return this.models.length}var d=this.models.length-1;for(var b=d;b>=0;b--){var c=this.at(b).get("hid");if(c==a){return b}if(c<a){return b+1}}return null},getVisible:function(a,b){return this.filter(function(c){return c.isVisible(a,b)})},getStateLists:function(){var a={};_.each(_.values(HistoryDatasetAssociation.STATES),function(b){a[b]=[]});this.each(function(b){a[b.get("state")].push(b.get("id"))});return a},running:function(){var a=[];this.each(function(b){if(!b.inReadyState()){a.push(b.get("id"))}});return a},update:function(a){this.log(this+"update:",a);if(!(a&&a.length)){return[]}var c=this,b=null;_.each(a,function(f,d){var e=c.get(f);if(e){e.fetch();b.push(e)}});return b},toString:function(){return("HDACollection()")}}); \ No newline at end of file diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 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 @@ -var HistoryPanel=BaseView.extend(LoggableMixin).extend({el:"body.historyPage",HDAView:HDAEditView,events:{"click #history-tag":"loadAndDisplayTags"},initialize:function(a){this.log(this+".initialize:",a);if(!a.urlTemplates){throw (this+" needs urlTemplates on initialize")}if(!a.urlTemplates.history){throw (this+" needs urlTemplates.history on initialize")}if(!a.urlTemplates.hda){throw (this+" needs urlTemplates.hda on initialize")}this.urlTemplates=a.urlTemplates.history;this.hdaUrlTemplates=a.urlTemplates.hda;this._setUpWebStorage(a.initiallyExpanded,a.show_deleted,a.show_hidden);this.model.bind("change:nice_size",this.updateHistoryDiskSize,this);this.model.hdas.bind("add",this.add,this);this.model.hdas.bind("reset",this.addAll,this);this.model.hdas.bind("change:state",function(c,d,b){if((c.inReadyState())&&(!c.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHda(c)}},this);this.hdaViews={};this.urls={}},_setUpWebStorage:function(b,a,c){this.storage=new PersistantStorage("HistoryView."+this.model.get("id"),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log("this.storage:",this.storage.get());if(b){this.storage.set("exandedHdas",b)}if((a===true)||(a===false)){this.storage.set("show_deleted",a)}if((c===true)||(c===false)){this.storage.set("show_hidden",c)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.log("(init'd) this.storage:",this.storage.get())},add:function(a){this.render()},addAll:function(){this.render()},removeHda:function(a,c){var b=this.hdaViews[a.get("id")];b.$el.fadeOut("fast",function(){b.$el.remove();if(c){c()}});this.model.hdas.remove(a)},render:function(){var b=this,d=b.toString()+".set-up",c=$("<div/>"),a=this.model.toJSON(),e=(this.$el.children().size()===0);a.urls=this._renderUrls(a);c.append(HistoryPanel.templates.historyPanel(a));c.find(".tooltip").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(c.find("#"+this.model.get("id")+"-datasets"))){c.find("#emptyHistoryMessage").show()}$(b).queue(d,function(f){b.$el.fadeOut("fast",function(){f()})});$(b).queue(d,function(f){b.$el.html("");b.$el.append(c.children());b.$el.fadeIn("fast",function(){f()})});$(b).queue(d,function(f){this.log(b+" rendered:",b.$el);b._setUpBehaviours();if(e){b.trigger("rendered:initial")}else{b.trigger("rendered")}f()});$(b).dequeue(d);return this},_renderUrls:function(a){var b=this;b.urls={};_.each(this.urlTemplates,function(d,c){b.urls[c]=_.template(d,a)});return b.urls},renderItems:function(b){this.hdaViews={};var a=this,c=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(c,function(f){var e=f.get("id"),d=a.storage.get("expandedHdas").get(e);a.hdaViews[e]=new a.HDAView({model:f,expanded:d,urlTemplates:a.hdaUrlTemplates});a._setUpHdaListeners(a.hdaViews[e]);b.prepend(a.hdaViews[e].render().$el)});return c.length},_setUpHdaListeners:function(b){var a=this;b.bind("body-expanded",function(c){a.storage.get("expandedHdas").set(c,true)});b.bind("body-collapsed",function(c){a.storage.get("expandedHdas").deleteKey(c)})},_setUpBehaviours:function(){if(!(this.model.get("user")&&this.model.get("user").email)){return}var a=this.$("#history-annotation-area");this.$("#history-annotate").click(function(){if(a.is(":hidden")){a.slideDown("fast")}else{a.slideUp("fast")}return false});async_save_text("history-name-container","history-name",this.urls.rename,"new_name",18);async_save_text("history-annotation-container","history-annotation",this.urls.annotate,"new_annotation",18,true,4)},updateHistoryDiskSize:function(){this.$el.find("#history-size").text(this.model.get("nice_size"))},showQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(a.is(":hidden")){a.slideDown("fast")}},hideQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(!a.is(":hidden")){a.slideUp("fast")}},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.render()},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.render()},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(a){a.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},loadAndDisplayTags:function(c){this.log(this+".loadAndDisplayTags",c);var d=this.$el.find("#history-tag-area"),b=d.find(".tag-elt");this.log("\t tagArea",d," tagElt",b);if(d.is(":hidden")){if(!jQuery.trim(b.html())){var a=this;$.ajax({url:a.urls.tag,error:function(){alert(_l("Tagging failed"))},success:function(e){b.html(e);b.find(".tooltip").tooltip();d.slideDown("fast")}})}else{d.slideDown("fast")}}else{d.slideUp("fast")}return false},toString:function(){var a=this.model.get("name")||"";return"HistoryPanel("+a+")"}});HistoryPanel.templates={historyPanel:Handlebars.templates["template-history-historyPanel"]}; \ No newline at end of file +var HistoryPanel=BaseView.extend(LoggableMixin).extend({el:"body.historyPage",HDAView:HDAEditView,events:{"click #history-tag":"loadAndDisplayTags"},initialize:function(a){if(a.logger){this.logger=this.model.logger=a.logger}this.log(this+".initialize:",a);if(!a.urlTemplates){throw (this+" needs urlTemplates on initialize")}if(!a.urlTemplates.history){throw (this+" needs urlTemplates.history on initialize")}if(!a.urlTemplates.hda){throw (this+" needs urlTemplates.hda on initialize")}this.urlTemplates=a.urlTemplates.history;this.hdaUrlTemplates=a.urlTemplates.hda;this._setUpWebStorage(a.initiallyExpanded,a.show_deleted,a.show_hidden);this.model.bind("change:nice_size",this.updateHistoryDiskSize,this);this.model.hdas.bind("add",this.add,this);this.model.hdas.bind("reset",this.addAll,this);this.model.hdas.bind("change:state",function(c,d,b){if((c.inReadyState())&&(!c.get("visible"))&&(!this.storage.get("show_hidden"))){this.removeHda(c)}},this);this.hdaViews={};this.urls={}},_setUpWebStorage:function(b,a,c){this.storage=new PersistantStorage("HistoryView."+this.model.get("id"),{expandedHdas:{},show_deleted:false,show_hidden:false});this.log(this+" (prev) storage:",JSON.stringify(this.storage.get(),null,2));if(b){this.storage.set("exandedHdas",b)}if((a===true)||(a===false)){this.storage.set("show_deleted",a)}if((c===true)||(c===false)){this.storage.set("show_hidden",c)}this.show_deleted=this.storage.get("show_deleted");this.show_hidden=this.storage.get("show_hidden");this.log(this+" (init'd) storage:",this.storage.get())},add:function(a){this.render()},addAll:function(){this.render()},removeHda:function(a,c){var b=this.hdaViews[a.get("id")];b.$el.fadeOut("fast",function(){b.$el.remove();if(c){c()}});this.model.hdas.remove(a)},render:function(){var b=this,d=b.toString()+".set-up",c=$("<div/>"),a=this.model.toJSON(),e=(this.$el.children().size()===0);a.urls=this._renderUrls(a);c.append(HistoryPanel.templates.historyPanel(a));c.find(".tooltip").tooltip({placement:"bottom"});if(!this.model.hdas.length||!this.renderItems(c.find("#"+this.model.get("id")+"-datasets"))){c.find("#emptyHistoryMessage").show()}$(b).queue(d,function(f){b.$el.fadeOut("fast",function(){f()})});$(b).queue(d,function(f){b.$el.html("");b.$el.append(c.children());b.$el.fadeIn("fast",function(){f()})});$(b).queue(d,function(f){this.log(b+" rendered:",b.$el);b._setUpBehaviours();if(e){b.trigger("rendered:initial")}else{b.trigger("rendered")}f()});$(b).dequeue(d);return this},_renderUrls:function(a){var b=this;b.urls={};_.each(this.urlTemplates,function(d,c){b.urls[c]=_.template(d,a)});return b.urls},renderItems:function(b){this.hdaViews={};var a=this,c=this.model.hdas.getVisible(this.storage.get("show_deleted"),this.storage.get("show_hidden"));_.each(c,function(f){var e=f.get("id"),d=a.storage.get("expandedHdas").get(e);a.hdaViews[e]=new a.HDAView({model:f,expanded:d,urlTemplates:a.hdaUrlTemplates,logger:a.logger});a._setUpHdaListeners(a.hdaViews[e]);b.prepend(a.hdaViews[e].render().$el)});return c.length},_setUpHdaListeners:function(b){var a=this;b.bind("body-expanded",function(c){a.storage.get("expandedHdas").set(c,true)});b.bind("body-collapsed",function(c){a.storage.get("expandedHdas").deleteKey(c)})},_setUpBehaviours:function(){if(!(this.model.get("user")&&this.model.get("user").email)){return}var a=this.$("#history-annotation-area");this.$("#history-annotate").click(function(){if(a.is(":hidden")){a.slideDown("fast")}else{a.slideUp("fast")}return false});async_save_text("history-name-container","history-name",this.urls.rename,"new_name",18);async_save_text("history-annotation-container","history-annotation",this.urls.annotate,"new_annotation",18,true,4)},updateHistoryDiskSize:function(){this.$el.find("#history-size").text(this.model.get("nice_size"))},showQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(a.is(":hidden")){a.slideDown("fast")}},hideQuotaMessage:function(){var a=this.$el.find("#quota-message-container");if(!a.is(":hidden")){a.slideUp("fast")}},toggleShowDeleted:function(){this.storage.set("show_deleted",!this.storage.get("show_deleted"));this.render();return this.storage.get("show_deleted")},toggleShowHidden:function(){this.storage.set("show_hidden",!this.storage.get("show_hidden"));this.render();return this.storage.get("show_hidden")},collapseAllHdaBodies:function(){_.each(this.hdaViews,function(a){a.toggleBodyVisibility(null,false)});this.storage.set("expandedHdas",{})},loadAndDisplayTags:function(c){this.log(this+".loadAndDisplayTags",c);var d=this.$el.find("#history-tag-area"),b=d.find(".tag-elt");this.log("\t tagArea",d," tagElt",b);if(d.is(":hidden")){if(!jQuery.trim(b.html())){var a=this;$.ajax({url:a.urls.tag,error:function(){alert(_l("Tagging failed"))},success:function(e){b.html(e);b.find(".tooltip").tooltip();d.slideDown("fast")}})}else{d.slideDown("fast")}}else{d.slideUp("fast")}return false},toString:function(){var a=this.model.get("name")||"";return"HistoryPanel("+a+")"}});HistoryPanel.templates={historyPanel:Handlebars.templates["template-history-historyPanel"]}; \ No newline at end of file diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 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,tooltip_config:{},isMenuButton:true,id:null,href:null,target:null,enabled:true,visible:true}});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=$(Handlebars.partials.iconButton(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(this.model.attributes.on_click){this.model.attributes.on_click(a);return false}return true}});IconButtonView.templates={iconButton:Handlebars.partials.iconButton};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 GalaxyPaths=Backbone.Model.extend({defaults:{root_path:"",image_path:""}}); \ No newline at end of file +var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,tooltip_config:{},isMenuButton:true,id:null,href:null,target:null,enabled:true,visible:true}});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=$(Handlebars.partials.iconButton(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(this.model.attributes.on_click){this.model.attributes.on_click(a);return false}return true}});IconButtonView.templates={iconButton:Handlebars.partials.iconButton};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 GalaxyPaths=Backbone.Model.extend({defaults:{root_path:"",image_path:""}});var PopupMenu=Backbone.View.extend({templates:{wrapper:(function(){var a=['<ul id="<%= id %>-menu" class="dropdown-menu">',"<% if( options.length ){ %>","<% for( var i=0; i<options.length; i++ ){ var option = options[ i ]; %>","<% if( option.divider ){ %>",'<li class="divider"></li>',"<% } else { %>","<% if( option.header ){ %>",'<li class="head"><a href=""javascript:void(0);"><%- option.html %></a></li>',"<% } else { %>","<li><a ",'href="<% print( ( option.href )?( option.href ):( "javascript:void(0);" ) ) %>" ','<% if( option.target ){ %>target="<%= option.target %>" <% } %>','class="popupmenu-option">','<% if( option.checked ){ %><span class="ficon ok"></span><% } %>',"<%- option.html %>","</a></li>","<% } %>","<% } %>","<% } %>","<% } else { %>","<li>No Options.</li>","<% } %>","</ul>"];return _.template(a.join(""))}())},initialize:function(b,a){this.$button=b||$("<div/>");this.options=a||[];var c=this;this.$button.click(function(d){c._renderAndShow(d);return false});this.$button.data("PopupMenu",this);if(!this.templates.wrapper){this.templates.wrapper=Handlebars.templates["template-popupmenu-wrapper"]}},render:function(){var a=this;this.$el.addClass("popmenu-wrapper").css({position:"absolute",display:"none"});this.$el.html(PopupMenu.templates.menu({options:this.options,id:this.$button.attr("id")}));if(this.options.length){this.$el.find("li").each(function(c,b){var f=$(b),e=f.children("a.popupmenu-option"),d=a.options[c].func;if(e.length&&d){e.click(function(g){d(g,a.options[c])})}a.options[c].$li=f})}return this},_getShownPosition:function(b){var c=this.$el.width(),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}},_renderAndShow:function(a){this.render();this.$el.appendTo("body");this.$el.css(this._getShownPosition(a));this._setUpCloseBehavior();this.$el.show()},_setUpCloseBehavior:function(){var b=this,a=function(c){c.bind("click.close_popup",function(){b.remove();c.unbind("click.close_popup")})};a($(window.document));a($(window.top.document));_.each(window.top.frames,function(c){a($(c.document))})},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.templates={menu:Handlebars.templates["template-popupmenu-menu"]};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(j){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}var i;switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;case"demo":if(i===undefined||i.closed){i=window.open(j,k);i.creator=self}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 diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/packed/templates/compiled/template-popupmenu-menu.js --- /dev/null +++ b/static/scripts/packed/templates/compiled/template-popupmenu-menu.js @@ -0,0 +1,1 @@ +(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a["template-popupmenu-menu"]=b(function(f,s,q,l,x){q=q||f.helpers;var r="",i,h,d="function",c=this.escapeExpression,p=this;function o(B,A){var y="",z;y+="\n ";z=B.options;z=q.each.call(B,z,{hash:{},inverse:p.noop,fn:p.program(2,n,A)});if(z||z===0){y+=z}y+="\n";return y}function n(B,A){var y="",z;y+="\n ";z=B.divider;z=q["if"].call(B,z,{hash:{},inverse:p.program(5,k,A),fn:p.program(3,m,A)});if(z||z===0){y+=z}y+="\n ";return y}function m(z,y){return'\n <li class="divider"></li>\n '}function k(B,A){var y="",z;y+="\n ";z=B.header;z=q["if"].call(B,z,{hash:{},inverse:p.program(8,g,A),fn:p.program(6,j,A)});if(z||z===0){y+=z}y+="\n ";return y}function j(C,B){var z="",A,y;z+='\n <li class="head"><a href=""javascript:void(0);">';y=q.html;if(y){A=y.call(C,{hash:{}})}else{A=C.html;A=typeof A===d?A():A}if(A||A===0){z+=A}z+="</a></li>\n ";return z}function g(C,B){var z="",A,y;z+="\n ";z+='\n <li><a href="';A=C.href;A=q["if"].call(C,A,{hash:{},inverse:p.program(11,w,B),fn:p.program(9,e,B)});if(A||A===0){z+=A}z+='"\n ';A=C.href;A=q["if"].call(C,A,{hash:{},inverse:p.noop,fn:p.program(13,v,B)});if(A||A===0){z+=A}z+=' class="popupmenu-option">\n ';A=C.checked;A=q["if"].call(C,A,{hash:{},inverse:p.noop,fn:p.program(15,u,B)});if(A||A===0){z+=A}z+="\n ";y=q.html;if(y){A=y.call(C,{hash:{}})}else{A=C.html;A=typeof A===d?A():A}if(A||A===0){z+=A}z+="\n </a></li>\n ";return z}function e(B,A){var z,y;y=q.href;if(y){z=y.call(B,{hash:{}})}else{z=B.href;z=typeof z===d?z():z}return c(z)}function w(z,y){return"javascript:void(0);"}function v(C,B){var z="",A,y;z+='target="';y=q.target;if(y){A=y.call(C,{hash:{}})}else{A=C.target;A=typeof A===d?A():A}z+=c(A)+'"';return z}function u(z,y){return'<span class="ficon ok"></span>'}function t(z,y){return"\n <li>No Options.</li>\n"}r+='<ul id="';h=q.id;if(h){i=h.call(s,{hash:{}})}else{i=s.id;i=typeof i===d?i():i}r+=c(i)+'-menu" class="dropdown-menu">\n';i=s.options;i=i==null||i===false?i:i.length;i=q["if"].call(s,i,{hash:{},inverse:p.program(17,t,x),fn:p.program(1,o,x)});if(i||i===0){r+=i}r+="\n</ul>";return r})})(); \ No newline at end of file diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/templates/compiled/template-popupmenu-menu.js --- /dev/null +++ b/static/scripts/templates/compiled/template-popupmenu-menu.js @@ -0,0 +1,117 @@ +(function() { + var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; +templates['template-popupmenu-menu'] = template(function (Handlebars,depth0,helpers,partials,data) { + helpers = helpers || Handlebars.helpers; + var buffer = "", stack1, foundHelper, functionType="function", escapeExpression=this.escapeExpression, self=this; + +function program1(depth0,data) { + + var buffer = "", stack1; + buffer += "\n "; + stack1 = depth0.options; + stack1 = helpers.each.call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(2, program2, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\n"; + return buffer;} +function program2(depth0,data) { + + var buffer = "", stack1; + buffer += "\n "; + stack1 = depth0.divider; + stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\n "; + return buffer;} +function program3(depth0,data) { + + + return "\n <li class=\"divider\"></li>\n ";} + +function program5(depth0,data) { + + var buffer = "", stack1; + buffer += "\n "; + stack1 = depth0.header; + stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(8, program8, data),fn:self.program(6, program6, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\n "; + return buffer;} +function program6(depth0,data) { + + var buffer = "", stack1, foundHelper; + buffer += "\n <li class=\"head\"><a href=\"\"javascript:void(0);\">"; + foundHelper = helpers.html; + if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); } + else { stack1 = depth0.html; stack1 = typeof stack1 === functionType ? stack1() : stack1; } + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "</a></li>\n "; + return buffer;} + +function program8(depth0,data) { + + var buffer = "", stack1, foundHelper; + buffer += "\n "; + buffer += "\n <li><a href=\""; + stack1 = depth0.href; + stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(11, program11, data),fn:self.program(9, program9, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\"\n "; + stack1 = depth0.href; + stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(13, program13, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += " class=\"popupmenu-option\">\n "; + stack1 = depth0.checked; + stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.noop,fn:self.program(15, program15, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\n "; + foundHelper = helpers.html; + if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); } + else { stack1 = depth0.html; stack1 = typeof stack1 === functionType ? stack1() : stack1; } + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\n </a></li>\n "; + return buffer;} +function program9(depth0,data) { + + var stack1, foundHelper; + foundHelper = helpers.href; + if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); } + else { stack1 = depth0.href; stack1 = typeof stack1 === functionType ? stack1() : stack1; } + return escapeExpression(stack1);} + +function program11(depth0,data) { + + + return "javascript:void(0);";} + +function program13(depth0,data) { + + var buffer = "", stack1, foundHelper; + buffer += "target=\""; + foundHelper = helpers.target; + if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); } + else { stack1 = depth0.target; stack1 = typeof stack1 === functionType ? stack1() : stack1; } + buffer += escapeExpression(stack1) + "\""; + return buffer;} + +function program15(depth0,data) { + + + return "<span class=\"ficon ok\"></span>";} + +function program17(depth0,data) { + + + return "\n <li>No Options.</li>\n";} + + buffer += "<ul id=\""; + foundHelper = helpers.id; + if (foundHelper) { stack1 = foundHelper.call(depth0, {hash:{}}); } + else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1() : stack1; } + buffer += escapeExpression(stack1) + "-menu\" class=\"dropdown-menu\">\n"; + stack1 = depth0.options; + stack1 = stack1 == null || stack1 === false ? stack1 : stack1.length; + stack1 = helpers['if'].call(depth0, stack1, {hash:{},inverse:self.program(17, program17, data),fn:self.program(1, program1, data)}); + if(stack1 || stack1 === 0) { buffer += stack1; } + buffer += "\n</ul>"; + return buffer;}); +})(); \ No newline at end of file diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 static/scripts/templates/ui-templates.html --- a/static/scripts/templates/ui-templates.html +++ b/static/scripts/templates/ui-templates.html @@ -1,4 +1,4 @@ -<script type="text/template" class="template-history" id="template-user-quotaMeter-quota"> +<script type="text/template" class="template-user" id="template-user-quotaMeter-quota"><div id="quota-meter" class="quota-meter progress"><div id="quota-meter-bar" class="quota-meter-bar bar" style="width: {{quota_percent}}%"></div> {{! TODO: remove the hardcoded style }} @@ -8,7 +8,7 @@ </div></script> -<script type="text/template" class="template-history" id="template-user-quotaMeter-usage"> +<script type="text/template" class="template-user" id="template-user-quotaMeter-usage"> {{! TODO: remove the hardcoded styles }} <div id="quota-meter" class="quota-meter" style="background-color: transparent"><div id="quota-meter-text" class="quota-meter-text" style="top: 6px; color: white"> @@ -16,3 +16,28 @@ </div></div></script> + +<script type="text/template" class="template-ui" id="template-popupmenu-menu"> +<ul id="{{ id }}-menu" class="dropdown-menu"> +{{#if options.length }} + {{#each options }} + {{#if divider }} + <li class="divider"></li> + {{else}} + {{#if header }} + <li class="head"><a href=""javascript:void(0);">{{{ html }}}</a></li> + {{else}} + {{!NOTE: changed from # to void fn }} + <li><a href="{{#if href }}{{ href }}{{else}}javascript:void(0);{{/if}}" + {{#if href }}target="{{ target }}"{{/if}} class="popupmenu-option"> + {{#if checked }}<span class="ficon ok"></span>{{/if}} + {{{ html }}} + </a></li> + {{/if}} + {{/if}} + {{/each}} +{{else}} + <li>No Options.</li> +{{/if}} +</ul> +</script> diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 templates/base.mako --- a/templates/base.mako +++ b/templates/base.mako @@ -31,11 +31,18 @@ "libs/jquery/jquery", "libs/json2", "libs/bootstrap", - "galaxy.base", "libs/underscore", "libs/backbone/backbone", "libs/backbone/backbone-relational", "libs/handlebars.runtime", + "galaxy.base" + )} + + ${h.templates( + "template-popupmenu-menu" + )} + + ${h.js( "mvc/ui" )} diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 templates/base/base_panels.mako --- a/templates/base/base_panels.mako +++ b/templates/base/base_panels.mako @@ -56,9 +56,17 @@ 'libs/backbone/backbone', 'libs/backbone/backbone-relational', 'libs/handlebars.runtime', - 'mvc/ui', 'galaxy.base' )} + + ${h.templates( + "template-popupmenu-menu" + )} + + ${h.js( + "mvc/ui" + )} + <script type="text/javascript"> // console protection window.console = window.console || { diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 templates/root/alternate_history.mako --- a/templates/root/alternate_history.mako +++ b/templates/root/alternate_history.mako @@ -223,10 +223,12 @@ ${h.js( "libs/jquery/jstorage", "libs/jquery/jquery.autocomplete", "galaxy.autocom_tagging", - "libs/json2", + ##"libs/json2", ##"libs/bootstrap", - "libs/backbone/backbone-relational", - "mvc/base-mvc", "mvc/ui" + ## I think we can remove some of these + ##"libs/backbone/backbone-relational", + "mvc/base-mvc", + ##"mvc/ui" )} ${h.templates( @@ -302,13 +304,9 @@ galaxyPageSetUp(); Galaxy.historyFrame = window; + var debugging = ( new PersistantStorage( '__history_panel' ).get( 'debugging' ) || false ); + // ostensibly, this is the App - //if( window.console && console.debug ){ - // //if( console.clear ){ console.clear(); } - // console.pretty = function( o ){ $( '<pre/>' ).text( JSON.stringify( o, null, ' ' ) ).appendTo( 'body' ); } - // top.storage = jQuery.jStorage - //} - // LOAD INITIAL DATA IN THIS PAGE - since we're already sending it... // ...use mako to 'bootstrap' the models var user = ${ get_current_user() }, @@ -325,7 +323,7 @@ var historyPanel = new HistoryPanel({ model : new History( history, hdas ), urlTemplates : galaxy_paths.attributes, - //logger : console, + logger : ( debugging )?( console ):( null ), // is page sending in show settings? if so override history's show_deleted : ${ 'true' if show_deleted == True else ( 'null' if show_deleted == None else 'false' ) }, show_hidden : ${ 'true' if show_hidden == True else ( 'null' if show_hidden == None else 'false' ) } @@ -336,13 +334,17 @@ //historyPanel = new HistoryPanel({ // model: new History(), // urlTemplates : galaxy_paths.attributes, - // logger : console, + // logger : ( debugging )?( console ):( null ), // // is page sending in show settings? if so override history's // show_deleted : ${ 'true' if show_deleted == True else ( 'null' if show_deleted == None else 'false' ) }, // show_hidden : ${ 'true' if show_hidden == True else ( 'null' if show_hidden == None else 'false' ) } //}); //historyPanel.model.loadFromApi( history.id ); + // set it up to be accessible across iframes + //TODO:?? mem leak + top.Galaxy.currHistoryPanel = historyPanel; + // QUOTA METER is a cross-frame ui element (meter in masthead, over quota message in history) // create it and join them here for now (via events) @@ -352,6 +354,7 @@ //window.currUser.logger = console; var quotaMeter = new UserQuotaMeter({ model : currUser, + //logger : ( debugging )?( console ):( null ), el : $( top.document ).find( '.quota-meter-container' ) }); //quotaMeter.logger = console; window.quotaMeter = quotaMeter @@ -373,9 +376,81 @@ quotaMeter.update() }, quotaMeter ); - // set it up to be accessible across iframes - //TODO:?? mem leak - top.Galaxy.currHistoryPanel = historyPanel; + + //ANOTHER cross-frame element is the history-options-button... + // in this case, we need to change the popupmenu options listed to include some functions for this history + // these include: current (1 & 2) 'show/hide' delete and hidden functions, and (3) the collapse all option + (function(){ + // don't try this if the history panel is in it's own window + if( top.document === window.document ){ + return; + } + + // lots of wtf here...due to infernalframes + var $historyButtonWindow = $( top.document ), + HISTORY_MENU_BUTTON_ID = 'history-options-button', + $historyMenuButton = $historyButtonWindow.find( '#' + HISTORY_MENU_BUTTON_ID ), + // jq data in another frame can only be accessed by the jQuery in that frame, + // get the jQuery from the top frame (that contains the history-options-button) + START_INSERTING_AT_INDEX = 11, + COLLAPSE_OPTION_TEXT = _l("Collapse Expanded Datasets"), + DELETED_OPTION_TEXT = _l("Include Deleted Datasets"), + HIDDEN_OPTION_TEXT = _l("Include Hidden Datasets"); + windowJQ = $( top )[0].jQuery, + popupMenu = ( windowJQ && $historyMenuButton[0] )?( windowJQ.data( $historyMenuButton[0], 'PopupMenu' ) ) + :( null ); + + //console.debug( + // '$historyButtonWindow:', $historyButtonWindow, + // '$historyMenuButton:', $historyMenuButton, + // 'windowJQ:', windowJQ, + // 'popupmenu:', popupMenu + //); + if( !popupMenu ){ return; } + + // since the history frame reloads so often (compared to the main window), + // we need to check whether these options are there already before we add them again + //NOTE: we use the global here because these remain bound in the main window even if panel refreshes + //TODO: too much boilerplate + if( popupMenu.findIndexByHtml( COLLAPSE_OPTION_TEXT ) === null ){ + popupMenu.addItem({ + html : COLLAPSE_OPTION_TEXT, + func : function() { + Galaxy.currHistoryPanel.collapseAllHdaBodies(); + } + }, START_INSERTING_AT_INDEX ) + } + + var deletedOptionIndex = popupMenu.findIndexByHtml( DELETED_OPTION_TEXT ); + if( deletedOptionIndex === null ){ + popupMenu.addItem({ + html : DELETED_OPTION_TEXT, + func : function( clickEvent, thisMenuOption ){ + var show_deleted = Galaxy.currHistoryPanel.toggleShowDeleted(); + thisMenuOption.checked = show_deleted; + } + }, START_INSERTING_AT_INDEX + 1 ) + deletedOptionIndex = START_INSERTING_AT_INDEX + 1; + } + // whether was there or added, update the checked option to reflect the panel's settings on the panel render + popupMenu.options[ deletedOptionIndex ].checked = Galaxy.currHistoryPanel.storage.get( 'show_deleted' ); + + var hiddenOptionIndex = popupMenu.findIndexByHtml( HIDDEN_OPTION_TEXT ); + if( hiddenOptionIndex === null ){ + popupMenu.addItem({ + html : HIDDEN_OPTION_TEXT, + func : function( clickEvent, thisMenuOption ){ + var show_hidden = Galaxy.currHistoryPanel.toggleShowHidden(); + thisMenuOption.checked = show_hidden; + } + }, START_INSERTING_AT_INDEX + 2 ) + hiddenOptionIndex = START_INSERTING_AT_INDEX + 2; + } + // whether was there or added, update the checked option to reflect the panel's settings on the panel render + popupMenu.options[ hiddenOptionIndex ].checked = Galaxy.currHistoryPanel.storage.get( 'show_hidden' ); + })(); + + //TODO: both the quota meter and the options-menu stuff need to be moved out when iframes are removed return; }); diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 templates/root/index.mako --- a/templates/root/index.mako +++ b/templates/root/index.mako @@ -10,7 +10,7 @@ $(function(){ // Init history options. $("#history-options-button").css( "position", "relative" ); - make_popupmenu( $("#history-options-button"), { + var popupmenu = PopupMenu.make_popupmenu( $("#history-options-button"), { "${_("History Lists")}": null, "${_("Saved Histories")}": function() { galaxy_main.location = "${h.url_for( controller='history', action='list')}"; @@ -40,18 +40,6 @@ "${_("Resume Paused Jobs")}": function() { galaxy_history.location = "${h.url_for( controller='history', action='resume_paused_jobs', current=True)}"; }, - "${_("Collapse Expanded Datasets")}": function() { - Galaxy.currHistoryPanel.collapseAllHdaBodies(); - //galaxy_history.location = "${h.url_for( controller='root', action='history', show_deleted=True)}"; - }, - "${_("Show/Hide Deleted Datasets")}": function() { - Galaxy.currHistoryPanel.toggleShowDeleted(); - //galaxy_history.location = "${h.url_for( controller='root', action='history', show_deleted=True)}"; - }, - "${_("Show/Hide Hidden Datasets")}": function() { - Galaxy.currHistoryPanel.toggleShowHidden(); - //galaxy_history.location = "${h.url_for( controller='root', action='history', show_hidden=True)}"; - }, "${_("Unhide Hidden Datasets")}": function() { if ( confirm( "Really unhide all hidden datasets?" ) ) { galaxy_main.location = "${h.url_for( controller='history', action='unhide_datasets', current=True )}"; @@ -83,7 +71,6 @@ galaxy_main.location = "${h.url_for( controller='history', action='import_archive' )}"; } }); - }); </script></%def> diff -r 330f05e523aee275c91f3e5de1177f8eb832d512 -r 6d7e637883b7e0e4c72c08a1269ca422da087661 test/functional/test_history_functions.py --- a/test/functional/test_history_functions.py +++ b/test/functional/test_history_functions.py @@ -14,11 +14,12 @@ name = 'anonymous' self.new_history( name=name ) global anonymous_history - anonymous_history = sa_session.query( galaxy.model.History ) \ - .filter( and_( galaxy.model.History.table.c.deleted==False, - galaxy.model.History.table.c.name==name ) ) \ - .order_by( desc( galaxy.model.History.table.c.create_time ) ) \ - .first() + anonymous_history = ( + sa_session.query( galaxy.model.History ) + .filter( and_( galaxy.model.History.table.c.deleted==False, galaxy.model.History.table.c.name==name ) ) + .order_by( desc( galaxy.model.History.table.c.create_time ) ) + .first() + ) assert anonymous_history is not None, "Problem retrieving anonymous_history from database" # Upload a dataset to anonymous_history so it will be set as the current history after login self.upload_file( '1.bed', dbkey='hg18' ) @@ -235,27 +236,35 @@ # Check list of histories to make sure shared history3 was cloned strings_displayed=[ "Clone of '%s' shared by '%s'" % ( history3.name, admin_user.email ) ] self.view_stored_active_histories( strings_displayed=strings_displayed ) + def test_035_clone_current_history( self ): """Testing cloning the current history""" # logged in as regular_user1 self.logout() self.login( email=admin_user.email ) + # Current history should be history3, add more datasets to history3, then delete them so we can # test cloning activatable datasets as well as only the active datasets self.upload_file( '2.bed', dbkey='hg18' ) - hda_2_bed = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \ - .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id, - galaxy.model.HistoryDatasetAssociation.table.c.name=='2.bed' ) ) \ - .first() + hda_2_bed = ( + sa_session.query( galaxy.model.HistoryDatasetAssociation ) + .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id, + galaxy.model.HistoryDatasetAssociation.table.c.name=='2.bed' ) ) + .first() + ) assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database" self.delete_history_item( str( hda_2_bed.id ) ) + self.upload_file( '3.bed', dbkey='hg18' ) - hda_3_bed = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \ - .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id, - galaxy.model.HistoryDatasetAssociation.table.c.name=='3.bed' ) ) \ - .first() + hda_3_bed = ( + sa_session.query( galaxy.model.HistoryDatasetAssociation ) + .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id==history3.id, + galaxy.model.HistoryDatasetAssociation.table.c.name=='3.bed' ) ) + .first() + ) assert hda_3_bed is not None, "Problem retrieving hda_3_bed from database" self.delete_history_item( str( hda_3_bed.id ) ) + # Test cloning activatable datasets self.clone_history( self.security.encode_id( history3.id ), 'activatable', @@ -267,6 +276,7 @@ .order_by( desc( galaxy.model.History.table.c.create_time ) ) \ .first() assert history3_clone2 is not None, "Problem retrieving history3_clone2 from database" + # Check list of histories to make sure shared history3 was cloned self.view_stored_active_histories( strings_displayed=[ "Clone of '%s'" % history3.name ] ) # Switch to the cloned history to make sure activatable datasets were cloned @@ -307,6 +317,7 @@ raise AssertionError, "Deleted datasets incorrectly included in cloned history history3_clone3" except: pass + def test_040_sharing_mulitple_histories_with_multiple_users( self ): """Testing sharing multiple histories containing only public datasets with multiple users""" # Logged in as admin_user https://bitbucket.org/galaxy/galaxy-central/changeset/cba8dbdb8312/ changeset: cba8dbdb8312 user: carlfeberhard date: 2012-12-07 20:00:51 summary: clean up; pack affected #: 3 files diff -r 6d7e637883b7e0e4c72c08a1269ca422da087661 -r cba8dbdb8312dcfa93e0be299fb560c067266064 static/scripts/mvc/history/history-model.js --- a/static/scripts/mvc/history/history-model.js +++ b/static/scripts/mvc/history/history-model.js @@ -66,7 +66,6 @@ //}); //this.bind( 'all', function( event ){ // //this.log( this + '', arguments ); - // console.info( this + '', arguments ); //}); }, diff -r 6d7e637883b7e0e4c72c08a1269ca422da087661 -r cba8dbdb8312dcfa93e0be299fb560c067266064 static/scripts/mvc/ui.js --- a/static/scripts/mvc/ui.js +++ b/static/scripts/mvc/ui.js @@ -190,7 +190,6 @@ // default settings this.$button = $button || $( '<div/>' ); this.options = options || []; - //console.debug( this + '.initialize, button:', $button, ', options:', options ); // set up button click -> open menu behavior var menu = this; @@ -230,7 +229,6 @@ // sets menu div id to '{{ id }}-menu' id : this.$button.attr( 'id' ) })); - //console.debug( this.$el, ':', this.$el.html() ); // set up behavior on each link/anchor elem if( this.options.length ){ @@ -239,7 +237,6 @@ $anchor = $li.children( 'a.popupmenu-option' ), menuFunc = menu.options[ i ].func; - //console.debug( 'setting up behavior:', i, menu.options[ i ], $li, $anchor ); if( $anchor.length && menuFunc ){ $anchor.click( function( event ){ menuFunc( event, menu.options[ i ] ); diff -r 6d7e637883b7e0e4c72c08a1269ca422da087661 -r cba8dbdb8312dcfa93e0be299fb560c067266064 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,tooltip_config:{},isMenuButton:true,id:null,href:null,target:null,enabled:true,visible:true}});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=$(Handlebars.partials.iconButton(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(this.model.attributes.on_click){this.model.attributes.on_click(a);return false}return true}});IconButtonView.templates={iconButton:Handlebars.partials.iconButton};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 GalaxyPaths=Backbone.Model.extend({defaults:{root_path:"",image_path:""}});var PopupMenu=Backbone.View.extend({templates:{wrapper:(function(){var a=['<ul id="<%= id %>-menu" class="dropdown-menu">',"<% if( options.length ){ %>","<% for( var i=0; i<options.length; i++ ){ var option = options[ i ]; %>","<% if( option.divider ){ %>",'<li class="divider"></li>',"<% } else { %>","<% if( option.header ){ %>",'<li class="head"><a href=""javascript:void(0);"><%- option.html %></a></li>',"<% } else { %>","<li><a ",'href="<% print( ( option.href )?( option.href ):( "javascript:void(0);" ) ) %>" ','<% if( option.target ){ %>target="<%= option.target %>" <% } %>','class="popupmenu-option">','<% if( option.checked ){ %><span class="ficon ok"></span><% } %>',"<%- option.html %>","</a></li>","<% } %>","<% } %>","<% } %>","<% } else { %>","<li>No Options.</li>","<% } %>","</ul>"];return _.template(a.join(""))}())},initialize:function(b,a){this.$button=b||$("<div/>");this.options=a||[];var c=this;this.$button.click(function(d){c._renderAndShow(d);return false});this.$button.data("PopupMenu",this);if(!this.templates.wrapper){this.templates.wrapper=Handlebars.templates["template-popupmenu-wrapper"]}},render:function(){var a=this;this.$el.addClass("popmenu-wrapper").css({position:"absolute",display:"none"});this.$el.html(PopupMenu.templates.menu({options:this.options,id:this.$button.attr("id")}));if(this.options.length){this.$el.find("li").each(function(c,b){var f=$(b),e=f.children("a.popupmenu-option"),d=a.options[c].func;if(e.length&&d){e.click(function(g){d(g,a.options[c])})}a.options[c].$li=f})}return this},_getShownPosition:function(b){var c=this.$el.width(),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}},_renderAndShow:function(a){this.render();this.$el.appendTo("body");this.$el.css(this._getShownPosition(a));this._setUpCloseBehavior();this.$el.show()},_setUpCloseBehavior:function(){var b=this,a=function(c){c.bind("click.close_popup",function(){b.remove();c.unbind("click.close_popup")})};a($(window.document));a($(window.top.document));_.each(window.top.frames,function(c){a($(c.document))})},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.templates={menu:Handlebars.templates["template-popupmenu-menu"]};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(j){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}var i;switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;case"demo":if(i===undefined||i.closed){i=window.open(j,k);i.creator=self}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,tooltip_config:{},isMenuButton:true,id:null,href:null,target:null,enabled:true,visible:true}});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=$(Handlebars.partials.iconButton(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(this.model.attributes.on_click){this.model.attributes.on_click(a);return false}return true}});IconButtonView.templates={iconButton:Handlebars.partials.iconButton};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 GalaxyPaths=Backbone.Model.extend({defaults:{root_path:"",image_path:""}});var PopupMenu=Backbone.View.extend({initialize:function(b,a){this.$button=b||$("<div/>");this.options=a||[];var c=this;this.$button.click(function(d){c._renderAndShow(d);return false});this.$button.data("PopupMenu",this);if(!this.templates.wrapper){this.templates.wrapper=Handlebars.templates["template-popupmenu-wrapper"]}},render:function(){var a=this;this.$el.addClass("popmenu-wrapper").css({position:"absolute",display:"none"});this.$el.html(PopupMenu.templates.menu({options:this.options,id:this.$button.attr("id")}));if(this.options.length){this.$el.find("li").each(function(c,b){var f=$(b),e=f.children("a.popupmenu-option"),d=a.options[c].func;if(e.length&&d){e.click(function(g){d(g,a.options[c])})}a.options[c].$li=f})}return this},_getShownPosition:function(b){var c=this.$el.width(),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}},_renderAndShow:function(a){this.render();this.$el.appendTo("body");this.$el.css(this._getShownPosition(a));this._setUpCloseBehavior();this.$el.show()},_setUpCloseBehavior:function(){var b=this,a=function(c){c.bind("click.close_popup",function(){b.remove();c.unbind("click.close_popup")})};a($(window.document));a($(window.top.document));_.each(window.top.frames,function(c){a($(c.document))})},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.templates={menu:Handlebars.templates["template-popupmenu-menu"]};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(j){var j=d.attr("href"),k=d.attr("target"),h=d.attr("confirm");f.func=function(){if((h)&&(!confirm(h))){return}var i;switch(k){case"_parent":window.parent.location=j;break;case"_top":window.top.location=j;break;case"demo":if(i===undefined||i.closed){i=window.open(j,k);i.creator=self}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.
participants (1)
-
Bitbucket