From 96f6ea514b1d60a1a709ed998b9c8e15087f6575 Mon Sep 17 00:00:00 2001 From: James Taylor Date: Fri, 20 Jul 2012 14:53:30 -0400 Subject: [PATCH] Add support for bootstrap style tabs, use tabs in edit attributes form --- static/june_2007_style/base.less | 4 + static/june_2007_style/blue/base.css | 8 +- static/june_2007_style/bootstrap/navs.less | 4 +- static/june_2007_style/galaxy_bootstrap.less | 16 +++ static/scripts/bootstrap.js | 135 +++++++++++++++++++ static/scripts/packed/bootstrap.js | 1 + templates/base.mako | 2 +- templates/dataset/edit_attributes.mako | 37 +++-- 8 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 static/scripts/bootstrap.js create mode 100644 static/scripts/packed/bootstrap.js diff --git a/static/june_2007_style/base.less b/static/june_2007_style/base.less index 42ba72f913c..c2b17e3cdbb 100644 --- a/static/june_2007_style/base.less +++ b/static/june_2007_style/base.less @@ -40,6 +40,10 @@ a, a:link, a:visited, a:active { color: @link_text; } +// Overrides for links that shouldn't be underlined +.nav-tabs a { + text-decoration: none; +} h1, h2, h3, h4 { color: @header_text; diff --git a/static/june_2007_style/blue/base.css b/static/june_2007_style/blue/base.css index cedd4055f8f..84e8ae1e2c2 100644 --- a/static/june_2007_style/blue/base.css +++ b/static/june_2007_style/blue/base.css @@ -252,8 +252,8 @@ button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding- .nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} .nav-tabs{border-bottom:1px solid #ddd;} .nav-tabs>li{margin-bottom:-1px;} -.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:16px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} -.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:16px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #999999;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #999;border-bottom-color:transparent;cursor:default;} .nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} .nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#303030;} .nav-stacked>li{float:none;} @@ -450,6 +450,9 @@ button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding- .btn.active,.btn:active{color:inherit;} .dropdown-menu{max-width:auto;} input[type="checkbox"],input[type="radio"]{margin-left:0.5ex;margin-right:0.5ex;} +.nav-tabs{border-bottom:1px solid #999999;} +.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #999999;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{border:1px solid #999999;border-bottom-color:transparent;} @font-face{font-family:'FontAwesome';src:url('../images/fonts/fontawesome-webfont.eot');src:url('../images/fonts/fontawesome-webfont.eot?#iefix') format('embedded-opentype'),url('../images/fonts/fontawesome-webfont.woff') format('woff'),url('../images/fonts/fontawesome-webfont.ttf') format('truetype'),url('../images/fonts/fontawesome-webfont.svgz#FontAwesomeRegular') format('svg'),url('../images/fonts/fontawesome-webfont.svg#FontAwesomeRegular') format('svg');font-weight:normal;font-style:normal;}.ficon,[class^="ficon"]:before,[class*=" ficon"]:before{font-family:FontAwesome;font-weight:normal;font-style:normal;display:inline-block;} .ficon.large:before{font-size:1.3333333333333333em;} .btn [class^="ficon"],.btn [class*=" ficon"]{line-height:.9em;} @@ -606,6 +609,7 @@ li[class^="ficon"].ficon.large:before,li[class*=" ficon"].ficon.large:before{tex body{background:#ffffff;color:#303030;background-image:url(base_bg.png);background-repeat:repeat-x;background-position:top;margin:10px;} img{border:0;} a,a:link,a:visited,a:active{text-decoration:underline;color:#303030;} +.nav-tabs a{text-decoration:none;} h1,h2,h3,h4{color:#023858;margin:0.5em 0;} h1{font-size:24px;} h2{font-size:18px;line-height:24px;}h2 small{font-size:14px;} diff --git a/static/june_2007_style/bootstrap/navs.less b/static/june_2007_style/bootstrap/navs.less index 5cb9f9f3a2e..2a011cf938b 100644 --- a/static/june_2007_style/bootstrap/navs.less +++ b/static/june_2007_style/bootstrap/navs.less @@ -115,7 +115,7 @@ border: 1px solid transparent; .border-radius(4px 4px 0 0); &:hover { - border-color: @grayLighter @grayLighter #ddd; + border-color: @grayLighter @grayLighter #999; } } // Active state, and it's :hover to override normal :hover @@ -123,7 +123,7 @@ .nav-tabs > .active > a:hover { color: @gray; background-color: @white; - border: 1px solid #ddd; + border: 1px solid #999; border-bottom-color: transparent; cursor: default; } diff --git a/static/june_2007_style/galaxy_bootstrap.less b/static/june_2007_style/galaxy_bootstrap.less index 307e13c15c4..d385b3c300e 100644 --- a/static/june_2007_style/galaxy_bootstrap.less +++ b/static/june_2007_style/galaxy_bootstrap.less @@ -97,3 +97,19 @@ input[type="checkbox"],input[type="radio"] { margin-left: 0.5ex; margin-right: 0.5ex; } + +// Tabs -- border color is hardcoded in navs.less, change to @btnBorder here + +.nav-tabs { + border-bottom: 1px solid @btnBorder; +} +.nav-tabs > li > a { + &:hover { + border-color: @grayLighter @grayLighter @btnBorder; + } +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + border: 1px solid @btnBorder; + border-bottom-color: transparent; +} diff --git a/static/scripts/bootstrap.js b/static/scripts/bootstrap.js new file mode 100644 index 00000000000..d87f35099ae --- /dev/null +++ b/static/scripts/bootstrap.js @@ -0,0 +1,135 @@ +/* ======================================================== + * bootstrap-tab.js v2.0.4 + * http://twitter.github.com/bootstrap/javascript.html#tabs + * ======================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* TAB CLASS DEFINITION + * ==================== */ + + var Tab = function ( element ) { + this.element = $(element) + } + + Tab.prototype = { + + constructor: Tab + + , show: function () { + var $this = this.element + , $ul = $this.closest('ul:not(.dropdown-menu)') + , selector = $this.attr('data-target') + , previous + , $target + , e + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + if ( $this.parent('li').hasClass('active') ) return + + previous = $ul.find('.active a').last()[0] + + e = $.Event('show', { + relatedTarget: previous + }) + + $this.trigger(e) + + if (e.isDefaultPrevented()) return + + $target = $(selector) + + this.activate($this.parent('li'), $ul) + this.activate($target, $target.parent(), function () { + $this.trigger({ + type: 'shown' + , relatedTarget: previous + }) + }) + } + + , activate: function ( element, container, callback) { + var $active = container.find('> .active') + , transition = callback + && $.support.transition + && $active.hasClass('fade') + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + + element.addClass('active') + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if ( element.parent('.dropdown-menu') ) { + element.closest('li.dropdown').addClass('active') + } + + callback && callback() + } + + transition ? + $active.one($.support.transition.end, next) : + next() + + $active.removeClass('in') + } + } + + + /* TAB PLUGIN DEFINITION + * ===================== */ + + $.fn.tab = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tab') + if (!data) $this.data('tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tab.Constructor = Tab + + + /* TAB DATA-API + * ============ */ + + $(function () { + $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { + e.preventDefault() + $(this).tab('show') + }) + }) + +}(window.jQuery); \ No newline at end of file diff --git a/static/scripts/packed/bootstrap.js b/static/scripts/packed/bootstrap.js new file mode 100644 index 00000000000..fbe9542f5bc --- /dev/null +++ b/static/scripts/packed/bootstrap.js @@ -0,0 +1 @@ +!function(b){var a=function(c){this.element=b(c)};a.prototype={constructor:a,show:function(){var i=this.element,f=i.closest("ul:not(.dropdown-menu)"),d=i.attr("data-target"),g,c,h;if(!d){d=i.attr("href");d=d&&d.replace(/.*(?=#[^\s]*$)/,"")}if(i.parent("li").hasClass("active")){return}g=f.find(".active a").last()[0];h=b.Event("show",{relatedTarget:g});i.trigger(h);if(h.isDefaultPrevented()){return}c=b(d);this.activate(i.parent("li"),f);this.activate(c,c.parent(),function(){i.trigger({type:"shown",relatedTarget:g})})},activate:function(e,d,h){var c=d.find("> .active"),g=h&&b.support.transition&&c.hasClass("fade");function f(){c.removeClass("active").find("> .dropdown-menu > .active").removeClass("active");e.addClass("active");if(g){e[0].offsetWidth;e.addClass("in")}else{e.removeClass("fade")}if(e.parent(".dropdown-menu")){e.closest("li.dropdown").addClass("active")}h&&h()}g?c.one(b.support.transition.end,f):f();c.removeClass("in")}};b.fn.tab=function(c){return this.each(function(){var e=b(this),d=e.data("tab");if(!d){e.data("tab",(d=new a(this)))}if(typeof c=="string"){d[c]()}})};b.fn.tab.Constructor=a;b(function(){b("body").on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(c){c.preventDefault();b(this).tab("show")})})}(window.jQuery); \ No newline at end of file diff --git a/templates/base.mako b/templates/base.mako index 846c88cc2b0..056ebf5585e 100644 --- a/templates/base.mako +++ b/templates/base.mako @@ -26,7 +26,7 @@ ## - ${h.js( "jquery", "galaxy.base", "libs/underscore", "libs/backbone", "libs/backbone-relational", "libs/handlebars.runtime", "mvc/ui" )} + ${h.js( "jquery", "bootstrap", "galaxy.base", "libs/underscore", "libs/backbone", "libs/backbone-relational", "libs/handlebars.runtime", "mvc/ui" )}