Unification and refactoring of front end templating for js-visualizations (trackster, circster, etc.)

This commit is contained in:
Aysam Guerler
2013-08-05 17:02:05 -04:00
parent 31d457cfc5
commit bc5b2f5953
30 changed files with 1335 additions and 750 deletions
@@ -745,47 +745,58 @@ class VisualizationController( BaseUIController, SharableMixin, UsesAnnotations,
@web.expose
@web.require_login()
def trackster(self, trans, id=None, **kwargs):
def trackster(self, trans, **kwargs):
"""
Display browser for the visualization denoted by id and add the datasets listed in `dataset_ids`.
"""
# Get dataset to add.
# define app configuration
app = { 'jscript' : "viz/trackster" }
# get dataset to add
id = kwargs.get( "id", None )
# get dataset to add
new_dataset_id = kwargs.get( "dataset_id", None )
# Check for gene region
gene_region = GenomeRegion.from_str(kwargs.get("gene_region", ""))
# Set up new browser if no id provided.
# set up new browser if no id provided
if not id:
# Use dbkey from dataset to be added or from incoming parameter.
# use dbkey from dataset to be added or from incoming parameter
dbkey = None
if new_dataset_id:
dbkey = self.get_dataset( trans, new_dataset_id ).dbkey
if dbkey == '?':
dbkey = kwargs.get( "dbkey", None )
# fill template
return trans.fill_template( "tracks/browser.mako", viewport_config=gene_region.__dict__, add_dataset=new_dataset_id, default_dbkey=dbkey )
# save database key
app['default_dbkey'] = dbkey
# add url
app['new_browser'] = web.url_for( controller='visualization', action='new_browser', default_dbkey=dbkey )
else:
# load saved visualization
vis = self.get_visualization( trans, id, check_ownership=False, check_accessible=True )
app['viz_config'] = self.get_visualization_config( trans, vis )
# backup id
app['id'] = id;
# Display saved visualization.
vis = self.get_visualization( trans, id, check_ownership=False, check_accessible=True )
viz_config = self.get_visualization_config( trans, vis )
# Update gene region of saved visualization if user parses a new gene region in the url
# add dataset id
app['add_dataset'] = new_dataset_id
# check for gene region
gene_region = GenomeRegion.from_str(kwargs.get("gene_region", ""))
# update gene region of saved visualization if user parses a new gene region in the url
if gene_region.chrom is not None:
viz_config['viewport']['chrom'] = gene_region.chrom
viz_config['viewport']['start'] = gene_region.start
viz_config['viewport']['end'] = gene_region.end
'''
FIXME:
if new_dataset is not None:
if trans.security.decode_id(new_dataset) in [ d["dataset_id"] for d in viz_config.get("tracks") ]:
new_dataset = None # Already in browser, so don't add
'''
app['gene_region'] = {
'chrom' : gene_region.chrom,
'start' : gene_region.start,
'end' : gene_region.end
}
# fill template
return trans.fill_template( 'tracks/browser.mako', config=viz_config, add_dataset=new_dataset_id )
return trans.fill_template('galaxy.panels.mako', config = {'right_panel' : True, 'app' : app})
@web.expose
def circster( self, trans, id=None, hda_ldda=None, dataset_id=None, dbkey=None ):
@@ -839,7 +850,15 @@ class VisualizationController( BaseUIController, SharableMixin, UsesAnnotations,
if not isinstance( genome_data, str ):
track[ 'preloaded_data' ] = genome_data
return trans.fill_template( 'visualization/circster.mako', viz_config=viz_config, genome=genome )
# define app configuration for generic mako template
app = {
'jscript' : "viz/circster",
'viz_config' : viz_config,
'genome' : genome
}
# fill template
return trans.fill_template('galaxy.panels.mako', config = {'app' : app})
@web.expose
def sweepster( self, trans, id=None, hda_ldda=None, dataset_id=None, regions=None ):
-1
View File
@@ -4,7 +4,6 @@
// dependencies
define(["utils/galaxy.css", "libs/backbone/backbone-relational"], function(css) {
// frame manager
var GalaxyFrameManager = Backbone.View.extend(
+3 -3
View File
@@ -98,7 +98,7 @@ $._farbtastic = function (container, options) {
.find('div>*').css('position', 'absolute');
// IE Fix: Recreate canvas elements with doc.createElement and excanvas.
$.browser.msie && $('canvas', container).each(function () {
navigator.userAgent.match(/msie/i) && $('canvas', container).each(function () {
// Fetch info.
var attr = { 'class': $(this).attr('class'), style: this.getAttribute('style') },
e = document.createElement('canvas');
@@ -166,7 +166,7 @@ $._farbtastic = function (container, options) {
// New color
color2 = fb.pack(fb.HSLToRGB([d2, 1, 0.5]));
if (i > 0) {
if ($.browser.msie) {
if (navigator.userAgent.match(/msie/i)) {
// IE's gradient calculations mess up the colors. Correct along the diagonals.
var corr = (1 + Math.min(Math.abs(Math.tan(angle1)), Math.abs(Math.tan(Math.PI / 2 - angle1)))) / n;
color1 = fb.pack(fb.HSLToRGB([d1 - 0.15 * corr, 1, 0.5]));
@@ -246,7 +246,7 @@ $._farbtastic = function (container, options) {
fb.ctxMask.drawImage(buffer, 0, 0, sz + 1, sz + 1, -sq, -sq, sq * 2, sq * 2);
}
// Method #2: drawing commands (old Canvas).
else if (!$.browser.msie) {
else if (!navigator.userAgent.match(/msie/i)) {
// Render directly at half-resolution
var sz = Math.floor(size / 2);
calculateMask(sz, sz, function (x, y, c, a) {
@@ -1,20 +1,19 @@
;(function($){ // secure $ jQuery alias
/*******************************************************************************************/
// jquery.event.hover.js - rev 5
// jquery.event.hover.js
// Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
// Liscensed under the MIT License (MIT-LICENSE.txt)
// Licensed under the MIT License (MIT-LICENSE.txt)
// http://www.opensource.org/licenses/mit-license.php
// Created: 2008-06-02 | Updated: 2008-07-30
//
// JQuery 1.9+ compatible version
//
// Optional settings :
// $.event.special.hover.delay = 100;
// Defines the delay (msec) while mouse is inside the element before checking the speed
// $.event.special.hover.speed = 100;
// Defines the maximum speed (px/sec) the mouse may be moving to trigger the hover event
/*******************************************************************************************/
// USE THESE PROPERTIES TO CUSTOMIZE SETTINGS...
// $.event.special.hover.delay = 100;
// Defines the delay (msec) while mouse is inside the element before checking the speed
// $.event.special.hover.speed = 100;
// Defines the maximum speed (px/sec) the mouse may be moving to trigger the hover event
// save the old jquery "hover" method
$.fn._hover = $.fn.hover;
@@ -47,8 +46,8 @@ function hoverHandler( event ){
data.dist2 = 0; // init mouse distance²
data.event = event; // store the event
event.type = "hoverstart"; // hijack event
if ( $.event.handle.call( this, event ) !== false ){ // handle "hoverstart"
data.elem = this; // ref to the current element
if($.event.dispatch.call(this, event) !== false) {
data.elem = this; // ref to the current element
$.event.add( this, "mousemove", hoverHandler, data ); // track the mouse
data.timer = setTimeout( compare, data.delay ); // start async compare
}
@@ -62,7 +61,7 @@ function hoverHandler( event ){
clearTimeout( data.timer ); // uncompare
if ( data.hovered ){
event.type = "hoverend"; // hijack event
$.event.handle.call( this, event ); // handle "hoverend"
$.event.dispatch.call(this, event); // handle "hoverend"
data.hovered--; // reset flag
}
else $.event.remove( data.elem, "mousemove", hoverHandler ); // untrack
@@ -71,7 +70,7 @@ function hoverHandler( event ){
if ( data.dist2 <= Math.pow( data.speed*( data.delay/1e3 ), 2 ) ){ // speed acceptable
$.event.remove( data.elem, "mousemove", hoverHandler ); // untrack
data.event.type = "hover"; // hijack event
if ( $.event.handle.call( data.elem, data.event ) !== false ) // handle "hover"
if($.event.dispatch.call(data.elem, data.event) !== false) // handle "hover"
data.hovered++; // flag for "hoverend"
}
else data.timer = setTimeout( compare, data.delay ); // async recurse
+304 -190
View File
@@ -1,101 +1,172 @@
/**
* -- Functions for creating large UI elements. --
* necessary galaxy paths
*/
// =============================================================================
/**
* -- Utility models and views for Galaxy objects. --
*/
/**
* Clickable button represented as an icon.
*/
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 GalaxyPaths = Backbone.Model.extend(
{
defaults:
{
root_path: "",
image_path: ""
}
//validate : function( attributes ){
//TODO: validate href or on_click
//TODO: validate icon_class
//}
});
/**
* functions for creating large ui elements
*/
/**
*
* backbone model for icon buttons
*/
var IconButtonView = Backbone.View.extend({
initialize : function(){
// better rendering this way (for me anyway)
var IconButton = Backbone.Model.extend(
{
defaults:
{
title : "",
icon_class : "",
on_click : null,
menu_options : null,
is_menu_button : true,
id : null,
href : null,
target : null,
enabled : true,
visible : true,
tooltip_config : {}
}
});
/**
* backbone view for icon buttons
*/
var IconButtonView = Backbone.View.extend(
{
// initialize
initialize: function()
{
// better rendering this way
this.model.attributes.tooltip_config = { placement : 'bottom' };
this.model.bind( 'change', this.render, this );
this.model.bind('change', this.render, this);
},
render : function(){
//NOTE: not doing this hide will lead to disappearing buttons when they're both being hovered over & rendered
this.$el.tooltip( 'hide' );
// render
render: function()
{
// hide tooltip
this.$el.tooltip('hide');
// template in common-templates.html
var newElem = $( Handlebars.partials.iconButton( this.model.toJSON() ) );
newElem.tooltip( this.model.get( 'tooltip_config' ) );
// create element
var new_elem = this.template(this.model.attributes);
this.$el.replaceWith( newElem );
this.setElement( newElem );
// configure tooltip
new_elem.tooltip(this.model.get('tooltip_config'));
// replace
this.$el.replaceWith(new_elem);
this.setElement(new_elem);
// return
return this;
},
events : {
// events
events:
{
'click' : 'click'
},
click : function( event ){
// click
click: function( event )
{
// if on_click pass to that function
if( this.model.attributes.on_click ){
this.model.attributes.on_click( event );
if(this.model.attributes.on_click)
{
this.model.attributes.on_click(event);
return false;
}
// otherwise, bubble up (to href or whatever)
return true;
},
// generate html element
template: function(options)
{
// initialize
var buffer = 'title="' + options.title + '" class="icon-button';
// is menu button
if(options.is_menu_button)
buffer += ' menu-button';
// define tooltip
if(options.title)
buffer += ' tooltip';
// add icon class
buffer += ' ' + options.icon_class;
// add enabled/disabled class
if(!options.enabled)
buffer += '_disabled';
// close class tag
buffer += '"';
// add id
if(options.id)
buffer += ' id="' + options.id + '"';
// add href
buffer += ' href="' + options.href + '"';
// add target for href
if(options.target)
buffer += ' target="' + options.target + '"';
// set visibility
if(!options.visible)
buffer += ' style="display: none;"';
// enabled/disabled
if (options.enabled)
buffer = '<a ' + buffer + '/>';
else
buffer = '<span ' + buffer + '/>';
// return element
return $(buffer);
}
});
//TODO: bc h.templates is gen. loaded AFTER ui, Handlebars.partials.iconButton === undefined
IconButtonView.templates = {
iconButton : Handlebars.partials.iconButton
};
var IconButtonCollection = Backbone.Collection.extend({
// define collection
var IconButtonCollection = Backbone.Collection.extend(
{
model: IconButton
});
//------------------------------------------------------------------------------
/**
* Menu with multiple icon buttons. Views are not needed nor used for individual buttons.
* menu with multiple icon buttons
* views are not needed nor used for individual buttons
*/
var IconButtonMenuView = Backbone.View.extend({
var IconButtonMenuView = Backbone.View.extend(
{
// tag
tagName: 'div',
initialize: function() {
// initialize
initialize: function()
{
this.render();
},
render: function() {
// render
render: function()
{
// initialize icon buttons
var self = this;
this.collection.each(function(button) {
// Create and add icon button to menu.
this.collection.each(function(button)
{
// create and add icon button to menu
var elt =
$('<a/>').attr('href', 'javascript:void(0)')
.attr('title', button.attributes.title)
@@ -104,17 +175,17 @@ var IconButtonMenuView = Backbone.View.extend({
.appendTo(self.$el)
.click(button.attributes.on_click);
if (button.attributes.tooltip_config) {
// configure tooltip
if (button.attributes.tooltip_config)
elt.tooltip(button.attributes.tooltip_config);
}
// If there are options, add popup menu to icon.
// add popup menu to icon
var menu_options = button.get('options');
if (menu_options) {
if (menu_options)
make_popupmenu(elt, menu_options);
}
});
// return
return this;
}
});
@@ -125,20 +196,23 @@ var IconButtonMenuView = Backbone.View.extend({
* defines an icon button. Each dictionary must have the following
* elements: icon_class, title, and on_click.
*/
var create_icon_buttons_menu = function(config, global_config) {
if (!global_config) { global_config = {}; }
var create_icon_buttons_menu = function(config, global_config)
{
// initialize global configuration
if (!global_config) global_config = {};
// Create and initialize menu.
// create and initialize menu
var buttons = new IconButtonCollection(
_.map(config, function(button_config) {
return new IconButton(_.extend(button_config, global_config));
})
);
_.map(config, function(button_config)
{
return new IconButton(_.extend(button_config, global_config));
})
);
// return menu
return new IconButtonMenuView( {collection: buttons} );
};
// =============================================================================
/**
*
@@ -155,196 +229,232 @@ var GridView = Backbone.View.extend({
});
// =============================================================================
/**
* Necessary Galaxy paths.
*/
var GalaxyPaths = Backbone.Model.extend({
defaults: {
root_path: "",
image_path: ""
}
});
// =============================================================================
/** @class View for a popup menu
* @name PopupMenu
*
* @constructs
/**
* view for a popup menu
*/
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 ){
initialize: function($button, options)
{
// default settings
this.$button = $button || $( '<div/>' );
this.$button = $button || $('<div/>');
this.options = options || [];
// set up button click -> open menu behavior
var menu = this;
this.$button.click( function( event ){
menu._renderAndShow( event );
//event.stopPropagation();
this.$button.click(function(event)
{
menu._renderAndShow(event);
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
this.$button.data('PopupMenu', this);
},
/** Render the menu. NOTE: doesn't attach itself to the DOM.
* @see PopupMenu#_renderAndShow
*/
render : function(){
// render the menu
// this menu doesn't attach itself to the DOM (see _renderAndShow)
render: function()
{
// link this popup
var menu = this;
// render the menu body
this.$el.addClass( 'popmenu-wrapper' )
.css({
position: 'absolute',
display: 'none'
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' )
}));
// use template
this.$el.html(this.template(this.$button.attr('id'), this.options));
// set up behavior on each link/anchor elem
if( this.options.length ){
this.$el.find( 'li' ).each( function( i, li ){
var $li = $( li ),
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;
menuFunc = menu.options[i].func;
if( $anchor.length && menuFunc ){
$anchor.click( function( event ){
menuFunc( event, menu.options[ i ] );
// click event
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;
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 ;
// get the absolute position/offset for the menu
_getShownPosition : function( clickEvent )
{
// get element width
var menuWidth = this.$el.width();
// display menu horiz. centered on click...
var x = clickEvent.pageX - menuWidth / 2 ;
// ...but adjust that to handle horiz. scroll and window dimensions (draw entirely on visible screen area)
// adjust to handle horiz. scroll and window dimensions (draw entirely on visible screen area)
x = Math.min( x, $( document ).scrollLeft() + $( window ).width() - menuWidth - 5 );
x = Math.max( x, $( document ).scrollLeft() + 5 );
// return
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 ){
// 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.$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 an event handler to all available frames so that when anything is clicked
// the menu is removed from the DOM and the event handler unbinds itself
_setUpCloseBehavior: function()
{
// function to close popup and unbind itself
var menu = this;
var 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 ) );
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 ){
// 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 );
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 );
}
// 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 ) ){
// 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 ) )];
// search for a menu option by it's html
findItemByHtml: function(html)
{
return this.options[(this.findIndexByHtml(html))];
},
/** String representation. */
toString : function(){
// string representation
toString: function()
{
return 'PopupMenu';
},
// template
template: function(id, options)
{
// initialize template
var tmpl = '<ul id="' + id + '-menu" class="dropdown-menu">';
// check item number
if (options.length > 0)
{
// add option
for (var i in options)
{
// get item
var item = options[i];
// check for divider
if (item.divider)
{
// add divider
tmpl += '<li class="divider"></li>';
} else {
// identify header
if(item.header)
{
tmpl += '<li class="head"><a href="javascript:void(0);">' + item.html + '</a></li>';
} else {
// add href
if (item.href)
{
tmpl += '<li><a href="' + item.href + '"';
tmpl += 'target="' + item.target + '"';
} else
tmpl += '<li><a href="javascript:void(0);"';
// add class
tmpl += 'class="popupmenu-option">'
// add target
if (item.checked)
tmpl += '<span class="fa-icon-ok"></span>';
// add html
tmpl += item.html;
}
}
}
} else
tmpl += '<li>No Options.</li>';
// return
return tmpl + '</ul>';
}
});
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
// 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.
@@ -379,29 +489,33 @@ PopupMenu.make_popupmenu = function( button_element, initial_options ){
* @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 );
PopupMenu.convertLinksToOptions = function( $parent, selector )
{
$parent = $($parent);
selector = selector || 'a';
var options = [];
$parent.find( selector ).each( function( elem, i ){
var option = {},
$link = $( elem );
$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 ){
if( linkHref )
{
var linkHref = $link.attr( 'href' ),
linkTarget = $link.attr( 'target' ),
confirmText = $link.attr( 'confirm' );
option.func = function(){
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 ){
switch( linkTarget )
{
// relocate the center panel
case '_parent':
window.parent.location = linkHref;
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
(function(c){c.fn._hover=c.fn.hover;c.fn.hover=function(f,e,d){if(d){this.bind("hoverstart",f)}if(e){this.bind("hoverend",d?d:e)}return !f?this.trigger("hover"):this.bind("hover",d?e:f)};var b=c.event.special.hover={delay:100,speed:100,setup:function(d){d=c.extend({speed:b.speed,delay:b.delay,hovered:0},d||{});c.event.add(this,"mouseenter mouseleave",a,d)},teardown:function(){c.event.remove(this,"mouseenter mouseleave",a)}};function a(d){var f=d.data||d;switch(d.type){case"mouseenter":f.dist2=0;f.event=d;d.type="hoverstart";if(c.event.handle.call(this,d)!==false){f.elem=this;c.event.add(this,"mousemove",a,f);f.timer=setTimeout(e,f.delay)}break;case"mousemove":f.dist2+=Math.pow(d.pageX-f.event.pageX,2)+Math.pow(d.pageY-f.event.pageY,2);f.event=d;break;case"mouseleave":clearTimeout(f.timer);if(f.hovered){d.type="hoverend";c.event.handle.call(this,d);f.hovered--}else{c.event.remove(f.elem,"mousemove",a)}break;default:if(f.dist2<=Math.pow(f.speed*(f.delay/1000),2)){c.event.remove(f.elem,"mousemove",a);f.event.type="hover";if(c.event.handle.call(f.elem,f.event)!==false){f.hovered++}}else{f.timer=setTimeout(e,f.delay)}f.dist2=0;break}function e(){a(f)}}})(jQuery);
(function(c){c.fn._hover=c.fn.hover;c.fn.hover=function(f,e,d){if(d){this.bind("hoverstart",f)}if(e){this.bind("hoverend",d?d:e)}return !f?this.trigger("hover"):this.bind("hover",d?e:f)};var b=c.event.special.hover={delay:100,speed:100,setup:function(d){d=c.extend({speed:b.speed,delay:b.delay,hovered:0},d||{});c.event.add(this,"mouseenter mouseleave",a,d)},teardown:function(){c.event.remove(this,"mouseenter mouseleave",a)}};function a(d){var f=d.data||d;switch(d.type){case"mouseenter":f.dist2=0;f.event=d;d.type="hoverstart";if(c.event.dispatch.call(this,d)!==false){f.elem=this;c.event.add(this,"mousemove",a,f);f.timer=setTimeout(e,f.delay)}break;case"mousemove":f.dist2+=Math.pow(d.pageX-f.event.pageX,2)+Math.pow(d.pageY-f.event.pageY,2);f.event=d;break;case"mouseleave":clearTimeout(f.timer);if(f.hovered){d.type="hoverend";c.event.dispatch.call(this,d);f.hovered--}else{c.event.remove(f.elem,"mousemove",a)}break;default:if(f.dist2<=Math.pow(f.speed*(f.delay/1000),2)){c.event.remove(f.elem,"mousemove",a);f.event.type="hover";if(c.event.dispatch.call(f.elem,f.event)!==false){f.hovered++}}else{f.timer=setTimeout(e,f.delay)}f.dist2=0;break}function e(){a(f)}}})(jQuery);
+1 -1
View File
@@ -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({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)},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};
var IconButton=Backbone.Model.extend({defaults:{title:"",icon_class:"",on_click:null,menu_options:null,is_menu_button:true,id:null,href:null,target:null,enabled:true,visible:true,tooltip_config:{}}});var IconButtonView=Backbone.View.extend({initialize:function(){this.model.attributes.tooltip_config={placement:"bottom"};this.model.bind("change",this.render,this)},render:function(){this.$el.tooltip("hide");var a=this.template(this.model.attributes);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},template:function(b){var a='title="'+b.title+'" class="icon-button';if(b.is_menu_button){a+=" menu-button"}if(b.title){a+=" tooltip"}a+=" "+b.icon_class;if(!b.enabled){a+="_disabled"}a+='"';if(b.id){a+=' id="'+b.id+'"'}a+=' href="'+b.href+'"';if(b.target){a+=' target="'+b.target+'"'}if(!b.visible){a+=' style="display: none;"'}if(b.enabled){a="<a "+a+"/>"}else{a="<span "+a+"/>"}return $(a)}});var IconButtonCollection=Backbone.Collection.extend({model:IconButton});var IconButtonMenuView=Backbone.View.extend({tagName:"div",initialize:function(){this.render()},render:function(){var a=this;this.collection.each(function(d){var b=$("<a/>").attr("href","javascript:void(0)").attr("title",d.attributes.title).addClass("icon-button menu-button").addClass(d.attributes.icon_class).appendTo(a.$el).click(d.attributes.on_click);if(d.attributes.tooltip_config){b.tooltip(d.attributes.tooltip_config)}var c=d.get("options");if(c){make_popupmenu(b,c)}});return this}});var create_icon_buttons_menu=function(b,a){if(!a){a={}}var c=new IconButtonCollection(_.map(b,function(d){return new IconButton(_.extend(d,a))}));return new IconButtonMenuView({collection:c})};var Grid=Backbone.Collection.extend({});var GridView=Backbone.View.extend({});var 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)},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};
@@ -1 +1 @@
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.panel_section=b(function(e,n,d,l,k){d=d||e.helpers;var i="",c,h,o=this,f="function",m=d.helperMissing,g=void 0,j=this.escapeExpression;i+='<div class="toolSectionTitle" id="title_';h=d.id;c=h||n.id;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"id",{hash:{}})}}i+=j(c)+'">\n <a href="javascript:void(0)"><span>';h=d.name;c=h||n.name;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"name",{hash:{}})}}i+=j(c)+'</span></a>\n</div>\n<div id="';h=d.id;c=h||n.id;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"id",{hash:{}})}}i+=j(c)+'" class="toolSectionBody" style="display: none; ">\n <div class="toolSectionBg"></div>\n<div>';return i})})();
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.panel_section=b(function(e,k,d,j,i){this.compilerInfo=[2,">= 1.0.0-rc.3"];d=d||e.helpers;i=i||{};var g="",c,f="function",h=this.escapeExpression;g+='<div class="toolSectionTitle" id="title_';if(c=d.id){c=c.call(k,{hash:{},data:i})}else{c=k.id;c=typeof c===f?c.apply(k):c}g+=h(c)+'">\n <a href="javascript:void(0)"><span>';if(c=d.name){c=c.call(k,{hash:{},data:i})}else{c=k.name;c=typeof c===f?c.apply(k):c}g+=h(c)+'</span></a>\n</div>\n<div id="';if(c=d.id){c=c.call(k,{hash:{},data:i})}else{c=k.id;c=typeof c===f?c.apply(k):c}g+=h(c)+'" class="toolSectionBody" style="display: none; ">\n <div class="toolSectionBg"></div>\n<div>';return g})})();
@@ -1 +1 @@
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_form=b(function(f,p,e,n,m){e=e||f.helpers;var k="",c,r,j,i,q=this,g="function",o=e.helperMissing,h=void 0,l=this.escapeExpression;function d(v,u){var s="",t;s+='\n <div class="form-row">\n <label for="';j=e.name;t=j||v.name;if(typeof t===g){t=t.call(v,{hash:{}})}else{if(t===h){t=o.call(v,"name",{hash:{}})}}s+=l(t)+'">';j=e.label;t=j||v.label;if(typeof t===g){t=t.call(v,{hash:{}})}else{if(t===h){t=o.call(v,"label",{hash:{}})}}s+=l(t)+':</label>\n <div class="form-row-input">\n ';j=e.html;t=j||v.html;if(typeof t===g){t=t.call(v,{hash:{}})}else{if(t===h){t=o.call(v,"html",{hash:{}})}}if(t||t===0){s+=t}s+='\n </div>\n <div class="toolParamHelp" style="clear: both;">\n ';j=e.help;t=j||v.help;if(typeof t===g){t=t.call(v,{hash:{}})}else{if(t===h){t=o.call(v,"help",{hash:{}})}}s+=l(t)+'\n </div>\n <div style="clear: both;"></div>\n </div>\n ';return s}k+='<div class="toolFormTitle">';j=e.name;c=j||p.name;if(typeof c===g){c=c.call(p,{hash:{}})}else{if(c===h){c=o.call(p,"name",{hash:{}})}}k+=l(c)+" (version ";j=e.version;c=j||p.version;if(typeof c===g){c=c.call(p,{hash:{}})}else{if(c===h){c=o.call(p,"version",{hash:{}})}}k+=l(c)+')</div>\n <div class="toolFormBody">\n ';j=e.inputs;c=j||p.inputs;r=e.each;i=q.program(1,d,m);i.hash={};i.fn=i;i.inverse=q.noop;c=r.call(p,c,i);if(c||c===0){k+=c}k+='\n </div>\n <div class="form-row form-actions">\n <input type="submit" class="btn btn-primary" name="runtool_btn" value="Execute">\n</div>\n<div class="toolHelp">\n <div class="toolHelpBody">';j=e.help;c=j||p.help;if(typeof c===g){c=c.call(p,{hash:{}})}else{if(c===h){c=o.call(p,"help",{hash:{}})}}k+=l(c)+"</div>\n</div>";return k})})();
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_form=b(function(f,l,e,k,j){this.compilerInfo=[2,">= 1.0.0-rc.3"];e=e||f.helpers;j=j||{};var h="",c,g="function",i=this.escapeExpression,m=this;function d(q,p){var n="",o;n+='\n <div class="form-row">\n <label for="';if(o=e.name){o=o.call(q,{hash:{},data:p})}else{o=q.name;o=typeof o===g?o.apply(q):o}n+=i(o)+'">';if(o=e.label){o=o.call(q,{hash:{},data:p})}else{o=q.label;o=typeof o===g?o.apply(q):o}n+=i(o)+':</label>\n <div class="form-row-input">\n ';if(o=e.html){o=o.call(q,{hash:{},data:p})}else{o=q.html;o=typeof o===g?o.apply(q):o}if(o||o===0){n+=o}n+='\n </div>\n <div class="toolParamHelp" style="clear: both;">\n ';if(o=e.help){o=o.call(q,{hash:{},data:p})}else{o=q.help;o=typeof o===g?o.apply(q):o}n+=i(o)+'\n </div>\n <div style="clear: both;"></div>\n </div>\n ';return n}h+='<div class="toolFormTitle">';if(c=e.name){c=c.call(l,{hash:{},data:j})}else{c=l.name;c=typeof c===g?c.apply(l):c}h+=i(c)+" (version ";if(c=e.version){c=c.call(l,{hash:{},data:j})}else{c=l.version;c=typeof c===g?c.apply(l):c}h+=i(c)+')</div>\n <div class="toolFormBody">\n ';c=e.each.call(l,l.inputs,{hash:{},inverse:m.noop,fn:m.program(1,d,j),data:j});if(c||c===0){h+=c}h+='\n </div>\n <div class="form-row form-actions">\n <input type="submit" class="btn btn-primary" name="runtool_btn" value="Execute">\n</div>\n<div class="toolHelp">\n <div class="toolHelpBody">';if(c=e.help){c=c.call(l,{hash:{},data:j})}else{c=l.help;c=typeof c===g?c.apply(l):c}h+=i(c)+"</div>\n</div>";return h})})();
@@ -1 +1 @@
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_link=b(function(e,n,d,l,k){d=d||e.helpers;var i="",c,h,o=this,f="function",m=d.helperMissing,g=void 0,j=this.escapeExpression;i+='<a class="';h=d.id;c=h||n.id;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"id",{hash:{}})}}i+=j(c)+' tool-link" href="';h=d.link;c=h||n.link;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"link",{hash:{}})}}i+=j(c)+'" target="';h=d.target;c=h||n.target;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"target",{hash:{}})}}i+=j(c)+'" minsizehint="';h=d.min_width;c=h||n.min_width;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"min_width",{hash:{}})}}i+=j(c)+'">';h=d.name;c=h||n.name;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"name",{hash:{}})}}i+=j(c)+"</a> ";h=d.description;c=h||n.description;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"description",{hash:{}})}}i+=j(c);return i})})();
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_link=b(function(e,k,d,j,i){this.compilerInfo=[2,">= 1.0.0-rc.3"];d=d||e.helpers;i=i||{};var g="",c,f="function",h=this.escapeExpression;g+='<a class="';if(c=d.id){c=c.call(k,{hash:{},data:i})}else{c=k.id;c=typeof c===f?c.apply(k):c}g+=h(c)+' tool-link" href="';if(c=d.link){c=c.call(k,{hash:{},data:i})}else{c=k.link;c=typeof c===f?c.apply(k):c}g+=h(c)+'" target="';if(c=d.target){c=c.call(k,{hash:{},data:i})}else{c=k.target;c=typeof c===f?c.apply(k):c}g+=h(c)+'" minsizehint="';if(c=d.min_width){c=c.call(k,{hash:{},data:i})}else{c=k.min_width;c=typeof c===f?c.apply(k):c}g+=h(c)+'">';if(c=d.name){c=c.call(k,{hash:{},data:i})}else{c=k.name;c=typeof c===f?c.apply(k):c}g+=h(c)+"</a> ";if(c=d.description){c=c.call(k,{hash:{},data:i})}else{c=k.description;c=typeof c===f?c.apply(k):c}g+=h(c);return g})})();
@@ -1 +1 @@
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_search=b(function(e,n,d,l,k){d=d||e.helpers;var i="",c,h,o=this,f="function",m=d.helperMissing,g=void 0,j=this.escapeExpression;i+='<input type="text" name="query" value="';h=d.search_hint_string;c=h||n.search_hint_string;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"search_hint_string",{hash:{}})}}i+=j(c)+'" id="tool-search-query" autocomplete="off" class="search-query parent-width" />\n<a id="search-clear-btn" class="tooltip" title="clear search (esc)"> </a>\n<img src="';h=d.spinner_url;c=h||n.spinner_url;if(typeof c===f){c=c.call(n,{hash:{}})}else{if(c===g){c=m.call(n,"spinner_url",{hash:{}})}}i+=j(c)+'" id="search-spinner" class="search-spinner"/>';return i})})();
(function(){var b=Handlebars.template,a=Handlebars.templates=Handlebars.templates||{};a.tool_search=b(function(e,k,d,j,i){this.compilerInfo=[2,">= 1.0.0-rc.3"];d=d||e.helpers;i=i||{};var g="",c,f="function",h=this.escapeExpression;g+='<input type="text" name="query" value="';if(c=d.search_hint_string){c=c.call(k,{hash:{},data:i})}else{c=k.search_hint_string;c=typeof c===f?c.apply(k):c}g+=h(c)+'" id="tool-search-query" autocomplete="off" class="search-query parent-width" />\n<a id="search-clear-btn" class="tooltip" title="clear search (esc)"> </a>\n<img src="';if(c=d.spinner_url){c=c.call(k,{hash:{},data:i})}else{c=k.spinner_url;c=typeof c===f?c.apply(k):c}g+=h(c)+'" id="search-spinner" class="search-spinner"/>';return g})})();
+1 -1
View File
@@ -1 +1 @@
define(["libs/underscore","viz/trackster/slotting","viz/trackster/painters","viz/trackster/tracks"],function(b,d,c,a){});
var ui=null;var view=null;var browser_router=null;require(["utils/galaxy.css","libs/jquery/jstorage","libs/jquery/jquery.event.drag","libs/jquery/jquery.event.hover","libs/jquery/jquery.mousewheel","libs/jquery/jquery-ui","libs/jquery/jquery-ui-combobox","libs/farbtastic","libs/jquery/jquery.form","libs/jquery/jquery.rating"],function(a){a.load_file("/static/style/jquery.rating.css");a.load_file("/static/style/history.css");a.load_file("/static/style/autocomplete_tagging.css");a.load_file("/static/style/jquery-ui/smoothness/jquery-ui.css");a.load_file("/static/style/library.css");a.load_file("/static/style/trackster.css")});define(["libs/backbone/backbone-relational","viz/visualization","viz/trackster_ui"],function(c,a,b){var d=Backbone.View.extend({initialize:function(){ui=new b.TracksterUI(config.url.root);ui.createButtonMenu();ui.buttonMenu.$el.attr("style","float: right");$("#center .unified-panel-header-inner").append(ui.buttonMenu.$el);$("#right-border").click(function(){view.resize_window()});force_right_panel("hide");if(config.app.id){this.view_existing()}else{this.view_new()}},set_up_router:function(e){browser_router=new a.TrackBrowserRouter(e);Backbone.history.start()},view_existing:function(){var e=config.app.viz_config;view=ui.create_visualization({container:$("#browser-container"),name:e.title,vis_id:e.vis_id,dbkey:e.dbkey},e.viewport,e.tracks,e.bookmarks,true);this.init_editor()},view_new:function(){var e=this;$.ajax({url:config.url.new_browser,data:{},error:function(){alert("Couldn't create new browser.")},success:function(f){show_modal("New Visualization",f,{Cancel:function(){window.location=config.url.viz_list},Create:function(){e.create_browser($("#new-title").val(),$("#new-dbkey").val())}});$("#new-title").focus();$("select[name='dbkey']").combobox({appendTo:$("#overlay"),size:40});$("#overlay").css("overflow","auto")}})},create_browser:function(f,e){$(document).trigger("convert_to_values");view=ui.create_visualization({container:$("#browser-container"),name:f,dbkey:e},config.app.gene_region);this.init_editor();view.editor=true;hide_modal()},init_editor:function(){$("#title").text(view.name+" ("+view.dbkey+")");if(config.app.add_dataset){$.ajax({url:config.url.datasets+"/"+config.app.add_dataset,data:{hda_ldda:"hda",data_type:"track_config"},dataType:"json",success:function(e){view.add_drawable(b.object_from_template(e,view,view))}})}$("#add-bookmark-button").click(function(){var f=view.chrom+":"+view.low+"-"+view.high,e="Bookmark description";return ui.add_bookmark(f,e,true)});ui.init_keyboard_nav(view);this.set_up_router({view:view})}});return{GalaxyApp:d}});
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
define(["base","libs/underscore","viz/trackster/slotting","viz/trackster/painters","viz/trackster/tracks","viz/visualization"],function(g,c,h,e,b,d){var a=b.object_from_template;var f=g.Base.extend({initialize:function(j){this.baseURL=j},createButtonMenu:function(){var j=this,k=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){d.select_datasets(select_datasets_url,add_track_async_url,{"f-dbkey":view.dbkey},function(l){c.each(l,function(m){view.add_drawable(a(m,view,view))})})}},{icon_class:"block--plus",title:"Add group",on_click:function(){view.add_drawable(new b.DrawableGroup(view,view,{name:"New Group"}))}},{icon_class:"bookmarks",title:"Bookmarks",on_click:function(){parent.force_right_panel(($("div#right").css("right")=="0px"?"hide":"show"))}},{icon_class:"globe",title:"Circster",on_click:function(){window.location=j.baseURL+"visualization/circster?id="+view.vis_id}},{icon_class:"disk--arrow",title:"Save",on_click:function(){show_modal("Saving...","progress");var l=[];$(".bookmark").each(function(){l.push({position:$(this).children(".position").text(),annotation:$(this).children(".annotation").text()})});var m=(view.overview_drawable?view.overview_drawable.name:null),n={view:view.to_dict(),viewport:{chrom:view.chrom,start:view.low,end:view.high,overview:m},bookmarks:l};$.ajax({url:galaxy_paths.get("visualization_url"),type:"POST",dataType:"json",data:{id:view.vis_id,title:view.name,dbkey:view.dbkey,type:"trackster",vis_json:JSON.stringify(n)}}).success(function(o){hide_modal();view.vis_id=o.vis_id;view.has_changes=false;window.history.pushState({},"",o.url+window.location.hash)}).error(function(){show_modal("Could Not Save","Could not save visualization. Please try again later.",{Close:hide_modal})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=j.baseURL+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});this.buttonMenu=k;return k},add_bookmarks:function(){var j=this,k=this.baseURL;show_modal("Select dataset for new bookmarks","progress");$.ajax({url:this.baseURL+"/visualization/list_histories",data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(l){show_modal("Select dataset for new bookmarks",l,{Cancel:function(){hide_modal()},Insert:function(){$("input[name=id]:checked,input[name=ldda_ids]:checked").first().each(function(){var m,n=$(this).val();if($(this).attr("name")==="id"){m={hda_id:n}}else{m={ldda_id:n}}$.ajax({url:this.baseURL+"/visualization/bookmarks_from_dataset",data:m,dataType:"json"}).then(function(o){for(i=0;i<o.data.length;i++){var p=o.data[i];j.add_bookmark(p[0],p[1])}})});hide_modal()}})}})},add_bookmark:function(n,l,j){var p=$("#bookmarks-container"),r=$("<div/>").addClass("bookmark").appendTo(p);var s=$("<div/>").addClass("position").appendTo(r),o=$("<a href=''/>").text(n).appendTo(s).click(function(){view.go_to(n);return false}),m=$("<div/>").text(l).appendTo(r);if(j){var q=$("<div/>").addClass("delete-icon-container").prependTo(r).click(function(){r.slideUp("fast");r.remove();view.has_changes=true;return false}),k=$("<a href=''/>").addClass("icon-button delete").appendTo(q);m.make_text_editable({num_rows:3,use_textarea:true,help_text:"Edit bookmark note"}).addClass("annotation")}view.has_changes=true;return r},create_visualization:function(o,j,n,p,m){var l=this,k=new b.TracksterView(o);k.editor=true;$.when(k.load_chroms_deferred).then(function(A){if(j){var y=j.chrom,q=j.start,v=j.end,s=j.overview;if(y&&(q!==undefined)&&v){k.change_chrom(y,q,v)}else{k.change_chrom(A[0].chrom)}}else{k.change_chrom(A[0].chrom)}if(n){var t,r,u;for(var w=0;w<n.length;w++){k.add_drawable(a(n[w],k,k))}}k.update_intro_div();var z;for(var w=0;w<k.drawables.length;w++){if(k.drawables[w].name===s){k.set_overview(k.drawables[w]);break}}if(p){var x;for(var w=0;w<p.length;w++){x=p[w];l.add_bookmark(x.position,x.annotation,m)}}k.has_changes=false});return k},init_keyboard_nav:function(j){$(document).keydown(function(k){if($(k.srcElement).is(":input")){return}switch(k.which){case 37:j.move_fraction(0.25);break;case 38:var l=Math.round(j.viewport_container.height()/15);j.viewport_container.scrollTop(j.viewport_container.scrollTop()-20);break;case 39:j.move_fraction(-0.25);break;case 40:var l=Math.round(j.viewport_container.height()/15);j.viewport_container.scrollTop(j.viewport_container.scrollTop()+20);break}})}});return{object_from_template:a,TracksterUI:f}});
define(["base","libs/underscore","viz/trackster/slotting","viz/trackster/painters","viz/trackster/tracks","viz/visualization"],function(a,f,e,c,d,h){var j=d.object_from_template;var b=function(l,k){if(!k){k={}}var m=new IconButtonCollection(f.map(l,function(n){return new IconButton(f.extend(n,k))}));return new IconButtonMenuView({collection:m})};var g=a.Base.extend({initialize:function(k){this.baseURL=k},createButtonMenu:function(){var k=this,l=b([{icon_class:"plus-button",title:"Add tracks",on_click:function(){h.select_datasets(config.url.select_datasets,config.url.datasets,{"f-dbkey":view.dbkey},function(m){f.each(m,function(n){view.add_drawable(j(n,view,view))})})}},{icon_class:"block--plus",title:"Add group",on_click:function(){view.add_drawable(new d.DrawableGroup(view,view,{name:"New Group"}))}},{icon_class:"bookmarks",title:"Bookmarks",on_click:function(){force_right_panel(($("div#right").css("right")=="0px"?"hide":"show"))}},{icon_class:"globe",title:"Circster",on_click:function(){window.location=k.baseURL+"visualization/circster?id="+view.vis_id}},{icon_class:"disk--arrow",title:"Save",on_click:function(){show_modal("Saving...","progress");var m=[];$(".bookmark").each(function(){m.push({position:$(this).children(".position").text(),annotation:$(this).children(".annotation").text()})});var n=(view.overview_drawable?view.overview_drawable.name:null),o={view:view.to_dict(),viewport:{chrom:view.chrom,start:view.low,end:view.high,overview:n},bookmarks:m};$.ajax({url:config.url.visualization,type:"POST",dataType:"json",data:{id:view.vis_id,title:view.name,dbkey:view.dbkey,type:"trackster",vis_json:JSON.stringify(o)}}).success(function(p){hide_modal();view.vis_id=p.vis_id;view.has_changes=false;window.history.pushState({},"",p.url+window.location.hash)}).error(function(){show_modal("Could Not Save","Could not save visualization. Please try again later.",{Close:hide_modal})})}}],{tooltip_config:{placement:"bottom"}});this.buttonMenu=l;return l},add_bookmarks:function(){var k=this,l=this.baseURL;show_modal("Select dataset for new bookmarks","progress");$.ajax({url:this.baseURL+"/visualization/list_histories",data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(m){show_modal("Select dataset for new bookmarks",m,{Cancel:function(){hide_modal()},Insert:function(){$("input[name=id]:checked,input[name=ldda_ids]:checked").first().each(function(){var n,o=$(this).val();if($(this).attr("name")==="id"){n={hda_id:o}}else{n={ldda_id:o}}$.ajax({url:this.baseURL+"/visualization/bookmarks_from_dataset",data:n,dataType:"json"}).then(function(p){for(i=0;i<p.data.length;i++){var q=p.data[i];k.add_bookmark(q[0],q[1])}})});hide_modal()}})}})},add_bookmark:function(o,m,k){var q=$("#bookmarks-container"),s=$("<div/>").addClass("bookmark").appendTo(q);var t=$("<div/>").addClass("position").appendTo(s),p=$("<a href=''/>").text(o).appendTo(t).click(function(){view.go_to(o);return false}),n=$("<div/>").text(m).appendTo(s);if(k){var r=$("<div/>").addClass("delete-icon-container").prependTo(s).click(function(){s.slideUp("fast");s.remove();view.has_changes=true;return false}),l=$("<a href=''/>").addClass("icon-button delete").appendTo(r);n.make_text_editable({num_rows:3,use_textarea:true,help_text:"Edit bookmark note"}).addClass("annotation")}view.has_changes=true;return s},create_visualization:function(p,k,o,q,n){var m=this,l=new d.TracksterView(p);l.editor=true;$.when(l.load_chroms_deferred).then(function(B){if(k){var z=k.chrom,r=k.start,w=k.end,t=k.overview;if(z&&(r!==undefined)&&w){l.change_chrom(z,r,w)}else{l.change_chrom(B[0].chrom)}}else{l.change_chrom(B[0].chrom)}if(o){var u,s,v;for(var x=0;x<o.length;x++){l.add_drawable(j(o[x],l,l))}}l.update_intro_div();var A;for(var x=0;x<l.drawables.length;x++){if(l.drawables[x].name===t){l.set_overview(l.drawables[x]);break}}if(q){var y;for(var x=0;x<q.length;x++){y=q[x];m.add_bookmark(y.position,y.annotation,n)}}l.has_changes=false});return l},init_keyboard_nav:function(k){$(document).keydown(function(l){if($(l.srcElement).is(":input")){return}switch(l.which){case 37:k.move_fraction(0.25);break;case 38:var m=Math.round(k.viewport_container.height()/15);k.viewport_container.scrollTop(k.viewport_container.scrollTop()-20);break;case 39:k.move_fraction(-0.25);break;case 40:var m=Math.round(k.viewport_container.height()/15);k.viewport_container.scrollTop(k.viewport_container.scrollTop()+20);break}})}});return{object_from_template:j,TracksterUI:g}});
@@ -28,36 +28,6 @@ Handlebars.registerHelper( 'local', function( options ){
<div class="warningmessagesmall"><strong>{{{ warning }}}</strong></div>
</script>
<script type="text/javascript" class="helper-common" id="helper-iconButton">
/** Renders a glx style icon-button (see IconButton in mvc/ui.js)
* can be used in either of the following ways:
* within a template: {{> iconButton buttonData}}
* from js: var templated = ( Handlebars.partials.iconButton( buttonData ) );
*/
Handlebars.registerPartial( 'iconButton', function( buttonData, options ){
var buffer = "";
buffer += ( buttonData.enabled )?( '<a' ):( '<span' );
if( buttonData.title ){ buffer += ' title="' + buttonData.title + '"'; }
buffer += ' class="icon-button';
if( buttonData.isMenuButton ){ buffer += ' menu-button'; }
if( buttonData.title ){ buffer += ' tooltip'; }
buffer += ' ' + buttonData.icon_class;
if( !buttonData.enabled ){ buffer += '_disabled'; }
buffer += '"';
if( buttonData.id ){ buffer += ' id="' + buttonData.id + '"'; }
buffer += ' href="' + ( ( buttonData.href )?( buttonData.href ):( 'javascript:void(0);' ) ) + '"';
if( buttonData.target ){ buffer += ' target="' + buttonData.target + '"'; }
if( !buttonData.visible ){ buffer += ' style="display: none;"'; }
buffer += '>' + ( ( buttonData.enabled )?( '</a>' ):( '</span>' ) );
return buffer;
});
</script>
<script type="text/template" class="template-common" id="template-iconButton">
{{! alternate template-based icon-button }}
{{> iconButton this}}
@@ -1,25 +1,24 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['panel_section'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, self=this, functionType="function", helperMissing=helpers.helperMissing, undef=void 0, escapeExpression=this.escapeExpression;
this.compilerInfo = [2,'>= 1.0.0-rc.3'];
helpers = helpers || Handlebars.helpers; data = data || {};
var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression;
buffer += "<div class=\"toolSectionTitle\" id=\"title_";
foundHelper = helpers.id;
stack1 = foundHelper || depth0.id;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "id", { hash: {} }); }
buffer += escapeExpression(stack1) + "\">\n <a href=\"javascript:void(0)\"><span>";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "</span></a>\n</div>\n<div id=\"";
foundHelper = helpers.id;
stack1 = foundHelper || depth0.id;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "id", { hash: {} }); }
buffer += escapeExpression(stack1) + "\" class=\"toolSectionBody\" style=\"display: none; \">\n <div class=\"toolSectionBg\"></div>\n<div>";
return buffer;});
if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\">\n <a href=\"javascript:void(0)\"><span>";
if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "</span></a>\n</div>\n<div id=\"";
if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\" class=\"toolSectionBody\" style=\"display: none; \">\n <div class=\"toolSectionBg\"></div>\n<div>";
return buffer;
});
})();
+34 -46
View File
@@ -1,61 +1,49 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['tool_form'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, stack2, foundHelper, tmp1, self=this, functionType="function", helperMissing=helpers.helperMissing, undef=void 0, escapeExpression=this.escapeExpression;
this.compilerInfo = [2,'>= 1.0.0-rc.3'];
helpers = helpers || Handlebars.helpers; data = data || {};
var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this;
function program1(depth0,data) {
var buffer = "", stack1;
buffer += "\n <div class=\"form-row\">\n <label for=\"";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "\">";
foundHelper = helpers.label;
stack1 = foundHelper || depth0.label;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "label", { hash: {} }); }
buffer += escapeExpression(stack1) + ":</label>\n <div class=\"form-row-input\">\n ";
foundHelper = helpers.html;
stack1 = foundHelper || depth0.html;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "html", { hash: {} }); }
if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\">";
if (stack1 = helpers.label) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.label; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ ":</label>\n <div class=\"form-row-input\">\n ";
if (stack1 = helpers.html) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.html; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n </div>\n <div class=\"toolParamHelp\" style=\"clear: both;\">\n ";
foundHelper = helpers.help;
stack1 = foundHelper || depth0.help;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "help", { hash: {} }); }
buffer += escapeExpression(stack1) + "\n </div>\n <div style=\"clear: both;\"></div>\n </div>\n ";
return buffer;}
if (stack1 = helpers.help) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.help; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\n </div>\n <div style=\"clear: both;\"></div>\n </div>\n ";
return buffer;
}
buffer += "<div class=\"toolFormTitle\">";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + " (version ";
foundHelper = helpers.version;
stack1 = foundHelper || depth0.version;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "version", { hash: {} }); }
buffer += escapeExpression(stack1) + ")</div>\n <div class=\"toolFormBody\">\n ";
foundHelper = helpers.inputs;
stack1 = foundHelper || depth0.inputs;
stack2 = helpers.each;
tmp1 = self.program(1, program1, data);
tmp1.hash = {};
tmp1.fn = tmp1;
tmp1.inverse = self.noop;
stack1 = stack2.call(depth0, stack1, tmp1);
if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ " (version ";
if (stack1 = helpers.version) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.version; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ ")</div>\n <div class=\"toolFormBody\">\n ";
stack1 = helpers.each.call(depth0, depth0.inputs, {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
if(stack1 || stack1 === 0) { buffer += stack1; }
buffer += "\n </div>\n <div class=\"form-row form-actions\">\n <input type=\"submit\" class=\"btn btn-primary\" name=\"runtool_btn\" value=\"Execute\">\n</div>\n<div class=\"toolHelp\">\n <div class=\"toolHelpBody\">";
foundHelper = helpers.help;
stack1 = foundHelper || depth0.help;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "help", { hash: {} }); }
buffer += escapeExpression(stack1) + "</div>\n</div>";
return buffer;});
if (stack1 = helpers.help) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.help; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "</div>\n</div>";
return buffer;
});
})();
+27 -32
View File
@@ -1,40 +1,35 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['tool_link'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, self=this, functionType="function", helperMissing=helpers.helperMissing, undef=void 0, escapeExpression=this.escapeExpression;
this.compilerInfo = [2,'>= 1.0.0-rc.3'];
helpers = helpers || Handlebars.helpers; data = data || {};
var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression;
buffer += "<a class=\"";
foundHelper = helpers.id;
stack1 = foundHelper || depth0.id;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "id", { hash: {} }); }
buffer += escapeExpression(stack1) + " tool-link\" href=\"";
foundHelper = helpers.link;
stack1 = foundHelper || depth0.link;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "link", { hash: {} }); }
buffer += escapeExpression(stack1) + "\" target=\"";
foundHelper = helpers.target;
stack1 = foundHelper || depth0.target;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "target", { hash: {} }); }
buffer += escapeExpression(stack1) + "\" minsizehint=\"";
foundHelper = helpers.min_width;
stack1 = foundHelper || depth0.min_width;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "min_width", { hash: {} }); }
buffer += escapeExpression(stack1) + "\">";
foundHelper = helpers.name;
stack1 = foundHelper || depth0.name;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "name", { hash: {} }); }
buffer += escapeExpression(stack1) + "</a> ";
foundHelper = helpers.description;
stack1 = foundHelper || depth0.description;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "description", { hash: {} }); }
if (stack1 = helpers.id) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.id; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ " tool-link\" href=\"";
if (stack1 = helpers.link) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.link; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\" target=\"";
if (stack1 = helpers.target) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.target; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\" minsizehint=\"";
if (stack1 = helpers.min_width) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.min_width; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\">";
if (stack1 = helpers.name) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.name; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "</a> ";
if (stack1 = helpers.description) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.description; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1);
return buffer;});
return buffer;
});
})();
@@ -1,20 +1,20 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['tool_search'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", stack1, foundHelper, self=this, functionType="function", helperMissing=helpers.helperMissing, undef=void 0, escapeExpression=this.escapeExpression;
this.compilerInfo = [2,'>= 1.0.0-rc.3'];
helpers = helpers || Handlebars.helpers; data = data || {};
var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression;
buffer += "<input type=\"text\" name=\"query\" value=\"";
foundHelper = helpers.search_hint_string;
stack1 = foundHelper || depth0.search_hint_string;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "search_hint_string", { hash: {} }); }
buffer += escapeExpression(stack1) + "\" id=\"tool-search-query\" autocomplete=\"off\" class=\"search-query parent-width\" />\n<a id=\"search-clear-btn\" class=\"tooltip\" title=\"clear search (esc)\"> </a>\n<img src=\"";
foundHelper = helpers.spinner_url;
stack1 = foundHelper || depth0.spinner_url;
if(typeof stack1 === functionType) { stack1 = stack1.call(depth0, { hash: {} }); }
else if(stack1=== undef) { stack1 = helperMissing.call(depth0, "spinner_url", { hash: {} }); }
buffer += escapeExpression(stack1) + "\" id=\"search-spinner\" class=\"search-spinner\"/>";
return buffer;});
if (stack1 = helpers.search_hint_string) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.search_hint_string; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\" id=\"tool-search-query\" autocomplete=\"off\" class=\"search-query parent-width\" />\n<a id=\"search-clear-btn\" class=\"tooltip\" title=\"clear search (esc)\"> </a>\n<img src=\"";
if (stack1 = helpers.spinner_url) { stack1 = stack1.call(depth0, {hash:{},data:data}); }
else { stack1 = depth0.spinner_url; stack1 = typeof stack1 === functionType ? stack1.apply(depth0) : stack1; }
buffer += escapeExpression(stack1)
+ "\" id=\"search-spinner\" class=\"search-spinner\"/>";
return buffer;
});
})();
+87 -3
View File
@@ -236,7 +236,7 @@ var CircsterView = Backbone.View.extend({
// -- Render circular tracks. --
// Create a view for each track in the visualiation and render.
// Create a view for each track in the visualization and render.
this.circular_views = circular_tracks.map(function(track, index) {
var view = new CircsterBigWigTrackView({
el: svg.append('g')[0],
@@ -250,7 +250,7 @@ var CircsterView = Backbone.View.extend({
return view;
});
// -- Render chords tracks. --
this.chords_views = chords_tracks.map(function(track) {
@@ -950,9 +950,93 @@ var CircsterChromInteractionsTrackView = CircsterTrackView.extend({
});
// circster app loader
var Circster = Backbone.View.extend(
{
initialize: function ()
{
// configure visualization
var genome = new visualization.Genome(config.app.genome),
vis = new visualization.GenomeVisualization(config.app.viz_config),
viz_view = new CircsterView(
{
// view pane
el : $('#center .unified-panel-body'),
// gaps are difficult to set because it very dependent on chromosome size and organization.
total_gap : 2 * Math.PI * 0.1,
genome : genome,
model : vis,
dataset_arc_height : 25
});
// render vizualization
viz_view.render();
// setup title
$('#center .unified-panel-header-inner').append(config.app.viz_config.title + " " + config.app.viz_config.dbkey);
// setup menu
var menu = create_icon_buttons_menu([
{ icon_class: 'plus-button', title: 'Add tracks', on_click: function()
{
visualization.select_datasets(config.root + "visualization/list_current_history_datasets", config.root + "api/datasets", vis.get('dbkey'), function(tracks)
{
vis.add_tracks(tracks);
});
}
},{
icon_class: 'disk--arrow', title: 'Save', on_click: function()
{
// show saving dialog box
show_modal("Saving...", "progress");
// link configuration
var view = config.app.viz_config;
// send to server
$.ajax({
url: config.root + "visualization/save",
type: "POST",
dataType: "json",
data: {
'id' : view.vis_id,
'title' : view.title,
'dbkey' : view.dbkey,
'type' : 'trackster',
'vis_json' : JSON.stringify(view)
}
}).success(function(vis_info) {
hide_modal();
view.vis_id = vis_info.vis_id;
view.has_changes = false;
// needed to set URL when first saving a visualization
window.history.pushState({}, "", vis_info.url + window.location.hash);
})
.error(function() {
show_modal( "Could Not Save", "Could not save visualization. Please try again later.", { "Close" : hide_modal } );
});
}
},{
icon_class: 'cross-circle', title: 'Close', on_click: function()
{
window.location = config.root + "visualization/list";
}
}], { tooltip_config: { placement: 'bottom' } });
// add menu
menu.$el.attr("style", "float: right");
$("#center .unified-panel-header-inner").append(menu.$el);
// manual tooltip config because default gravity is S and cannot be changed
$(".menu-button").tooltip( { placement: 'bottom' } );
}
});
// Module exports.
return {
CircsterView: CircsterView
GalaxyApp: Circster
};
});
+195 -3
View File
@@ -1,5 +1,197 @@
define( ["libs/underscore","viz/trackster/slotting", "viz/trackster/painters","viz/trackster/tracks"], function( _, slotting, painters, tracks ) {
// Nothing?
// global variables
var ui = null;
var view = null;
var browser_router = null;
// load required libraries
require(
[
// load js libraries
'utils/galaxy.css',
'libs/jquery/jstorage',
'libs/jquery/jquery.event.drag',
'libs/jquery/jquery.event.hover',
'libs/jquery/jquery.mousewheel',
'libs/jquery/jquery-ui',
'libs/jquery/jquery-ui-combobox',
'libs/farbtastic',
'libs/jquery/jquery.form',
'libs/jquery/jquery.rating',
'mvc/ui'
], function(css)
{
// load css
css.load_file("/static/style/jquery.rating.css");
css.load_file("/static/style/history.css");
css.load_file("/static/style/autocomplete_tagging.css");
css.load_file("/static/style/jquery-ui/smoothness/jquery-ui.css");
css.load_file("/static/style/library.css");
css.load_file("/static/style/trackster.css");
});
// trackster viewer
define( ["libs/backbone/backbone-relational", "viz/visualization", "viz/trackster_ui"],
function(backbone, visualization, trackster_ui)
{
var TracksterView = Backbone.View.extend(
{
// initalize trackster
initialize : function ()
{
// load ui
ui = new trackster_ui.TracksterUI(config.root);
// create button menu
ui.createButtonMenu();
// attach the button menu to the panel header and float it left
ui.buttonMenu.$el.attr("style", "float: right");
// add to center panel
$("#center .unified-panel-header-inner").append(ui.buttonMenu.$el);
// configure right panel
$("#right .unified-panel-title").append("Bookmarks");
$("#right .unified-panel-icons").append("<a id='add-bookmark-button' class='icon-button menu-button plus-button' href='javascript:void(0);' title='Add bookmark'></a>");
// resize view when showing/hiding right panel (bookmarks for now).
$("#right-border").click(function() { view.resize_window(); });
// hide right panel
force_right_panel("hide");
// check if id is available
if (config.app.id)
this.view_existing();
else
this.view_new();
},
// set up router
set_up_router : function(options)
{
browser_router = new visualization.TrackBrowserRouter(options);
Backbone.history.start();
},
// view
view_existing : function ()
{
// get config
var viz_config = config.app.viz_config;
// view
view = ui.create_visualization(
{
container: $("#center .unified-panel-body"),
name: viz_config.title,
vis_id: viz_config.vis_id,
dbkey: viz_config.dbkey
}, viz_config.viewport, viz_config.tracks, viz_config.bookmarks, true);
// initialize editor
this.init_editor();
},
// view
view_new : function ()
{
// availability of default database key
/*if (config.app.default_dbkey !== undefined)
{
this.create_browser("Unnamed", config.app.default_dbkey);
return;
}*/
// reference this
var self = this;
// ajax
$.ajax(
{
url: config.app.new_browser,
data: {},
error: function() { alert( "Couldn't create new browser." ); },
success: function(form_html)
{
show_modal("New Visualization", form_html,
{
"Cancel": function() { window.location = config.root + "visualization/list"; },
"Create": function() { self.create_browser($("#new-title").val(), $("#new-dbkey").val()); }
});
$("#new-title").focus();
$("select[name='dbkey']").combobox(
{
appendTo: $("#overlay"),
size: 40
});
// to support the large number of options for dbkey, enable scrolling in overlay.
$("#overlay").css("overflow", "auto");
}
});
},
// create
create_browser : function(name, dbkey)
{
$(document).trigger("convert_to_values");
view = ui.create_visualization (
{
container: $("#center .unified-panel-body"),
name: name,
dbkey: dbkey
}, config.app.gene_region);
// initialize editor
this.init_editor();
// modify view setting
view.editor = true;
// hide modal dialog
hide_modal();
},
// initialization for editor-specific functions.
init_editor : function ()
{
// set title
$("#center .unified-panel-title").text(view.name + " (" + view.dbkey + ")");
// add dataset
if (config.app.add_dataset)
$.ajax({
url: config.root + "api/datasets/" + config.app.add_dataset,
data: { hda_ldda: 'hda', data_type: 'track_config' },
dataType: "json",
success: function(track_data) { view.add_drawable( trackster_ui.object_from_template(track_data, view, view) ); }
});
// initialize icons
$("#add-bookmark-button").click(function()
{
// add new bookmark.
var position = view.chrom + ":" + view.low + "-" + view.high,
annotation = "Bookmark description";
return ui.add_bookmark(position, annotation, true);
});
// initialize keyboard
ui.init_keyboard_nav(view);
// set up router
this.set_up_router({view: view});
}
});
// return
return {
GalaxyApp : TracksterView
};
// done
});
+11 -11
View File
@@ -254,7 +254,7 @@ var Drawable = function(view, container, obj_dict) {
this.container_div.hover(
function() { drawable.icons_div.show(); }, function() { drawable.icons_div.hide(); }
);
// Needed for floating elts in header.
$("<div style='clear: both'/>").appendTo(this.container_div);
}
@@ -951,7 +951,7 @@ var TracksterView = Backbone.View.extend({
// Introduction div shown when there are no tracks.
this.intro_div = $("<div/>").addClass("intro").appendTo(this.viewport_container).hide();
var add_tracks_button = $("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function () {
visualization.select_datasets(select_datasets_url, add_track_async_url, { 'f-dbkey': view.dbkey }, function(tracks) {
visualization.select_datasets(config.root + "/visualization/list_current_history_datasets", config.root + "/api/datasets", { 'f-dbkey': view.dbkey }, function(tracks) {
_.each(tracks, function(track) {
view.add_drawable( object_from_template(track, view, view) );
});
@@ -1215,11 +1215,11 @@ extend( TracksterView.prototype, DrawableCollection.prototype, {
load_chroms: function(url_parms) {
url_parms.num = MAX_CHROMS_SELECTABLE;
var
var
view = this,
chrom_data = $.Deferred();
$.ajax({
url: chrom_url + "/" + this.dbkey,
url: config.root + "api/genomes/" + this.dbkey,
data: url_parms,
dataType: "json",
success: function (result) {
@@ -1253,7 +1253,6 @@ extend( TracksterView.prototype, DrawableCollection.prototype, {
alert("Could not load chroms for this dbkey:", view.dbkey);
}
});
return chrom_data;
},
@@ -1857,7 +1856,7 @@ extend(Tool.prototype, {
url_params.inputs = this.get_param_values_dict();
var ss_deferred = new util.ServerStateDeferred({
ajax_settings: {
url: galaxy_paths.get('tool_url'),
url: config.root + "/api/tools",
data: JSON.stringify(url_params),
dataType: "json",
contentType: 'application/json',
@@ -2237,10 +2236,12 @@ FeatureTrackTile.prototype.predisplay_actions = function() {
// Only show popups in Pack mode.
if (tile.mode !== "Pack") { return; }
$(this.html_elt).hover( function() {
$(this.html_elt).hover(
function() {
this.hovered = true;
$(this).mousemove();
}, function() {
},
function() {
this.hovered = false;
// Clear popup if it is still hanging around (this is probably not needed)
$(this).parents(".track-content").children(".overlay").children(".feature-popup").remove();
@@ -2284,7 +2285,6 @@ FeatureTrackTile.prototype.predisplay_actions = function() {
}
// Build popup.
var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"),
table = $("<table/>"),
key, value, row;
@@ -2490,7 +2490,7 @@ extend(Track.prototype, Drawable.prototype, {
// Go to visualization.
window.location.href =
galaxy_paths.get('sweepster_url') + "?" +
config.root + "visualization/sweepster" + "?" +
$.param({
dataset_id: track.dataset.id,
hda_ldda: track.dataset.get('hda_ldda'),
@@ -3757,7 +3757,7 @@ var ReferenceTrack = function (view) {
this.content_div.css("background", "none");
this.content_div.css("min-height", "0px");
this.content_div.css("border", "none");
this.data_url = reference_url + "/" + this.view.dbkey;
this.data_url = config.root + "api/genomes/" + "/" + this.view.dbkey;
this.data_url_extra_params = {reference: true};
this.data_manager = new visualization.GenomeReferenceDataManager({
data_url: this.data_url,
+31 -14
View File
@@ -7,6 +7,27 @@ define( ["base","libs/underscore","viz/trackster/slotting", "viz/trackster/paint
var object_from_template = tracks.object_from_template;
/**
* Returns an IconButtonMenuView for the provided configuration.
* Configuration is a list of dictionaries where each dictionary
* defines an icon button. Each dictionary must have the following
* elements: icon_class, title, and on_click.
*/
var create_icon_buttons_menu = function(config, global_config) {
if (!global_config) { global_config = {}; }
// Create and initialize menu.
var buttons = new IconButtonCollection(
_.map(config, function(button_config) {
return new IconButton(_.extend(button_config, global_config));
})
);
return new IconButtonMenuView( {collection: buttons} );
};
var TracksterUI = base.Base.extend({
initialize: function( baseURL ) {
@@ -20,7 +41,7 @@ var TracksterUI = base.Base.extend({
var self = this,
menu = create_icon_buttons_menu([
{ icon_class: 'plus-button', title: 'Add tracks', on_click: function() {
visualization.select_datasets(select_datasets_url, add_track_async_url, { 'f-dbkey': view.dbkey }, function(tracks) {
visualization.select_datasets(config.root + "visualization/list_current_history_datasets", config.root + "api/datasets", { 'f-dbkey': view.dbkey }, function(tracks) {
_.each(tracks, function(track) {
view.add_drawable( object_from_template(track, view, view) );
});
@@ -31,7 +52,7 @@ var TracksterUI = base.Base.extend({
} },
{ icon_class: 'bookmarks', title: 'Bookmarks', on_click: function() {
// HACK -- use style to determine if panel is hidden and hide/show accordingly.
parent.force_right_panel(($("div#right").css("right") == "0px" ? "hide" : "show"));
force_right_panel(($("div#right").css("right") == "0px" ? "hide" : "show"));
} },
{
icon_class: 'globe',
@@ -62,15 +83,15 @@ var TracksterUI = base.Base.extend({
};
$.ajax({
url: galaxy_paths.get("visualization_url"),
url: config.root + "visualization/save",
type: "POST",
dataType: "json",
data: {
'id': view.vis_id,
'title': view.name,
'dbkey': view.dbkey,
'type': 'trackster',
vis_json: JSON.stringify(viz_config)
'id' : view.vis_id,
'title' : view.name,
'dbkey' : view.dbkey,
'type' : 'trackster',
'vis_json' : JSON.stringify(viz_config)
}
}).success(function(vis_info) {
hide_modal();
@@ -81,12 +102,8 @@ var TracksterUI = base.Base.extend({
window.history.pushState({}, "", vis_info.url + window.location.hash);
})
.error(function() {
show_modal( "Could Not Save", "Could not save visualization. Please try again later.",
{ "Close" : hide_modal } );
show_modal( "Could Not Save", "Could not save visualization. Please try again later.", { "Close" : hide_modal } );
});
} },
{ icon_class: 'cross-circle', title: 'Close', on_click: function() {
window.location = self.baseURL + "visualization/list";
} }
],
{
@@ -148,7 +165,7 @@ var TracksterUI = base.Base.extend({
*/
add_bookmark: function(position, annotation, editable) {
// Create HTML.
var bookmarks_container = $("#bookmarks-container"),
var bookmarks_container = $("#right .unified-panel-body"),
new_bookmark = $("<div/>").addClass("bookmark").appendTo(bookmarks_container);
var position_div = $("<div/>").addClass("position").appendTo(new_bookmark),
+3 -21
View File
@@ -79,28 +79,10 @@
}
};
## check if its in a galaxy iframe
function is_in_galaxy_frame()
{
var iframes = parent.document.getElementsByTagName("iframe");
for (var i=0, len=iframes.length; i < len; ++i)
if (document == iframes[i].contentDocument || self == iframes[i].contentWindow)
return $(iframes[i]).hasClass('f-iframe');
return false;
};
## load css
function load_css (url)
{
## check if css is already available
if (!$('link[href="' + url + '"]').length)
$('<link href="' + url + '" rel="stylesheet">').appendTo('head');
};
## load additional style sheet
if (is_in_galaxy_frame())
load_css(galaxy_config.url.styles + '/galaxy.frame.masthead.css');
if (window != window.top)
$('<link href="' + galaxy_config.url.styles + '/galaxy.frame.masthead.css" rel="stylesheet">').appendTo('head');
// console protection
window.console = window.console || {
log : function(){},
@@ -0,0 +1,253 @@
## get user data
<%def name="get_user_json()">
<%
"""Bootstrapping user API JSON"""
#TODO: move into common location (poss. BaseController)
if trans.user:
user_dict = trans.user.get_api_value( view='element', value_mapper={ 'id': trans.security.encode_id,
'total_disk_usage': float } )
user_dict['quota_percent'] = trans.app.quota_agent.get_percent( trans=trans )
else:
usage = 0
percent = None
try:
usage = trans.app.quota_agent.get_usage( trans, history=trans.history )
percent = trans.app.quota_agent.get_percent( trans=trans, usage=usage )
except AssertionError, assertion:
# no history for quota_agent.get_usage assertion
pass
user_dict = {
'total_disk_usage' : int( usage ),
'nice_total_disk_usage' : util.nice_size( usage ),
'quota_percent' : percent
}
%>
${h.to_json_string( user_dict )}
</%def>
## master head generator
<%def name="load()">
## load the frame manager
<script type="text/javascript">
## path to style sheets
var galaxy_config = {
url: {
styles : "${h.url_for('/static/style')}"
}
};
## load additional style sheet
if (window != window.top)
$('<link href="' + galaxy_config.url.styles + '/galaxy.frame.masthead.css" rel="stylesheet">').appendTo('head');
## frame manager
var frame_manager = null;
require(['galaxy.frame'], function(frame) { this.frame_manager = new frame.GalaxyFrameManager(galaxy_config); });
</script>
## start main tag
<div id="masthead" class="navbar navbar-fixed-top">
<div class="masthead-inner navbar-inner">
## Tab area, fills entire width
<div style="position: relative; right: -50%; float: left;">
<div style="display: block; position: relative; right: 50%;">
<ul class="nav" border="0" cellspacing="0">
<%def name="tab( id, display, href, target='_parent', visible=True, extra_class='', menu_options=None )">
## Create a tab at the top of the panels. menu_options is a list of 2-elements lists of [name, link]
## that are options in the menu.
<%
cls = ""
a_cls = ""
extra = ""
if extra_class:
cls += " " + extra_class
##if self.active_view == id:
## cls += " active"
if menu_options:
cls += " dropdown"
a_cls += " dropdown-toggle"
extra = "<b class='caret'></b>"
style = ""
if not visible:
style = "display: none;"
%>
<li class="${cls}" style="${style}">
%if href:
<a class="${a_cls}" data-toggle="dropdown" target="${target}" href="${href}">${display}${extra}</a>
%else:
<a class="${a_cls}" data-toggle="dropdown">${display}${extra}</a>
%endif
%if menu_options:
<ul class="dropdown-menu">
%for menu_item in menu_options:
%if not menu_item:
<li class="divider"></li>
%else:
<li>
%if len ( menu_item ) == 1:
${menu_item[0]}
%elif len ( menu_item ) == 2:
<% name, link = menu_item %>
<a href="${link}">${name}</a>
%else:
<% name, link, target = menu_item %>
<a target="${target}" href="${link}">${name}</a>
%endif
</li>
%endif
%endfor
</ul>
%endif
</li>
</%def>
## Analyze data tab.
${tab( "analysis", _("Analyze Data"), h.url_for( controller='/root', action='index' ) )}
## Workflow tab.
${tab( "workflow", _("Workflow"), "javascript:frame_manager.frame_new({title: 'Workflow', type: 'url', content: '" + h.url_for( controller='/workflow', action='index' ) + "'});")}
## 'Shared Items' or Libraries tab.
<%
menu_options = [
[ _('Data Libraries'), h.url_for( controller='/library', action='index') ],
None,
[ _('Published Histories'), h.url_for( controller='/history', action='list_published' ) ],
[ _('Published Workflows'), h.url_for( controller='/workflow', action='list_published' ) ],
[ _('Published Visualizations'), h.url_for( controller='/visualization', action='list_published' ) ],
[ _('Published Pages'), h.url_for( controller='/page', action='list_published' ) ]
]
tab( "shared", _("Shared Data"), h.url_for( controller='/library', action='index'), menu_options=menu_options )
%>
## Lab menu.
<%
menu_options = [
[ _('Sequencing Requests'), h.url_for( controller='/requests', action='index' ) ],
[ _('Find Samples'), h.url_for( controller='/requests', action='find_samples_index' ) ],
[ _('Help'), app.config.get( "lims_doc_url", "http://main.g2.bx.psu.edu/u/rkchak/p/sts" ), "galaxy_main" ]
]
tab( "lab", "Lab", None, menu_options=menu_options, visible=( trans.user and ( trans.user.requests or trans.app.security_agent.get_accessible_request_types( trans, trans.user ) ) ) )
%>
## Visualization menu.
<%
menu_options = [
[_('New Track Browser'), "javascript:frame_manager.frame_new({title: 'Trackster', type: 'url', content: '" + h.url_for( controller='/visualization', action='trackster' ) + "'});"],
[_('Saved Visualizations'), "javascript:frame_manager.frame_new({ type: 'url', content : '" + h.url_for( controller='/visualization', action='list' ) + "'});" ]
]
tab( "visualization", _("Visualization"), "javascript:frame_manager.frame_new({title: 'Trackster', type: 'url', content: '" + h.url_for( controller='/visualization', action='list' ) + "'});", menu_options=menu_options )
%>
## Cloud menu.
%if app.config.get_bool( 'enable_cloud_launch', False ):
<%
menu_options = [
[_('New Cloud Cluster'), h.url_for( controller='/cloudlaunch', action='index' ) ],
]
tab( "cloud", _("Cloud"), h.url_for( controller='/cloudlaunch', action='index'), menu_options=menu_options )
%>
%endif
## Admin tab.
${tab( "admin", "Admin", h.url_for( controller='/admin', action='index' ), extra_class="admin-only", visible=( trans.user and app.config.is_admin_user( trans.user ) ) )}
## Help tab.
<%
menu_options = []
if app.config.biostar_url:
menu_options = [ [_('Galaxy Q&A Site'), h.url_for( controller='biostar', action='biostar_redirect', biostar_action='show/tag/galaxy' ), "_blank" ],
[_('Ask a question'), h.url_for( controller='biostar', action='biostar_question_redirect' ), "_blank" ] ]
menu_options.extend( [
[_('Support'), app.config.get( "support_url", "http://wiki.g2.bx.psu.edu/Support" ), "_blank" ],
[_('Tool shed wiki'), app.config.get( "wiki_url", "http://wiki.g2.bx.psu.edu/Tool%20Shed" ), "_blank" ],
[_('Galaxy wiki'), app.config.get( "wiki_url", "http://wiki.g2.bx.psu.edu/" ), "_blank" ],
[_('Video tutorials (screencasts)'), app.config.get( "screencasts_url", "http://galaxycast.org" ), "_blank" ],
[_('How to Cite Galaxy'), app.config.get( "citation_url", "http://wiki.g2.bx.psu.edu/Citing%20Galaxy" ), "_blank" ]
] )
if app.config.get( 'terms_url', None ) is not None:
menu_options.append( [_('Terms and Conditions'), app.config.get( 'terms_url', None ), '_blank'] )
tab( "help", _("Help"), None, menu_options=menu_options )
%>
## User tabs.
<%
# Menu for user who is not logged in.
menu_options = [ [ _("Login"), h.url_for( controller='/user', action='login' ), "galaxy_main" ] ]
if app.config.allow_user_creation:
menu_options.append( [ _("Register"), h.url_for( controller='/user', action='create', cntrller='user' ), "galaxy_main" ] )
extra_class = "loggedout-only"
visible = ( trans.user == None )
tab( "user", _("User"), None, visible=visible, menu_options=menu_options )
# Menu for user who is logged in.
if trans.user:
email = trans.user.email
else:
email = ""
menu_options = [ [ '<a>Logged in as <span id="user-email">%s</span></a>' % email ] ]
if app.config.use_remote_user:
if app.config.remote_user_logout_href:
menu_options.append( [ _('Logout'), app.config.remote_user_logout_href, "_top" ] )
else:
menu_options.append( [ _('Preferences'), h.url_for( controller='/user', action='index', cntrller='user' ), "galaxy_main" ] )
menu_options.append( [ 'Custom Builds', h.url_for( controller='/user', action='dbkeys' ), "galaxy_main" ] )
logout_url = h.url_for( controller='/user', action='logout' )
menu_options.append( [ 'Logout', logout_url, "_top" ] )
menu_options.append( None )
menu_options.append( [ _('Saved Histories'), h.url_for( controller='/history', action='list' ), "galaxy_main" ] )
menu_options.append( [ _('Saved Datasets'), h.url_for( controller='/dataset', action='list' ), "galaxy_main" ] )
menu_options.append( [ _('Saved Pages'), h.url_for( controller='/page', action='list' ), "_top" ] )
menu_options.append( [ _('API Keys'), h.url_for( controller='/user', action='api_keys', cntrller='user' ), "galaxy_main" ] )
if app.config.use_remote_user:
menu_options.append( [ _('Public Name'), h.url_for( controller='/user', action='edit_username', cntrller='user' ), "galaxy_main" ] )
extra_class = "loggedin-only"
visible = ( trans.user != None )
tab( "user", "User", None, visible=visible, menu_options=menu_options )
%>
</ul>
</div>
</div>
## Logo, layered over tabs to be clickable
<div class="title">
<a href="${h.url_for( app.config.get( 'logo_url', '/' ) )}">
<img border="0" src="${h.url_for('/static/images/galaxyIcon_noText.png')}">
Galaxy
%if app.config.brand:
<span>/ ${app.config.brand}</span>
%endif
</a>
</div>
<div class="quota-meter-container"></div>
## end main tag
</div>
</div>
<!-- quota meter -->
${h.templates( "helpers-common-templates", "template-user-quotaMeter-quota", "template-user-quotaMeter-usage" )}
${h.js( "mvc/base-mvc", "mvc/user/user-model", "mvc/user/user-quotameter" )}
<script type="text/javascript">
// start a Galaxy namespace for objects created
window.Galaxy = window.Galaxy || {};
// set up the quota meter (And fetch the current user data from trans)
Galaxy.currUser = new User( ${get_user_json()} );
Galaxy.quotaMeter = new UserQuotaMeter({
model : Galaxy.currUser,
el : $( document ).find( '.quota-meter-container' )
}).render();
</script>
</%def>
+280
View File
@@ -0,0 +1,280 @@
<%namespace name="masthead" file="/webapps/galaxy/galaxy.masthead.mako"/>
<!DOCTYPE HTML>
## inject parameters parsed by controller config dictionary
<%
## set defaults
self.galaxy_config = {
## template options
'title' : '',
'master' : True,
'left_panel' : False,
'right_panel' : False,
'message_box' : False,
'overlay' : False,
## root
'root' : h.url_for("/"),
## inject app specific configuration
'app' : config['app']
}
## update configuration
self.galaxy_config.update(config)
%>
<%def name="javascripts()">
## load jscript libraries
${h.js(
'libs/jquery/jquery',
'libs/bootstrap',
'libs/underscore',
'libs/backbone/backbone',
'libs/backbone/backbone-relational',
'libs/require',
'libs/d3',
'galaxy.base',
'galaxy.panels',
'libs/handlebars.runtime'
)}
${h.js(
"mvc/ui"
)}
## send errors to Sntry server if configured
%if app.config.sentry_dsn:
${h.js( "libs/tracekit", "libs/raven" )}
<script>
Raven.config('${app.config.sentry_dsn_public}').install();
%if trans.user:
Raven.setUser( { email: "${trans.user.email}" } );
%endif
</script>
%endif
## make sure console exists
<script type="text/javascript">
// console protection
window.console = window.console ||
{
log : function(){},
debug : function(){},
info : function(){},
warn : function(){},
error : function(){},
assert : function(){}
};
// set up needed paths
var galaxy_paths = new GalaxyPaths({
image_path: '${h.url_for( "/static/images" )}',
datasets_url: '${h.url_for( controller="/api/datasets" )}',
visualization_url: '${h.url_for( controller="/visualization", action="save" )}',
});
</script>
## load default style
${h.css("base")}
## modify default style
<style type="text/css">
#center {
%if not self.galaxy_config['left_panel']:
left: 0 !important;
%endif
%if not self.galaxy_config['right_panel']:
right: 0 !important;
%endif
}
%if self.galaxy_config['message_box']:
#left, #left-border, #center, #right-border, #right
{
top: 64px;
}
%endif
</style>
## default script wrapper
<script type="text/javascript">
## configure require
require.config({
baseUrl: "${h.url_for('/static/scripts') }",
shim: {
"libs/underscore": { exports: "_" },
"libs/d3": { exports: "d3" },
"libs/backbone/backbone": { exports: "Backbone" },
"libs/backbone/backbone-relational": ["libs/backbone/backbone"]
}
});
## get configuration
var config = ${ h.to_json_string( self.galaxy_config ) };
## on page load
$(function()
{
## check if script is defined
var jscript = config.app.jscript;
if (jscript)
{
## load galaxy app
require([jscript], function(js_lib)
{
## load galaxy module application
var module = new js_lib.GalaxyApp();
});
} else
console.log("'config.app.jscript' missing.");
});
</script>
</%def>
## default late-load javascripts
<%def name="late_javascripts()">
## Scripts can be loaded later since they progressively add features to
## the panels, but do not change layout
<script type="text/javascript">
ensure_dd_helper();
## configure left panel
%if self.galaxy_config['left_panel']:
var lp = new Panel( { panel: $("#left"), center: $("#center"), drag: $("#left > .unified-panel-footer > .drag" ), toggle: $("#left > .unified-panel-footer > .panel-collapse" ) } );
force_left_panel = function( x ) { lp.force_panel( x ) };
%endif
## configure right panel
%if self.galaxy_config['right_panel']:
var rp = new Panel( { panel: $("#right"), center: $("#center"), drag: $("#right > .unified-panel-footer > .drag" ), toggle: $("#right > .unified-panel-footer > .panel-collapse" ), right: true } );
window.handle_minwidth_hint = function( x ) { rp.handle_minwidth_hint( x ) };
force_right_panel = function( x ) { rp.force_panel( x ) };
%endif
</script>
</%def>
## overlay
<%def name="overlay( title='', content='', visible=False )">
<%def name="title()"></%def>
<%def name="content()"></%def>
<%
if visible:
display = "style='display: block;'"
overlay_class = "in"
else:
display = "style='display: none;'"
overlay_class = ""
%>
<div id="overlay" ${display}>
<div id="overlay-background" class="modal-backdrop fade ${overlay_class}"></div>
<div id="dialog-box" class="modal dialog-box" border="0" ${display}>
<div class="modal-header">
<span><h3 class='title'>${title}</h3></span>
</div>
<div class="modal-body">${content}</div>
<div class="modal-footer">
<div class="buttons" style="float: right;"></div>
<div class="extra_buttons" style=""></div>
<div style="clear: both;"></div>
</div>
</div>
</div>
</%def>
## document
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
## for mobile browsers, don't scale up
<meta name = "viewport" content = "maximum-scale=1.0">
## force IE to standards mode, and prefer Google Chrome Frame if the user has already installed it
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
## load scripts
${self.javascripts()}
</head>
<body scroll="no" class="full-content">
<noscript>
<div class="overlay overlay-background">
<div class="modal dialog-box" border="0">
<div class="modal-header"><h3 class="title">Javascript Required</h3></div>
<div class="modal-body">The Galaxy analysis interface requires a browser with Javascript enabled. <br> Please enable Javascript and refresh this page</div>
</div>
</div>
</noscript>
<div id="everything" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;">
## background displays first
<div id="background"></div>
## master header
%if self.galaxy_config['master']:
${masthead.load()}
%endif
## message box
%if self.galaxy_config['message_box']:
<div id="messagebox" class="panel-message"></div>
%endif
## overlay
${self.overlay(visible=self.galaxy_config['overlay'])}
## left panel
%if self.galaxy_config['left_panel']:
<div id="left">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div class="unified-panel-icons" style="float: right"></div>
<div class="unified-panel-title"></div>
</div>
</div>
<div class="unified-panel-body" style="overflow: auto;"></div>
<div class="unified-panel-footer">
<div class="panel-collapse right"></span></div>
<div class="drag"></div>
</div>
</div>
%endif
## center panel
<div id="center">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div class="unified-panel-title" style="float:left;"></div>
</div>
<div style="clear: both"></div>
</div>
<div class="unified-panel-body"></div>
</div>
## right panel
%if self.galaxy_config['right_panel']:
<div id="right">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div class="unified-panel-icons" style="float: right"></div>
<div class="unified-panel-title"></div>
</div>
</div>
<div class="unified-panel-body" style="overflow: auto;"></div>
<div class="unified-panel-footer">
<div class="panel-collapse right"></span></div>
<div class="drag"></div>
</div>
</div>
%endif
</div>
</body>
## Scripts can be loaded later since they progressively add features to
## the panels, but do not change layout
${self.late_javascripts()}
</html>
@@ -1,191 +0,0 @@
<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%namespace file="/visualization/trackster_common.mako" import="*" />
<%def name="init()">
<%
self.has_left_panel=False
self.has_right_panel=True
self.active_view="visualization"
self.message_box_visible=False
%>
</%def>
<%def name="stylesheets()">
${parent.stylesheets()}
${render_trackster_css_files()}
</%def>
<%def name="javascripts()">
${parent.javascripts()}
<!--[if lt IE 9]>
<script type='text/javascript' src="${h.url_for('/static/scripts/libs/IE/excanvas.js')}"></script>
<![endif]-->
${render_trackster_js_files()}
<script type="text/javascript">
require.config({
baseUrl: "${h.url_for('/static/scripts') }",
shim: {
"libs/underscore": { exports: "_" },
"libs/backbone/backbone": { exports: "Backbone" },
"libs/backbone/backbone-relational": ["libs/backbone/backbone"]
}
});
require( ["base", "viz/visualization", "viz/trackster_ui", "viz/trackster/tracks"],
function( base, visualization, trackster_ui, tracks ) {
${render_trackster_js_vars()}
// FIXME: deliberate global required for now due to requireJS integration.
view = null;
var browser_router,
ui = new (trackster_ui.TracksterUI)( "${h.url_for('/')}" );
/**
* Set up router.
*/
var set_up_router = function(options) {
browser_router = new visualization.TrackBrowserRouter(options);
Backbone.history.start();
};
var browser_router;
$(function() {
ui.createButtonMenu();
// Attach the button menu to the panel header and float it left
ui.buttonMenu.$el.attr("style", "float: right");
$("#center .unified-panel-header-inner").append(ui.buttonMenu.$el);
// Hide bookmarks by default right now.
force_right_panel("hide");
// Resize view when showing/hiding right panel (bookmarks for now).
$("#right-border").click(function() { view.resize_window(); });
%if config:
view = ui.create_visualization( {
container: $("#browser-container"),
name: "${config.get('title') | h}",
vis_id: "${config.get('vis_id')}",
dbkey: "${config.get('dbkey')}"
},
${ h.to_json_string( config.get( 'viewport', dict() ) ) },
${ h.to_json_string( config['tracks'] ) },
${ h.to_json_string( config['bookmarks'] ) },
true
);
init_editor();
set_up_router({view: view});
%else:
var continue_fn = function() {
view = ui.create_visualization( {
container: $("#browser-container"),
name: $("#new-title").val(),
dbkey: $("#new-dbkey").val()
}, ${ h.to_json_string( viewport_config ) } );
view.editor = true;
init_editor();
set_up_router({view: view});
hide_modal();
};
$.ajax({
url: "${h.url_for( controller='visualization', action='new_browser', default_dbkey=default_dbkey )}",
data: {},
error: function() { alert( "Couldn't create new browser" ) },
success: function(form_html) {
show_modal("New Visualization", form_html, {
"Cancel": function() { window.location = "${h.url_for( controller='visualization', action='list' )}"; },
"Create": function() { $(document).trigger("convert_to_values"); continue_fn(); }
});
$("#new-title").focus();
$("select[name='dbkey']").select2({ width: 'resolve'});
// To support the large number of options for dbkey, enable scrolling in overlay.
$("#overlay").css("overflow", "auto");
}
});
%endif
/**
* Initialization for editor-specific functions.
*/
function init_editor() {
$("#title").text(view.name + " (" + view.dbkey + ")");
if (!is_in_galaxy_frame())
window.onbeforeunload = function() {
if (view.has_changes) {
return "There are unsaved changes to your visualization which will be lost.";
}
};
%if add_dataset is not None:
$.ajax({
url: add_track_async_url + "/${add_dataset}",
data: { hda_ldda: 'hda', data_type: 'track_config' },
dataType: "json",
success: function(track_data) { view.add_drawable( trackster_ui.object_from_template(track_data, view, view) ) }
});
%endif
//
// Initialize icons.
//
$("#add-bookmark-button").click(function() {
// Add new bookmark.
var position = view.chrom + ":" + view.low + "-" + view.high,
annotation = "Bookmark description";
return ui.add_bookmark(position, annotation, true);
});
// make_popupmenu( $("#bookmarks-more-button"), {
// "Add from BED dataset": function() {
// add_bookmarks();
// }
// });
ui.init_keyboard_nav(view);
};
});
});
</script>
</%def>
<%def name="center_panel()">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div style="float:left;" id="title"></div>
</div>
<div style="clear: both"></div>
</div>
<div id="browser-container" class="unified-panel-body"></div>
</%def>
<%def name="right_panel()">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div style="float: right">
<a id="add-bookmark-button" class='icon-button menu-button plus-button' href="javascript:void(0);" title="Add bookmark"></a>
## <a id="bookmarks-more-button" class='icon-button menu-button gear popup' href="javascript:void(0);" title="More actions"></a>
</div>
Bookmarks
</div>
</div>
<div class="unified-panel-body" style="overflow: auto;">
<div id="bookmarks-container"></div>
</div>
</%def>
@@ -1,121 +0,0 @@
<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%namespace file="/visualization/trackster_common.mako" import="render_trackster_js_vars" />
<%def name="init()">
<%
self.has_left_panel=False
self.has_right_panel=False
self.active_view="visualization"
self.message_box_visible=False
%>
</%def>
<%def name="stylesheets()">
${parent.stylesheets()}
<style>
text {
font-size: 10px;
}
</style>
</%def>
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "libs/require" )}
<script type="text/javascript">
// These vars are neeed for selecting datasets.
${render_trackster_js_vars()}
require.config({
baseUrl: "${h.url_for('/static/scripts')}",
shim: {
"libs/underscore": { exports: "_" },
"libs/d3": { exports: "d3" }
}
});
require( [ "viz/visualization", "viz/circster" ], function(visualization_mod, circster ) {
$(function() {
// -- Viz set up. --
var genome = new visualization_mod.Genome( ${ h.to_json_string( genome ) } )
vis = new visualization_mod.GenomeVisualization( ${ h.to_json_string( viz_config ) } ),
viz_view = new circster.CircsterView({
el: $('#vis'),
// Gap is difficult to set because it very dependent on chromosome size and organization.
total_gap: 2 * Math.PI * 0.1,
genome: genome,
model: vis,
dataset_arc_height: 25
});
// -- Render viz. --
viz_view.render();
// -- Visualization menu and set up.
var menu = create_icon_buttons_menu([
{ icon_class: 'plus-button', title: 'Add tracks', on_click: function() {
visualization_mod.select_datasets(select_datasets_url, add_track_async_url, vis.get('dbkey'), function(tracks) {
vis.add_tracks(tracks);
}
);
} },
{ icon_class: 'disk--arrow', title: 'Save', on_click: function() {
// Show saving dialog box
show_modal("Saving...", "progress");
$.ajax({
url: "${h.url_for( controller='visualization', action='save' )}",
type: "POST",
data: {
'id': view.vis_id,
'title': view.name,
'dbkey': view.dbkey,
'type': 'trackster',
'config': JSON.stringify(payload)
},
dataType: "json",
success: function(vis_info) {
hide_modal();
view.vis_id = vis_info.vis_id;
view.has_changes = false;
// Needed to set URL when first saving a visualization.
window.history.pushState({}, "", vis_info.url + window.location.hash);
},
error: function() {
show_modal( "Could Not Save", "Could not save visualization. Please try again later.",
{ "Close" : hide_modal } );
}
});
} },
{ icon_class: 'cross-circle', title: 'Close', on_click: function() {
window.location = "${h.url_for( controller='visualization', action='list' )}";
} }
], {
tooltip_config: { placement: 'bottom' }
});
menu.$el.attr("style", "float: right");
$("#center .unified-panel-header-inner").append(menu.$el);
// Manual tooltip config because default gravity is S and cannot be changed.
$(".menu-button").tooltip( { placement: 'bottom' } );
});
});
</script>
</%def>
<%def name="center_panel()">
<div class="unified-panel-header" unselectable="on">
<div class="unified-panel-header-inner">
<div style="float:left;" id="title">${viz_config[ 'title' ]} (${viz_config[ 'dbkey' ]})</div>
</div>
<div style="clear: both"></div>
</div>
<div id="vis" class="unified-panel-body"></div>
</%def>
@@ -73,6 +73,12 @@
var ui = new (trackster_ui.TracksterUI)( "${h.url_for('/')}" )
container_element = $("#${trans.security.encode_id( visualization.id )}");
// global config
config =
{
'root' : '${h.url_for("/")}'
};
$(function() {
var is_embedded = (container_element.parents(".item-content").length > 0);
@@ -82,7 +88,7 @@
} else { // Viewing just one shared viz
$("#right-border").click(function() { view.resize_window(); });
}
// Create visualization.
var callback;
%if 'viewport' in config: