├── .gitignore ├── .travis.yml ├── Appraisals ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── Guardfile ├── ISSUES.md ├── README.md ├── Rakefile ├── app ├── assets │ ├── fonts │ │ └── twitter │ │ │ └── bootstrap │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ ├── javascripts │ │ └── twitter │ │ │ ├── bootstrap.js │ │ │ └── bootstrap │ │ │ ├── affix.js │ │ │ ├── alert.js │ │ │ ├── button.js │ │ │ ├── carousel.js │ │ │ ├── collapse.js │ │ │ ├── dropdown.js │ │ │ ├── modal.js │ │ │ ├── popover.js │ │ │ ├── scrollspy.js │ │ │ ├── tab.js │ │ │ ├── tooltip.js │ │ │ └── transition.js │ └── stylesheets │ │ └── twitter │ │ └── bootstrap.less └── frameworks │ └── twitter │ └── bootstrap │ ├── alerts.less │ ├── badges.less │ ├── bootstrap.less │ ├── breadcrumbs.less │ ├── button-groups.less │ ├── buttons.less │ ├── carousel.less │ ├── close.less │ ├── code.less │ ├── component-animations.less │ ├── dropdowns.less │ ├── forms.less │ ├── glyphicons.less │ ├── grid.less │ ├── input-groups.less │ ├── jumbotron.less │ ├── labels.less │ ├── list-group.less │ ├── media.less │ ├── mixins.less │ ├── mixins │ ├── alerts.less │ ├── background-variant.less │ ├── border-radius.less │ ├── buttons.less │ ├── center-block.less │ ├── clearfix.less │ ├── forms.less │ ├── gradients.less │ ├── grid-framework.less │ ├── grid.less │ ├── hide-text.less │ ├── image.less │ ├── labels.less │ ├── list-group.less │ ├── nav-divider.less │ ├── nav-vertical-align.less │ ├── opacity.less │ ├── pagination.less │ ├── panels.less │ ├── progress-bar.less │ ├── reset-filter.less │ ├── reset-text.less │ ├── resize.less │ ├── responsive-visibility.less │ ├── size.less │ ├── tab-focus.less │ ├── table-row.less │ ├── text-emphasis.less │ ├── text-overflow.less │ └── vendor-prefixes.less │ ├── modals.less │ ├── navbar.less │ ├── navs.less │ ├── normalize.less │ ├── pager.less │ ├── pagination.less │ ├── panels.less │ ├── popovers.less │ ├── print.less │ ├── progress-bars.less │ ├── responsive-embed.less │ ├── responsive-utilities.less │ ├── scaffolding.less │ ├── tables.less │ ├── theme.less │ ├── thumbnails.less │ ├── tooltip.less │ ├── type.less │ ├── utilities.less │ ├── variables.less │ └── wells.less ├── less-rails-bootstrap.gemspec ├── lib ├── generators │ └── less_rails_bootstrap │ │ └── custom_bootstrap │ │ └── custom_bootstrap_generator.rb ├── less-rails-bootstrap.rb └── less │ └── rails │ ├── bootstrap.rb │ └── bootstrap │ ├── engine.rb │ └── version.rb ├── scripts └── update_bootstrap.sh └── test ├── cases ├── engine_spec.rb ├── generators │ └── custom_bootstrap_generator_test.rb ├── usage_css_spec.rb └── usage_js_spec.rb ├── dummy_app ├── app │ └── assets │ │ ├── javascripts │ │ ├── application.js │ │ └── individual.js │ │ └── stylesheets │ │ ├── application.css │ │ ├── fonts.css.less │ │ ├── framework.css.less │ │ └── individual.css.less └── init.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | *.lock 4 | pkg/* 5 | *.log 6 | test/dummy_app/log/* 7 | test/dummy_app/tmp/* 8 | tmp/* 9 | /twitter/ 10 | gemfiles/*.gemfile 11 | test/dummy_app/tmp/ 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | rvm: 2 | - 1.9.3 3 | - 2.0.0 4 | - 2.1.1 5 | - jruby-19mode 6 | before_install: 7 | - travis_retry gem install bundler 8 | - bundle --version 9 | install: 10 | - travis_retry bundle install 11 | before_script: 12 | - travis_retry bundle exec appraisal install 13 | script: 14 | - bundle exec appraisal rake test 15 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise "rails31" do 2 | gem "rails", "~> 3.1.12" 3 | gem "minitest", "~> 4.7.5" 4 | end if RUBY_VERSION < '2.0.0' 5 | 6 | appraise "rails32" do 7 | gem "rails", "~> 3.2.17" 8 | gem "minitest", "~> 4.7.5" 9 | end 10 | 11 | appraise "rails40" do 12 | gem "rails", "~> 4.0.4" 13 | end 14 | 15 | appraise "rails41" do 16 | gem "rails", "~> 4.1.0" 17 | end 18 | 19 | appraise "rails42" do 20 | gem "rails", "~> 4.2.0" 21 | end 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 3.3.4.0 - 2015-04-26 2 | 3 | * Bump less-rails dependency to allow Sprockets 3 4 | * Update to Twitter Bootstrap 3.3.4 5 | 6 | # 3.3.2.0 - 2015-01-20 7 | 8 | * Update to Twitter Bootstrap 3.3.2 9 | 10 | # 3.3.1.0 - 2014-11-13 11 | 12 | * Update to Twitter Bootstrap 3.3.1 13 | 14 | # 3.3.0.1 - 2014-11-07 15 | 16 | * Update to less-rails 2.6.0. 17 | 18 | # 3.3.0.0 - 2014-11-02 19 | 20 | * Update to Twitter Bootstrap 3.3.0 21 | 22 | # 3.2.0 - 2014-06-26 23 | 24 | * Update to Twitter Bootstrap 3.2.0 25 | 26 | # 3.1.1.1 - 2014-03-19 27 | 28 | * Update to less-rails ~> 2.5.0 29 | 30 | # 3.1.1.0 - 2014-02-15 31 | 32 | * Update to Twitter Bootstrap 3.1.1 33 | 34 | 35 | # 3.1.0.0 - 2014-01-30 36 | 37 | * Update to Twitter Bootstrap 3.1.0 38 | 39 | 40 | # 3.0.6 - 2013-12-06 41 | 42 | * Update to Twitter Bootstrap 3.0.3 43 | 44 | 45 | # 3.0.5 - 2013-11-07 46 | 47 | * Update to Twitter Bootstrap 3.0.2 48 | 49 | 50 | # 3.0.4 - 2013-10-31 51 | 52 | * Update to Twitter Bootstrap 3.0.1 53 | 54 | # 3.0.3 - 2013-09-01 55 | 56 | * Update to less-rails 2.4.2 or higher. Fix initializers for 2.4.2 too. 57 | * Remove Rails 3.1 with Ruby 2.0 build support. Sprockets will not work! 58 | 59 | # 3.0.2 - 2013-09-01 60 | 61 | * Cross platform update script. 62 | * Implement Rails generator to simplify customization of Bootstrap. 63 | * Generate bootstrap.js from twitter/bootstrap/Gruntfile.js 64 | 65 | # 3.0.1 - 2013-08-29 66 | 67 | * Another proper 3.0.0 bootstrap release. 68 | 69 | # 3.0.0.1 - 2013-08-20 70 | 71 | * proper 3.0.0 release 72 | 73 | # 3.0.0 (yanked) - 2013-08-20 74 | 75 | * Update boostrap to 3.0.0 76 | 77 | # 2.3.3 - 2013-03-07 78 | 79 | * Update boostrap to 2.3.2. 80 | 81 | # 2.3.2 - 2013-03-07 82 | 83 | * Update to less-rails 2.3.1. Really uses less v1.3.3 84 | * Update boostrap to 2.3.1. 85 | 86 | # 2.3.1 - 2013-03-06 87 | 88 | * Update to less-rails 2.3.0. 89 | 90 | # 2.3.0 - 2013-01-24 91 | 92 | * Update boostrap to 2.3.0. Thanks to all that helped! 93 | 94 | # 2.2.1 - 2013-01-14 95 | 96 | * Update bootstrap to 2.2.2. Thanks to @trentclowater 97 | 98 | # 2.2.0 - 2012-10-31 99 | 100 | * Update bootstrap to 2.2.1. Thanks to @spider-network 101 | 102 | # 2.1.1 - 2012-09-05 103 | 104 | * Use bootstrap 2.1.1. Thanks @erdah. 105 | 106 | # 2.1.0 - 2012-08-20 107 | 108 | * Use bootstrap 2.1.0. Thanks @vickash. 109 | 110 | # 2.0.13 - 2012-06-07 111 | 112 | * Update to bootstrap 2.0.4. 113 | 114 | # 2.0.12 - 2012-04-25 115 | 116 | * Work with latest less.rb v2.2.1. 117 | 118 | # 2.0.11 - 2012-04-25 119 | 120 | * Update to bootstrap 2.0.3. 121 | 122 | # 2.0.10 - 2012-04-04 123 | 124 | * Include a way to require the responsive responsive file. 125 | 126 | # 2.0.9 - 2012-04-04 127 | 128 | * Bumping the less-rails depedency so everyone can use therubyracer 0.10.0. 129 | 130 | # 2.0.8 - 2012-03-13 131 | 132 | * Fix icon sprite paths. Seems they are real paths now. 133 | 134 | # 2.0.7 - 2012-03-13 135 | 136 | * Update to official bootstrap 2.0.2 137 | 138 | # 2.0.6 - 2012-02-15 139 | 140 | * Update to official bootstrap 2.0.1 141 | 142 | # 2.0.5 - 2012-02-15 143 | 144 | * Fix .nav-list .active > a:hover Fixes #30 145 | 146 | # 2.0.3, 2.0.4 - 02-03/2012 147 | 148 | * Fix IE9 background hack from bootstrap upstream. 149 | * Misc border-radius 0px fixes. 150 | 151 | # 2.0.2 - 2012-02-01 152 | 153 | * Change require order for tooltip.js [Rufus Post] 154 | 155 | # 2.0.1 - 2012-01-31 156 | 157 | * Package up Glyphicons and use less-rails' asset-url() helper. 158 | 159 | # 2.0.0 - 2012-01-31 160 | 161 | * Update to Twitter Bootstrap 2.0.0 162 | 163 | # 1.4.1 - 2011-11-18 164 | 165 | * Update to use less-rails ~> 2.1.0 166 | 167 | # 1.4.0 - 2011-11-05 168 | 169 | * Bootstrap update (f92759b36db43e782e4235f1f214ac5851383f9b) 170 | 171 | # 1.3.3 - 2011-10-09 172 | 173 | * Move bootstrap LESS files to vendor/frameworks. Should fix assets:precompile bugs. 174 | * New test setup and hopefully a more sane engine initializer. 175 | 176 | # 1.3.2 - 2011-09-28 177 | 178 | * Require less-rails properly. Thanks Benoit Bénézech (bbenezech). 179 | 180 | # 1.3.1 - 2011-09-26 181 | 182 | * Require twipsy before popover [stratequip] 183 | 184 | # 1.3.0 - 2011-09-25 185 | 186 | * Initial 1.3.0 release (68605bdd51760a929cc661607f06f479c53b0bee) 187 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Creating Issues 2 | 3 | If you are having a problem, please see our [ISSUES](https://github.com/metaskills/less-rails-bootstrap/blob/master/ISSUES.md) page for troubleshooting steps and a guide for submitting a ticket that will help us solve the problem you are having as quickly as possible. 4 | 5 | ## Contributing 6 | 7 | Here are the steps to update the version of twitter bootstrap used. 8 | 9 | * Clone this repository. 10 | * Run the `./scripts/update_bootstrap.sh` script with bootstrap repo version tag argument. For example `./scripts/update_bootstrap.sh v3.0.0`. 11 | * Make your changes 12 | * Run the tests by doing: 13 | 14 | ``` 15 | $ bundle install 16 | $ bundle exec rake appraisal:setup 17 | $ bundle exec rake appraisal test 18 | ``` 19 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem "therubyracer", ">= 0.10.1", :require => nil, :platforms => :ruby 6 | gem "therubyrhino", ">= 1.73.2", :require => nil, :platforms => :jruby 7 | 8 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard 'minitest' do 2 | watch(%r|^lib/less/rails/bootstrap/(.*)\.rb|) { |m| "test/cases/#{m[1]}_spec.rb" } 3 | watch(%r|^test/spec_helper\.rb|) { "test/cases" } 4 | watch(%r|^test/cases/(.*)_spec\.rb|) 5 | end 6 | -------------------------------------------------------------------------------- /ISSUES.md: -------------------------------------------------------------------------------- 1 | # less-rails-bootstrap Issues 2 | 3 | ## Troubleshooting 4 | 5 | Please try to update to latest version with `bundle update less-rails-bootstrap` before creating an issue. 6 | 7 | Do not forget to lock major version in `Gemfile`. 8 | 9 | **For Twitter Bootstrap 2.3 use:** 10 | 11 | ```ruby 12 | gem 'less-rails-bootstrap', '~> 2.3.3' 13 | ``` 14 | 15 | **For Twitter Bootstrap 3 use:** 16 | 17 | ```ruby 18 | gem 'less-rails-bootstrap', '~> 3.0.0' 19 | ``` 20 | 21 | If you are looking for older versions of Twitter Bootstrap or you're facing the wrong path to Twitter Bootstrap resources problem, then try the following steps: 22 | 23 | * reset Asset Pipeline cache with `rake tmp:clear` 24 | * check settings related to caching inside 'environments/*.rb' files 25 | * remove `assets` directory from `public` directory if it exists in your development environment 26 | 27 | ## Reporting problems 28 | 29 | Please include: 30 | 31 | - Your rails version (you can find in `Gemfile.lock`) 32 | - Your less-rails-bootstrap version (you can find in `Gemfile.lock`) 33 | - What version of Ruby you are using (run `ruby -v`) 34 | 35 | Thanks for reporting an issue and helping make less-rails-bootstrap better! 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Less Rails Bootstrap [![Build Status](https://travis-ci.org/metaskills/less-rails-bootstrap.png?branch=master)](https://travis-ci.org/metaskills/less-rails-bootstrap) 2 | 3 | Bootstrap is Twitter's toolkit for kickstarting your site or app's CSS. It includes base styles for typography, forms, buttons, tables, grid layout, navigation, alerts, and more. To get started -- check out the [Bootstrap docs](http://getbootstrap.com/). 4 | 5 | The less-rails-bootstrap project hooks into [less-rails](http://github.com/metaskills/less-rails) and [less.rb](http://github.com/cowboyd/less.rb), making Bootstrap's source LESS files, compiled CSS, and JavaScript files available in the Rails 3.x and 4.x asset pipeline. 6 | 7 | The benefits: 8 | 9 | * Assets are namespaced in twitter/bootstrap to avoid asset conflicts. 10 | * Top level requires to get all stylesheets or javascripts. 11 | * Ability to import or require individually namespaced stylesheets or javascripts. 12 | 13 | 14 | ## Installation 15 | 16 | LESS requires a JavaScript runtime to work. Which one you use depends on your Ruby implementation. Two are shown for Ruby (MRI) and JRuby. Add only the relevant one to your Gemfile. If you want to use Bootstrap's JavaScript plugins, also add the `jquery-rails` gem. Finally, add `less-rails-bootstrap` and run `bundle install`. 17 | 18 | ```ruby 19 | # Gemfile 20 | 21 | gem 'therubyracer' # If using Ruby 22 | gem 'therubyrhino' # If using JRuby 23 | gem 'jquery-rails' # If using Bootstrap's JS plugins. 24 | gem 'less-rails-bootstrap' 25 | ``` 26 | 27 | ## Basic CSS Use 28 | 29 | ### Simple way 30 | 31 | Get the full Bootstrap stylesheet with a single line in your `application.css`. 32 | 33 | ``` 34 | /* 35 | *= require twitter/bootstrap 36 | */ 37 | ``` 38 | 39 | ### Advanced way 40 | 41 | In case when you just want to modify several LESS variables (i.e. change text color, etc.) and don't want to thinking about [Full Control & Customization](https://github.com/metaskills/less-rails-bootstrap-test#full-control--customization) you can run Rails generator: 42 | 43 | ``` 44 | rails generate less_rails_bootstrap:custom_bootstrap 45 | ``` 46 | 47 | It generates three files: 48 | 49 | * `app/assets/stylesheets/custom_bootstrap/custom_bootstrap.less` - auto-generated file base on bootstrap.less file from original Twitter Bootstrap. Don't modify it! 50 | * `app/assets/stylesheets/custom_bootstrap/variables.less` - in this file you can override Twitter Bootstrap variables or define own 51 | * `app/assets/stylesheets/custom_bootstrap/mixins.less` - in this file you can override Twitter Bootstrap mixins or define own 52 | 53 | Then just add single line to `application.css`. 54 | 55 | ``` 56 | /* 57 | *= require custom_bootstrap/custom_bootstrap 58 | */ 59 | ``` 60 | 61 | > Please see the [less-rails-bootstrap-test](http://github.com/metaskills/less-rails-bootstrap-test) repo for examples that customize the CSS output by using LESS. The "CSS Tests Suites" section of the README and code is what you want to focus on. Also, check out the [LESS syntax](http://lesscss.org/). 62 | 63 | ## Basic JavaScript Use 64 | 65 | In `application.js`, require jQuery first. Now you can add all the Bootstrap plugins with a single line. 66 | 67 | ```` 68 | //= require jquery 69 | //= require jquery_ujs 70 | //= require twitter/bootstrap 71 | ```` 72 | 73 | Or include plugins individually. 74 | 75 | ```` 76 | //= require jquery 77 | //= require jquery_ujs 78 | //= require twitter/bootstrap/modal 79 | //= require twitter/bootstrap/alert 80 | ```` 81 | 82 | 83 | ## Versioning 84 | 85 | This gem will directly track the semantic versioning of the Twitter Bootstrap project. Our major and minor versions will always match to theirs, though we may have tiny patch level releases specific to this gem. 86 | 87 | 88 | ## Contributing 89 | 90 | This gem is fully tested from Rails 3.1 to 4.1. We run our tests on [Travis CI](http://travis-ci.org/metaskills/less-rails-boostrap) in both Ruby 1.9, 2.0, 2.1, and jRuby 1.9 mode. If you detect a problem, open up a github issue or fork the repo and help out. After you fork or clone the repository, the following commands will get you up and running on the test suite. 91 | 92 | ```shell 93 | $ bundle install 94 | $ bundle exec appraisal install 95 | $ bundle exec appraisal rake test 96 | ``` 97 | 98 | We use the [appraisal](https://github.com/thoughtbot/appraisal) gem from Thoughtbot to help us generate the individual gemfiles for each Rails version and to run the tests locally against each generated Gemfile. The `appraisal rake test` command actually runs our test suite against all Rails versions in our `Appraisal` file. If you want to run the tests for a specific Rails version, use `rake -T` for a list. For example, the following command will run the tests for Rails 3.2 only. 99 | 100 | ```shell 101 | $ bundle exec appraisal rails32 rake test 102 | ``` 103 | 104 | Our current build status is: 105 | [![Build Status](https://secure.travis-ci.org/metaskills/minitest-spec-rails.png)](http://travis-ci.org/metaskills/less-rails-bootstrap) read more in our [CONTRIBUTING](https://github.com/metaskills/less-rails-bootstrap/blob/master/CONTRIBUTING.md) file. 106 | 107 | 108 | 109 | ## License 110 | 111 | Twitter Bootstrap Project: http://twitter.github.com/bootstrap 112 | 113 | Copyright 2011 Twitter, Inc. 114 | 115 | Licensed under the Apache License, Version 2.0 (the "License"); 116 | you may not use this file except in compliance with the License. 117 | You may obtain a copy of the License at 118 | 119 | http://www.apache.org/licenses/LICENSE-2.0 120 | 121 | Unless required by applicable law or agreed to in writing, software 122 | distributed under the License is distributed on an "AS IS" BASIS, 123 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124 | See the License for the specific language governing permissions and 125 | limitations under the License. 126 | 127 | Less::Rails is Copyright (c) 2011 Ken Collins, and is distributed under the MIT license. 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | require 'rake/testtask' 3 | require 'appraisal' 4 | 5 | Bundler::GemHelper.install_tasks 6 | 7 | Rake::TestTask.new do |t| 8 | t.libs = ['lib','test'] 9 | t.test_files = Dir.glob(["test/**/*_{spec,test}.rb"]).sort 10 | t.verbose = true 11 | end 12 | 13 | task :default => [:test] 14 | task :spec => [:test] 15 | 16 | desc "Setup Appraisal." 17 | task 'appraisal:setup' do 18 | Rake::Task['appraisal:cleanup'].invoke 19 | Rake::Task['appraisal:gemfiles'].invoke 20 | Rake::Task['appraisal:install'].invoke 21 | end 22 | -------------------------------------------------------------------------------- /app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metaskills/less-rails-bootstrap/908327bfaab6cac700229ab0b4b7913ea215c285/app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metaskills/less-rails-bootstrap/908327bfaab6cac700229ab0b4b7913ea215c285/app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metaskills/less-rails-bootstrap/908327bfaab6cac700229ab0b4b7913ea215c285/app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metaskills/less-rails-bootstrap/908327bfaab6cac700229ab0b4b7913ea215c285/app/assets/fonts/twitter/bootstrap/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap.js: -------------------------------------------------------------------------------- 1 | //= require twitter/bootstrap/transition.js 2 | //= require twitter/bootstrap/alert.js 3 | //= require twitter/bootstrap/button.js 4 | //= require twitter/bootstrap/carousel.js 5 | //= require twitter/bootstrap/collapse.js 6 | //= require twitter/bootstrap/dropdown.js 7 | //= require twitter/bootstrap/modal.js 8 | //= require twitter/bootstrap/tooltip.js 9 | //= require twitter/bootstrap/popover.js 10 | //= require twitter/bootstrap/scrollspy.js 11 | //= require twitter/bootstrap/tab.js 12 | //= require twitter/bootstrap/affix.js 13 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/affix.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: affix.js v3.3.5 3 | * http://getbootstrap.com/javascript/#affix 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // AFFIX CLASS DEFINITION 14 | // ====================== 15 | 16 | var Affix = function (element, options) { 17 | this.options = $.extend({}, Affix.DEFAULTS, options) 18 | 19 | this.$target = $(this.options.target) 20 | .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 21 | .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 22 | 23 | this.$element = $(element) 24 | this.affixed = null 25 | this.unpin = null 26 | this.pinnedOffset = null 27 | 28 | this.checkPosition() 29 | } 30 | 31 | Affix.VERSION = '3.3.5' 32 | 33 | Affix.RESET = 'affix affix-top affix-bottom' 34 | 35 | Affix.DEFAULTS = { 36 | offset: 0, 37 | target: window 38 | } 39 | 40 | Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { 41 | var scrollTop = this.$target.scrollTop() 42 | var position = this.$element.offset() 43 | var targetHeight = this.$target.height() 44 | 45 | if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false 46 | 47 | if (this.affixed == 'bottom') { 48 | if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' 49 | return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' 50 | } 51 | 52 | var initializing = this.affixed == null 53 | var colliderTop = initializing ? scrollTop : position.top 54 | var colliderHeight = initializing ? targetHeight : height 55 | 56 | if (offsetTop != null && scrollTop <= offsetTop) return 'top' 57 | if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' 58 | 59 | return false 60 | } 61 | 62 | Affix.prototype.getPinnedOffset = function () { 63 | if (this.pinnedOffset) return this.pinnedOffset 64 | this.$element.removeClass(Affix.RESET).addClass('affix') 65 | var scrollTop = this.$target.scrollTop() 66 | var position = this.$element.offset() 67 | return (this.pinnedOffset = position.top - scrollTop) 68 | } 69 | 70 | Affix.prototype.checkPositionWithEventLoop = function () { 71 | setTimeout($.proxy(this.checkPosition, this), 1) 72 | } 73 | 74 | Affix.prototype.checkPosition = function () { 75 | if (!this.$element.is(':visible')) return 76 | 77 | var height = this.$element.height() 78 | var offset = this.options.offset 79 | var offsetTop = offset.top 80 | var offsetBottom = offset.bottom 81 | var scrollHeight = Math.max($(document).height(), $(document.body).height()) 82 | 83 | if (typeof offset != 'object') offsetBottom = offsetTop = offset 84 | if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 85 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 86 | 87 | var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) 88 | 89 | if (this.affixed != affix) { 90 | if (this.unpin != null) this.$element.css('top', '') 91 | 92 | var affixType = 'affix' + (affix ? '-' + affix : '') 93 | var e = $.Event(affixType + '.bs.affix') 94 | 95 | this.$element.trigger(e) 96 | 97 | if (e.isDefaultPrevented()) return 98 | 99 | this.affixed = affix 100 | this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 101 | 102 | this.$element 103 | .removeClass(Affix.RESET) 104 | .addClass(affixType) 105 | .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') 106 | } 107 | 108 | if (affix == 'bottom') { 109 | this.$element.offset({ 110 | top: scrollHeight - height - offsetBottom 111 | }) 112 | } 113 | } 114 | 115 | 116 | // AFFIX PLUGIN DEFINITION 117 | // ======================= 118 | 119 | function Plugin(option) { 120 | return this.each(function () { 121 | var $this = $(this) 122 | var data = $this.data('bs.affix') 123 | var options = typeof option == 'object' && option 124 | 125 | if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 126 | if (typeof option == 'string') data[option]() 127 | }) 128 | } 129 | 130 | var old = $.fn.affix 131 | 132 | $.fn.affix = Plugin 133 | $.fn.affix.Constructor = Affix 134 | 135 | 136 | // AFFIX NO CONFLICT 137 | // ================= 138 | 139 | $.fn.affix.noConflict = function () { 140 | $.fn.affix = old 141 | return this 142 | } 143 | 144 | 145 | // AFFIX DATA-API 146 | // ============== 147 | 148 | $(window).on('load', function () { 149 | $('[data-spy="affix"]').each(function () { 150 | var $spy = $(this) 151 | var data = $spy.data() 152 | 153 | data.offset = data.offset || {} 154 | 155 | if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom 156 | if (data.offsetTop != null) data.offset.top = data.offsetTop 157 | 158 | Plugin.call($spy, data) 159 | }) 160 | }) 161 | 162 | }(jQuery); 163 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/alert.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: alert.js v3.3.5 3 | * http://getbootstrap.com/javascript/#alerts 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // ALERT CLASS DEFINITION 14 | // ====================== 15 | 16 | var dismiss = '[data-dismiss="alert"]' 17 | var Alert = function (el) { 18 | $(el).on('click', dismiss, this.close) 19 | } 20 | 21 | Alert.VERSION = '3.3.5' 22 | 23 | Alert.TRANSITION_DURATION = 150 24 | 25 | Alert.prototype.close = function (e) { 26 | var $this = $(this) 27 | var selector = $this.attr('data-target') 28 | 29 | if (!selector) { 30 | selector = $this.attr('href') 31 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 32 | } 33 | 34 | var $parent = $(selector) 35 | 36 | if (e) e.preventDefault() 37 | 38 | if (!$parent.length) { 39 | $parent = $this.closest('.alert') 40 | } 41 | 42 | $parent.trigger(e = $.Event('close.bs.alert')) 43 | 44 | if (e.isDefaultPrevented()) return 45 | 46 | $parent.removeClass('in') 47 | 48 | function removeElement() { 49 | // detach from parent, fire event then clean up data 50 | $parent.detach().trigger('closed.bs.alert').remove() 51 | } 52 | 53 | $.support.transition && $parent.hasClass('fade') ? 54 | $parent 55 | .one('bsTransitionEnd', removeElement) 56 | .emulateTransitionEnd(Alert.TRANSITION_DURATION) : 57 | removeElement() 58 | } 59 | 60 | 61 | // ALERT PLUGIN DEFINITION 62 | // ======================= 63 | 64 | function Plugin(option) { 65 | return this.each(function () { 66 | var $this = $(this) 67 | var data = $this.data('bs.alert') 68 | 69 | if (!data) $this.data('bs.alert', (data = new Alert(this))) 70 | if (typeof option == 'string') data[option].call($this) 71 | }) 72 | } 73 | 74 | var old = $.fn.alert 75 | 76 | $.fn.alert = Plugin 77 | $.fn.alert.Constructor = Alert 78 | 79 | 80 | // ALERT NO CONFLICT 81 | // ================= 82 | 83 | $.fn.alert.noConflict = function () { 84 | $.fn.alert = old 85 | return this 86 | } 87 | 88 | 89 | // ALERT DATA-API 90 | // ============== 91 | 92 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 93 | 94 | }(jQuery); 95 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/button.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: button.js v3.3.5 3 | * http://getbootstrap.com/javascript/#buttons 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // BUTTON PUBLIC CLASS DEFINITION 14 | // ============================== 15 | 16 | var Button = function (element, options) { 17 | this.$element = $(element) 18 | this.options = $.extend({}, Button.DEFAULTS, options) 19 | this.isLoading = false 20 | } 21 | 22 | Button.VERSION = '3.3.5' 23 | 24 | Button.DEFAULTS = { 25 | loadingText: 'loading...' 26 | } 27 | 28 | Button.prototype.setState = function (state) { 29 | var d = 'disabled' 30 | var $el = this.$element 31 | var val = $el.is('input') ? 'val' : 'html' 32 | var data = $el.data() 33 | 34 | state += 'Text' 35 | 36 | if (data.resetText == null) $el.data('resetText', $el[val]()) 37 | 38 | // push to event loop to allow forms to submit 39 | setTimeout($.proxy(function () { 40 | $el[val](data[state] == null ? this.options[state] : data[state]) 41 | 42 | if (state == 'loadingText') { 43 | this.isLoading = true 44 | $el.addClass(d).attr(d, d) 45 | } else if (this.isLoading) { 46 | this.isLoading = false 47 | $el.removeClass(d).removeAttr(d) 48 | } 49 | }, this), 0) 50 | } 51 | 52 | Button.prototype.toggle = function () { 53 | var changed = true 54 | var $parent = this.$element.closest('[data-toggle="buttons"]') 55 | 56 | if ($parent.length) { 57 | var $input = this.$element.find('input') 58 | if ($input.prop('type') == 'radio') { 59 | if ($input.prop('checked')) changed = false 60 | $parent.find('.active').removeClass('active') 61 | this.$element.addClass('active') 62 | } else if ($input.prop('type') == 'checkbox') { 63 | if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false 64 | this.$element.toggleClass('active') 65 | } 66 | $input.prop('checked', this.$element.hasClass('active')) 67 | if (changed) $input.trigger('change') 68 | } else { 69 | this.$element.attr('aria-pressed', !this.$element.hasClass('active')) 70 | this.$element.toggleClass('active') 71 | } 72 | } 73 | 74 | 75 | // BUTTON PLUGIN DEFINITION 76 | // ======================== 77 | 78 | function Plugin(option) { 79 | return this.each(function () { 80 | var $this = $(this) 81 | var data = $this.data('bs.button') 82 | var options = typeof option == 'object' && option 83 | 84 | if (!data) $this.data('bs.button', (data = new Button(this, options))) 85 | 86 | if (option == 'toggle') data.toggle() 87 | else if (option) data.setState(option) 88 | }) 89 | } 90 | 91 | var old = $.fn.button 92 | 93 | $.fn.button = Plugin 94 | $.fn.button.Constructor = Button 95 | 96 | 97 | // BUTTON NO CONFLICT 98 | // ================== 99 | 100 | $.fn.button.noConflict = function () { 101 | $.fn.button = old 102 | return this 103 | } 104 | 105 | 106 | // BUTTON DATA-API 107 | // =============== 108 | 109 | $(document) 110 | .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 111 | var $btn = $(e.target) 112 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 113 | Plugin.call($btn, 'toggle') 114 | if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() 115 | }) 116 | .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { 117 | $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) 118 | }) 119 | 120 | }(jQuery); 121 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/collapse.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: collapse.js v3.3.5 3 | * http://getbootstrap.com/javascript/#collapse 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // COLLAPSE PUBLIC CLASS DEFINITION 14 | // ================================ 15 | 16 | var Collapse = function (element, options) { 17 | this.$element = $(element) 18 | this.options = $.extend({}, Collapse.DEFAULTS, options) 19 | this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + 20 | '[data-toggle="collapse"][data-target="#' + element.id + '"]') 21 | this.transitioning = null 22 | 23 | if (this.options.parent) { 24 | this.$parent = this.getParent() 25 | } else { 26 | this.addAriaAndCollapsedClass(this.$element, this.$trigger) 27 | } 28 | 29 | if (this.options.toggle) this.toggle() 30 | } 31 | 32 | Collapse.VERSION = '3.3.5' 33 | 34 | Collapse.TRANSITION_DURATION = 350 35 | 36 | Collapse.DEFAULTS = { 37 | toggle: true 38 | } 39 | 40 | Collapse.prototype.dimension = function () { 41 | var hasWidth = this.$element.hasClass('width') 42 | return hasWidth ? 'width' : 'height' 43 | } 44 | 45 | Collapse.prototype.show = function () { 46 | if (this.transitioning || this.$element.hasClass('in')) return 47 | 48 | var activesData 49 | var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') 50 | 51 | if (actives && actives.length) { 52 | activesData = actives.data('bs.collapse') 53 | if (activesData && activesData.transitioning) return 54 | } 55 | 56 | var startEvent = $.Event('show.bs.collapse') 57 | this.$element.trigger(startEvent) 58 | if (startEvent.isDefaultPrevented()) return 59 | 60 | if (actives && actives.length) { 61 | Plugin.call(actives, 'hide') 62 | activesData || actives.data('bs.collapse', null) 63 | } 64 | 65 | var dimension = this.dimension() 66 | 67 | this.$element 68 | .removeClass('collapse') 69 | .addClass('collapsing')[dimension](0) 70 | .attr('aria-expanded', true) 71 | 72 | this.$trigger 73 | .removeClass('collapsed') 74 | .attr('aria-expanded', true) 75 | 76 | this.transitioning = 1 77 | 78 | var complete = function () { 79 | this.$element 80 | .removeClass('collapsing') 81 | .addClass('collapse in')[dimension]('') 82 | this.transitioning = 0 83 | this.$element 84 | .trigger('shown.bs.collapse') 85 | } 86 | 87 | if (!$.support.transition) return complete.call(this) 88 | 89 | var scrollSize = $.camelCase(['scroll', dimension].join('-')) 90 | 91 | this.$element 92 | .one('bsTransitionEnd', $.proxy(complete, this)) 93 | .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) 94 | } 95 | 96 | Collapse.prototype.hide = function () { 97 | if (this.transitioning || !this.$element.hasClass('in')) return 98 | 99 | var startEvent = $.Event('hide.bs.collapse') 100 | this.$element.trigger(startEvent) 101 | if (startEvent.isDefaultPrevented()) return 102 | 103 | var dimension = this.dimension() 104 | 105 | this.$element[dimension](this.$element[dimension]())[0].offsetHeight 106 | 107 | this.$element 108 | .addClass('collapsing') 109 | .removeClass('collapse in') 110 | .attr('aria-expanded', false) 111 | 112 | this.$trigger 113 | .addClass('collapsed') 114 | .attr('aria-expanded', false) 115 | 116 | this.transitioning = 1 117 | 118 | var complete = function () { 119 | this.transitioning = 0 120 | this.$element 121 | .removeClass('collapsing') 122 | .addClass('collapse') 123 | .trigger('hidden.bs.collapse') 124 | } 125 | 126 | if (!$.support.transition) return complete.call(this) 127 | 128 | this.$element 129 | [dimension](0) 130 | .one('bsTransitionEnd', $.proxy(complete, this)) 131 | .emulateTransitionEnd(Collapse.TRANSITION_DURATION) 132 | } 133 | 134 | Collapse.prototype.toggle = function () { 135 | this[this.$element.hasClass('in') ? 'hide' : 'show']() 136 | } 137 | 138 | Collapse.prototype.getParent = function () { 139 | return $(this.options.parent) 140 | .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') 141 | .each($.proxy(function (i, element) { 142 | var $element = $(element) 143 | this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) 144 | }, this)) 145 | .end() 146 | } 147 | 148 | Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { 149 | var isOpen = $element.hasClass('in') 150 | 151 | $element.attr('aria-expanded', isOpen) 152 | $trigger 153 | .toggleClass('collapsed', !isOpen) 154 | .attr('aria-expanded', isOpen) 155 | } 156 | 157 | function getTargetFromTrigger($trigger) { 158 | var href 159 | var target = $trigger.attr('data-target') 160 | || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 161 | 162 | return $(target) 163 | } 164 | 165 | 166 | // COLLAPSE PLUGIN DEFINITION 167 | // ========================== 168 | 169 | function Plugin(option) { 170 | return this.each(function () { 171 | var $this = $(this) 172 | var data = $this.data('bs.collapse') 173 | var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 174 | 175 | if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false 176 | if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 177 | if (typeof option == 'string') data[option]() 178 | }) 179 | } 180 | 181 | var old = $.fn.collapse 182 | 183 | $.fn.collapse = Plugin 184 | $.fn.collapse.Constructor = Collapse 185 | 186 | 187 | // COLLAPSE NO CONFLICT 188 | // ==================== 189 | 190 | $.fn.collapse.noConflict = function () { 191 | $.fn.collapse = old 192 | return this 193 | } 194 | 195 | 196 | // COLLAPSE DATA-API 197 | // ================= 198 | 199 | $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 200 | var $this = $(this) 201 | 202 | if (!$this.attr('data-target')) e.preventDefault() 203 | 204 | var $target = getTargetFromTrigger($this) 205 | var data = $target.data('bs.collapse') 206 | var option = data ? 'toggle' : $this.data() 207 | 208 | Plugin.call($target, option) 209 | }) 210 | 211 | }(jQuery); 212 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/dropdown.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: dropdown.js v3.3.5 3 | * http://getbootstrap.com/javascript/#dropdowns 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // DROPDOWN CLASS DEFINITION 14 | // ========================= 15 | 16 | var backdrop = '.dropdown-backdrop' 17 | var toggle = '[data-toggle="dropdown"]' 18 | var Dropdown = function (element) { 19 | $(element).on('click.bs.dropdown', this.toggle) 20 | } 21 | 22 | Dropdown.VERSION = '3.3.5' 23 | 24 | function getParent($this) { 25 | var selector = $this.attr('data-target') 26 | 27 | if (!selector) { 28 | selector = $this.attr('href') 29 | selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 30 | } 31 | 32 | var $parent = selector && $(selector) 33 | 34 | return $parent && $parent.length ? $parent : $this.parent() 35 | } 36 | 37 | function clearMenus(e) { 38 | if (e && e.which === 3) return 39 | $(backdrop).remove() 40 | $(toggle).each(function () { 41 | var $this = $(this) 42 | var $parent = getParent($this) 43 | var relatedTarget = { relatedTarget: this } 44 | 45 | if (!$parent.hasClass('open')) return 46 | 47 | if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return 48 | 49 | $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) 50 | 51 | if (e.isDefaultPrevented()) return 52 | 53 | $this.attr('aria-expanded', 'false') 54 | $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) 55 | }) 56 | } 57 | 58 | Dropdown.prototype.toggle = function (e) { 59 | var $this = $(this) 60 | 61 | if ($this.is('.disabled, :disabled')) return 62 | 63 | var $parent = getParent($this) 64 | var isActive = $parent.hasClass('open') 65 | 66 | clearMenus() 67 | 68 | if (!isActive) { 69 | if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 70 | // if mobile we use a backdrop because click events don't delegate 71 | $(document.createElement('div')) 72 | .addClass('dropdown-backdrop') 73 | .insertAfter($(this)) 74 | .on('click', clearMenus) 75 | } 76 | 77 | var relatedTarget = { relatedTarget: this } 78 | $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) 79 | 80 | if (e.isDefaultPrevented()) return 81 | 82 | $this 83 | .trigger('focus') 84 | .attr('aria-expanded', 'true') 85 | 86 | $parent 87 | .toggleClass('open') 88 | .trigger('shown.bs.dropdown', relatedTarget) 89 | } 90 | 91 | return false 92 | } 93 | 94 | Dropdown.prototype.keydown = function (e) { 95 | if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return 96 | 97 | var $this = $(this) 98 | 99 | e.preventDefault() 100 | e.stopPropagation() 101 | 102 | if ($this.is('.disabled, :disabled')) return 103 | 104 | var $parent = getParent($this) 105 | var isActive = $parent.hasClass('open') 106 | 107 | if (!isActive && e.which != 27 || isActive && e.which == 27) { 108 | if (e.which == 27) $parent.find(toggle).trigger('focus') 109 | return $this.trigger('click') 110 | } 111 | 112 | var desc = ' li:not(.disabled):visible a' 113 | var $items = $parent.find('.dropdown-menu' + desc) 114 | 115 | if (!$items.length) return 116 | 117 | var index = $items.index(e.target) 118 | 119 | if (e.which == 38 && index > 0) index-- // up 120 | if (e.which == 40 && index < $items.length - 1) index++ // down 121 | if (!~index) index = 0 122 | 123 | $items.eq(index).trigger('focus') 124 | } 125 | 126 | 127 | // DROPDOWN PLUGIN DEFINITION 128 | // ========================== 129 | 130 | function Plugin(option) { 131 | return this.each(function () { 132 | var $this = $(this) 133 | var data = $this.data('bs.dropdown') 134 | 135 | if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) 136 | if (typeof option == 'string') data[option].call($this) 137 | }) 138 | } 139 | 140 | var old = $.fn.dropdown 141 | 142 | $.fn.dropdown = Plugin 143 | $.fn.dropdown.Constructor = Dropdown 144 | 145 | 146 | // DROPDOWN NO CONFLICT 147 | // ==================== 148 | 149 | $.fn.dropdown.noConflict = function () { 150 | $.fn.dropdown = old 151 | return this 152 | } 153 | 154 | 155 | // APPLY TO STANDARD DROPDOWN ELEMENTS 156 | // =================================== 157 | 158 | $(document) 159 | .on('click.bs.dropdown.data-api', clearMenus) 160 | .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) 161 | .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) 162 | .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) 163 | .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) 164 | 165 | }(jQuery); 166 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/popover.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: popover.js v3.3.5 3 | * http://getbootstrap.com/javascript/#popovers 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // POPOVER PUBLIC CLASS DEFINITION 14 | // =============================== 15 | 16 | var Popover = function (element, options) { 17 | this.init('popover', element, options) 18 | } 19 | 20 | if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') 21 | 22 | Popover.VERSION = '3.3.5' 23 | 24 | Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { 25 | placement: 'right', 26 | trigger: 'click', 27 | content: '', 28 | template: '' 29 | }) 30 | 31 | 32 | // NOTE: POPOVER EXTENDS tooltip.js 33 | // ================================ 34 | 35 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) 36 | 37 | Popover.prototype.constructor = Popover 38 | 39 | Popover.prototype.getDefaults = function () { 40 | return Popover.DEFAULTS 41 | } 42 | 43 | Popover.prototype.setContent = function () { 44 | var $tip = this.tip() 45 | var title = this.getTitle() 46 | var content = this.getContent() 47 | 48 | $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 49 | $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events 50 | this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' 51 | ](content) 52 | 53 | $tip.removeClass('fade top bottom left right in') 54 | 55 | // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do 56 | // this manually by checking the contents. 57 | if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() 58 | } 59 | 60 | Popover.prototype.hasContent = function () { 61 | return this.getTitle() || this.getContent() 62 | } 63 | 64 | Popover.prototype.getContent = function () { 65 | var $e = this.$element 66 | var o = this.options 67 | 68 | return $e.attr('data-content') 69 | || (typeof o.content == 'function' ? 70 | o.content.call($e[0]) : 71 | o.content) 72 | } 73 | 74 | Popover.prototype.arrow = function () { 75 | return (this.$arrow = this.$arrow || this.tip().find('.arrow')) 76 | } 77 | 78 | 79 | // POPOVER PLUGIN DEFINITION 80 | // ========================= 81 | 82 | function Plugin(option) { 83 | return this.each(function () { 84 | var $this = $(this) 85 | var data = $this.data('bs.popover') 86 | var options = typeof option == 'object' && option 87 | 88 | if (!data && /destroy|hide/.test(option)) return 89 | if (!data) $this.data('bs.popover', (data = new Popover(this, options))) 90 | if (typeof option == 'string') data[option]() 91 | }) 92 | } 93 | 94 | var old = $.fn.popover 95 | 96 | $.fn.popover = Plugin 97 | $.fn.popover.Constructor = Popover 98 | 99 | 100 | // POPOVER NO CONFLICT 101 | // =================== 102 | 103 | $.fn.popover.noConflict = function () { 104 | $.fn.popover = old 105 | return this 106 | } 107 | 108 | }(jQuery); 109 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/scrollspy.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: scrollspy.js v3.3.5 3 | * http://getbootstrap.com/javascript/#scrollspy 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // SCROLLSPY CLASS DEFINITION 14 | // ========================== 15 | 16 | function ScrollSpy(element, options) { 17 | this.$body = $(document.body) 18 | this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) 19 | this.options = $.extend({}, ScrollSpy.DEFAULTS, options) 20 | this.selector = (this.options.target || '') + ' .nav li > a' 21 | this.offsets = [] 22 | this.targets = [] 23 | this.activeTarget = null 24 | this.scrollHeight = 0 25 | 26 | this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) 27 | this.refresh() 28 | this.process() 29 | } 30 | 31 | ScrollSpy.VERSION = '3.3.5' 32 | 33 | ScrollSpy.DEFAULTS = { 34 | offset: 10 35 | } 36 | 37 | ScrollSpy.prototype.getScrollHeight = function () { 38 | return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) 39 | } 40 | 41 | ScrollSpy.prototype.refresh = function () { 42 | var that = this 43 | var offsetMethod = 'offset' 44 | var offsetBase = 0 45 | 46 | this.offsets = [] 47 | this.targets = [] 48 | this.scrollHeight = this.getScrollHeight() 49 | 50 | if (!$.isWindow(this.$scrollElement[0])) { 51 | offsetMethod = 'position' 52 | offsetBase = this.$scrollElement.scrollTop() 53 | } 54 | 55 | this.$body 56 | .find(this.selector) 57 | .map(function () { 58 | var $el = $(this) 59 | var href = $el.data('target') || $el.attr('href') 60 | var $href = /^#./.test(href) && $(href) 61 | 62 | return ($href 63 | && $href.length 64 | && $href.is(':visible') 65 | && [[$href[offsetMethod]().top + offsetBase, href]]) || null 66 | }) 67 | .sort(function (a, b) { return a[0] - b[0] }) 68 | .each(function () { 69 | that.offsets.push(this[0]) 70 | that.targets.push(this[1]) 71 | }) 72 | } 73 | 74 | ScrollSpy.prototype.process = function () { 75 | var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 76 | var scrollHeight = this.getScrollHeight() 77 | var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() 78 | var offsets = this.offsets 79 | var targets = this.targets 80 | var activeTarget = this.activeTarget 81 | var i 82 | 83 | if (this.scrollHeight != scrollHeight) { 84 | this.refresh() 85 | } 86 | 87 | if (scrollTop >= maxScroll) { 88 | return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) 89 | } 90 | 91 | if (activeTarget && scrollTop < offsets[0]) { 92 | this.activeTarget = null 93 | return this.clear() 94 | } 95 | 96 | for (i = offsets.length; i--;) { 97 | activeTarget != targets[i] 98 | && scrollTop >= offsets[i] 99 | && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) 100 | && this.activate(targets[i]) 101 | } 102 | } 103 | 104 | ScrollSpy.prototype.activate = function (target) { 105 | this.activeTarget = target 106 | 107 | this.clear() 108 | 109 | var selector = this.selector + 110 | '[data-target="' + target + '"],' + 111 | this.selector + '[href="' + target + '"]' 112 | 113 | var active = $(selector) 114 | .parents('li') 115 | .addClass('active') 116 | 117 | if (active.parent('.dropdown-menu').length) { 118 | active = active 119 | .closest('li.dropdown') 120 | .addClass('active') 121 | } 122 | 123 | active.trigger('activate.bs.scrollspy') 124 | } 125 | 126 | ScrollSpy.prototype.clear = function () { 127 | $(this.selector) 128 | .parentsUntil(this.options.target, '.active') 129 | .removeClass('active') 130 | } 131 | 132 | 133 | // SCROLLSPY PLUGIN DEFINITION 134 | // =========================== 135 | 136 | function Plugin(option) { 137 | return this.each(function () { 138 | var $this = $(this) 139 | var data = $this.data('bs.scrollspy') 140 | var options = typeof option == 'object' && option 141 | 142 | if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) 143 | if (typeof option == 'string') data[option]() 144 | }) 145 | } 146 | 147 | var old = $.fn.scrollspy 148 | 149 | $.fn.scrollspy = Plugin 150 | $.fn.scrollspy.Constructor = ScrollSpy 151 | 152 | 153 | // SCROLLSPY NO CONFLICT 154 | // ===================== 155 | 156 | $.fn.scrollspy.noConflict = function () { 157 | $.fn.scrollspy = old 158 | return this 159 | } 160 | 161 | 162 | // SCROLLSPY DATA-API 163 | // ================== 164 | 165 | $(window).on('load.bs.scrollspy.data-api', function () { 166 | $('[data-spy="scroll"]').each(function () { 167 | var $spy = $(this) 168 | Plugin.call($spy, $spy.data()) 169 | }) 170 | }) 171 | 172 | }(jQuery); 173 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/tab.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: tab.js v3.3.5 3 | * http://getbootstrap.com/javascript/#tabs 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // TAB CLASS DEFINITION 14 | // ==================== 15 | 16 | var Tab = function (element) { 17 | // jscs:disable requireDollarBeforejQueryAssignment 18 | this.element = $(element) 19 | // jscs:enable requireDollarBeforejQueryAssignment 20 | } 21 | 22 | Tab.VERSION = '3.3.5' 23 | 24 | Tab.TRANSITION_DURATION = 150 25 | 26 | Tab.prototype.show = function () { 27 | var $this = this.element 28 | var $ul = $this.closest('ul:not(.dropdown-menu)') 29 | var selector = $this.data('target') 30 | 31 | if (!selector) { 32 | selector = $this.attr('href') 33 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 34 | } 35 | 36 | if ($this.parent('li').hasClass('active')) return 37 | 38 | var $previous = $ul.find('.active:last a') 39 | var hideEvent = $.Event('hide.bs.tab', { 40 | relatedTarget: $this[0] 41 | }) 42 | var showEvent = $.Event('show.bs.tab', { 43 | relatedTarget: $previous[0] 44 | }) 45 | 46 | $previous.trigger(hideEvent) 47 | $this.trigger(showEvent) 48 | 49 | if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return 50 | 51 | var $target = $(selector) 52 | 53 | this.activate($this.closest('li'), $ul) 54 | this.activate($target, $target.parent(), function () { 55 | $previous.trigger({ 56 | type: 'hidden.bs.tab', 57 | relatedTarget: $this[0] 58 | }) 59 | $this.trigger({ 60 | type: 'shown.bs.tab', 61 | relatedTarget: $previous[0] 62 | }) 63 | }) 64 | } 65 | 66 | Tab.prototype.activate = function (element, container, callback) { 67 | var $active = container.find('> .active') 68 | var transition = callback 69 | && $.support.transition 70 | && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) 71 | 72 | function next() { 73 | $active 74 | .removeClass('active') 75 | .find('> .dropdown-menu > .active') 76 | .removeClass('active') 77 | .end() 78 | .find('[data-toggle="tab"]') 79 | .attr('aria-expanded', false) 80 | 81 | element 82 | .addClass('active') 83 | .find('[data-toggle="tab"]') 84 | .attr('aria-expanded', true) 85 | 86 | if (transition) { 87 | element[0].offsetWidth // reflow for transition 88 | element.addClass('in') 89 | } else { 90 | element.removeClass('fade') 91 | } 92 | 93 | if (element.parent('.dropdown-menu').length) { 94 | element 95 | .closest('li.dropdown') 96 | .addClass('active') 97 | .end() 98 | .find('[data-toggle="tab"]') 99 | .attr('aria-expanded', true) 100 | } 101 | 102 | callback && callback() 103 | } 104 | 105 | $active.length && transition ? 106 | $active 107 | .one('bsTransitionEnd', next) 108 | .emulateTransitionEnd(Tab.TRANSITION_DURATION) : 109 | next() 110 | 111 | $active.removeClass('in') 112 | } 113 | 114 | 115 | // TAB PLUGIN DEFINITION 116 | // ===================== 117 | 118 | function Plugin(option) { 119 | return this.each(function () { 120 | var $this = $(this) 121 | var data = $this.data('bs.tab') 122 | 123 | if (!data) $this.data('bs.tab', (data = new Tab(this))) 124 | if (typeof option == 'string') data[option]() 125 | }) 126 | } 127 | 128 | var old = $.fn.tab 129 | 130 | $.fn.tab = Plugin 131 | $.fn.tab.Constructor = Tab 132 | 133 | 134 | // TAB NO CONFLICT 135 | // =============== 136 | 137 | $.fn.tab.noConflict = function () { 138 | $.fn.tab = old 139 | return this 140 | } 141 | 142 | 143 | // TAB DATA-API 144 | // ============ 145 | 146 | var clickHandler = function (e) { 147 | e.preventDefault() 148 | Plugin.call($(this), 'show') 149 | } 150 | 151 | $(document) 152 | .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) 153 | .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) 154 | 155 | }(jQuery); 156 | -------------------------------------------------------------------------------- /app/assets/javascripts/twitter/bootstrap/transition.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: transition.js v3.3.5 3 | * http://getbootstrap.com/javascript/#transitions 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 14 | // ============================================================ 15 | 16 | function transitionEnd() { 17 | var el = document.createElement('bootstrap') 18 | 19 | var transEndEventNames = { 20 | WebkitTransition : 'webkitTransitionEnd', 21 | MozTransition : 'transitionend', 22 | OTransition : 'oTransitionEnd otransitionend', 23 | transition : 'transitionend' 24 | } 25 | 26 | for (var name in transEndEventNames) { 27 | if (el.style[name] !== undefined) { 28 | return { end: transEndEventNames[name] } 29 | } 30 | } 31 | 32 | return false // explicit for ie8 ( ._.) 33 | } 34 | 35 | // http://blog.alexmaccaw.com/css-transitions 36 | $.fn.emulateTransitionEnd = function (duration) { 37 | var called = false 38 | var $el = this 39 | $(this).one('bsTransitionEnd', function () { called = true }) 40 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 41 | setTimeout(callback, duration) 42 | return this 43 | } 44 | 45 | $(function () { 46 | $.support.transition = transitionEnd() 47 | 48 | if (!$.support.transition) return 49 | 50 | $.event.special.bsTransitionEnd = { 51 | bindType: $.support.transition.end, 52 | delegateType: $.support.transition.end, 53 | handle: function (e) { 54 | if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 55 | } 56 | } 57 | }) 58 | 59 | }(jQuery); 60 | -------------------------------------------------------------------------------- /app/assets/stylesheets/twitter/bootstrap.less: -------------------------------------------------------------------------------- 1 | @import "twitter/bootstrap/bootstrap"; 2 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/alerts.less: -------------------------------------------------------------------------------- 1 | // 2 | // Alerts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // ------------------------- 8 | 9 | .alert { 10 | padding: @alert-padding; 11 | margin-bottom: @line-height-computed; 12 | border: 1px solid transparent; 13 | border-radius: @alert-border-radius; 14 | 15 | // Headings for larger alerts 16 | h4 { 17 | margin-top: 0; 18 | // Specified for the h4 to prevent conflicts of changing @headings-color 19 | color: inherit; 20 | } 21 | 22 | // Provide class for links that match alerts 23 | .alert-link { 24 | font-weight: @alert-link-font-weight; 25 | } 26 | 27 | // Improve alignment and spacing of inner content 28 | > p, 29 | > ul { 30 | margin-bottom: 0; 31 | } 32 | 33 | > p + p { 34 | margin-top: 5px; 35 | } 36 | } 37 | 38 | // Dismissible alerts 39 | // 40 | // Expand the right padding and account for the close button's positioning. 41 | 42 | .alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. 43 | .alert-dismissible { 44 | padding-right: (@alert-padding + 20); 45 | 46 | // Adjust close link position 47 | .close { 48 | position: relative; 49 | top: -2px; 50 | right: -21px; 51 | color: inherit; 52 | } 53 | } 54 | 55 | // Alternate styles 56 | // 57 | // Generate contextual modifier classes for colorizing the alert. 58 | 59 | .alert-success { 60 | .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); 61 | } 62 | 63 | .alert-info { 64 | .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); 65 | } 66 | 67 | .alert-warning { 68 | .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); 69 | } 70 | 71 | .alert-danger { 72 | .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); 73 | } 74 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/badges.less: -------------------------------------------------------------------------------- 1 | // 2 | // Badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .badge { 8 | display: inline-block; 9 | min-width: 10px; 10 | padding: 3px 7px; 11 | font-size: @font-size-small; 12 | font-weight: @badge-font-weight; 13 | color: @badge-color; 14 | line-height: @badge-line-height; 15 | vertical-align: middle; 16 | white-space: nowrap; 17 | text-align: center; 18 | background-color: @badge-bg; 19 | border-radius: @badge-border-radius; 20 | 21 | // Empty badges collapse automatically (not available in IE8) 22 | &:empty { 23 | display: none; 24 | } 25 | 26 | // Quick fix for badges in buttons 27 | .btn & { 28 | position: relative; 29 | top: -1px; 30 | } 31 | 32 | .btn-xs &, 33 | .btn-group-xs > .btn & { 34 | top: 0; 35 | padding: 1px 5px; 36 | } 37 | 38 | // Hover state, but only for links 39 | a& { 40 | &:hover, 41 | &:focus { 42 | color: @badge-link-hover-color; 43 | text-decoration: none; 44 | cursor: pointer; 45 | } 46 | } 47 | 48 | // Account for badges in navs 49 | .list-group-item.active > &, 50 | .nav-pills > .active > a > & { 51 | color: @badge-active-color; 52 | background-color: @badge-active-bg; 53 | } 54 | 55 | .list-group-item > & { 56 | float: right; 57 | } 58 | 59 | .list-group-item > & + & { 60 | margin-right: 5px; 61 | } 62 | 63 | .nav-pills > li > a > & { 64 | margin-left: 3px; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/bootstrap.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.5 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // Core variables and mixins 8 | @import "variables.less"; 9 | @import "mixins.less"; 10 | 11 | // Reset and dependencies 12 | @import "normalize.less"; 13 | @import "print.less"; 14 | @import "glyphicons.less"; 15 | 16 | // Core CSS 17 | @import "scaffolding.less"; 18 | @import "type.less"; 19 | @import "code.less"; 20 | @import "grid.less"; 21 | @import "tables.less"; 22 | @import "forms.less"; 23 | @import "buttons.less"; 24 | 25 | // Components 26 | @import "component-animations.less"; 27 | @import "dropdowns.less"; 28 | @import "button-groups.less"; 29 | @import "input-groups.less"; 30 | @import "navs.less"; 31 | @import "navbar.less"; 32 | @import "breadcrumbs.less"; 33 | @import "pagination.less"; 34 | @import "pager.less"; 35 | @import "labels.less"; 36 | @import "badges.less"; 37 | @import "jumbotron.less"; 38 | @import "thumbnails.less"; 39 | @import "alerts.less"; 40 | @import "progress-bars.less"; 41 | @import "media.less"; 42 | @import "list-group.less"; 43 | @import "panels.less"; 44 | @import "responsive-embed.less"; 45 | @import "wells.less"; 46 | @import "close.less"; 47 | 48 | // Components w/ JavaScript 49 | @import "modals.less"; 50 | @import "tooltip.less"; 51 | @import "popovers.less"; 52 | @import "carousel.less"; 53 | 54 | // Utility classes 55 | @import "utilities.less"; 56 | @import "responsive-utilities.less"; 57 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/breadcrumbs.less: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; 8 | margin-bottom: @line-height-computed; 9 | list-style: none; 10 | background-color: @breadcrumb-bg; 11 | border-radius: @border-radius-base; 12 | 13 | > li { 14 | display: inline-block; 15 | 16 | + li:before { 17 | content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space 18 | padding: 0 5px; 19 | color: @breadcrumb-color; 20 | } 21 | } 22 | 23 | > .active { 24 | color: @breadcrumb-active-color; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/button-groups.less: -------------------------------------------------------------------------------- 1 | // 2 | // Button groups 3 | // -------------------------------------------------- 4 | 5 | // Make the div behave like a button 6 | .btn-group, 7 | .btn-group-vertical { 8 | position: relative; 9 | display: inline-block; 10 | vertical-align: middle; // match .btn alignment given font-size hack above 11 | > .btn { 12 | position: relative; 13 | float: left; 14 | // Bring the "active" button to the front 15 | &:hover, 16 | &:focus, 17 | &:active, 18 | &.active { 19 | z-index: 2; 20 | } 21 | } 22 | } 23 | 24 | // Prevent double borders when buttons are next to each other 25 | .btn-group { 26 | .btn + .btn, 27 | .btn + .btn-group, 28 | .btn-group + .btn, 29 | .btn-group + .btn-group { 30 | margin-left: -1px; 31 | } 32 | } 33 | 34 | // Optional: Group multiple button groups together for a toolbar 35 | .btn-toolbar { 36 | margin-left: -5px; // Offset the first child's margin 37 | &:extend(.clearfix all); 38 | 39 | .btn, 40 | .btn-group, 41 | .input-group { 42 | float: left; 43 | } 44 | > .btn, 45 | > .btn-group, 46 | > .input-group { 47 | margin-left: 5px; 48 | } 49 | } 50 | 51 | .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { 52 | border-radius: 0; 53 | } 54 | 55 | // Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match 56 | .btn-group > .btn:first-child { 57 | margin-left: 0; 58 | &:not(:last-child):not(.dropdown-toggle) { 59 | .border-right-radius(0); 60 | } 61 | } 62 | // Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it 63 | .btn-group > .btn:last-child:not(:first-child), 64 | .btn-group > .dropdown-toggle:not(:first-child) { 65 | .border-left-radius(0); 66 | } 67 | 68 | // Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) 69 | .btn-group > .btn-group { 70 | float: left; 71 | } 72 | .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { 73 | border-radius: 0; 74 | } 75 | .btn-group > .btn-group:first-child:not(:last-child) { 76 | > .btn:last-child, 77 | > .dropdown-toggle { 78 | .border-right-radius(0); 79 | } 80 | } 81 | .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { 82 | .border-left-radius(0); 83 | } 84 | 85 | // On active and open, don't show outline 86 | .btn-group .dropdown-toggle:active, 87 | .btn-group.open .dropdown-toggle { 88 | outline: 0; 89 | } 90 | 91 | 92 | // Sizing 93 | // 94 | // Remix the default button sizing classes into new ones for easier manipulation. 95 | 96 | .btn-group-xs > .btn { &:extend(.btn-xs); } 97 | .btn-group-sm > .btn { &:extend(.btn-sm); } 98 | .btn-group-lg > .btn { &:extend(.btn-lg); } 99 | 100 | 101 | // Split button dropdowns 102 | // ---------------------- 103 | 104 | // Give the line between buttons some depth 105 | .btn-group > .btn + .dropdown-toggle { 106 | padding-left: 8px; 107 | padding-right: 8px; 108 | } 109 | .btn-group > .btn-lg + .dropdown-toggle { 110 | padding-left: 12px; 111 | padding-right: 12px; 112 | } 113 | 114 | // The clickable button for toggling the menu 115 | // Remove the gradient and set the same inset shadow as the :active state 116 | .btn-group.open .dropdown-toggle { 117 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); 118 | 119 | // Show no shadow for `.btn-link` since it has no other button styles. 120 | &.btn-link { 121 | .box-shadow(none); 122 | } 123 | } 124 | 125 | 126 | // Reposition the caret 127 | .btn .caret { 128 | margin-left: 0; 129 | } 130 | // Carets in other button sizes 131 | .btn-lg .caret { 132 | border-width: @caret-width-large @caret-width-large 0; 133 | border-bottom-width: 0; 134 | } 135 | // Upside down carets for .dropup 136 | .dropup .btn-lg .caret { 137 | border-width: 0 @caret-width-large @caret-width-large; 138 | } 139 | 140 | 141 | // Vertical button groups 142 | // ---------------------- 143 | 144 | .btn-group-vertical { 145 | > .btn, 146 | > .btn-group, 147 | > .btn-group > .btn { 148 | display: block; 149 | float: none; 150 | width: 100%; 151 | max-width: 100%; 152 | } 153 | 154 | // Clear floats so dropdown menus can be properly placed 155 | > .btn-group { 156 | &:extend(.clearfix all); 157 | > .btn { 158 | float: none; 159 | } 160 | } 161 | 162 | > .btn + .btn, 163 | > .btn + .btn-group, 164 | > .btn-group + .btn, 165 | > .btn-group + .btn-group { 166 | margin-top: -1px; 167 | margin-left: 0; 168 | } 169 | } 170 | 171 | .btn-group-vertical > .btn { 172 | &:not(:first-child):not(:last-child) { 173 | border-radius: 0; 174 | } 175 | &:first-child:not(:last-child) { 176 | border-top-right-radius: @btn-border-radius-base; 177 | .border-bottom-radius(0); 178 | } 179 | &:last-child:not(:first-child) { 180 | border-bottom-left-radius: @btn-border-radius-base; 181 | .border-top-radius(0); 182 | } 183 | } 184 | .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { 185 | border-radius: 0; 186 | } 187 | .btn-group-vertical > .btn-group:first-child:not(:last-child) { 188 | > .btn:last-child, 189 | > .dropdown-toggle { 190 | .border-bottom-radius(0); 191 | } 192 | } 193 | .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { 194 | .border-top-radius(0); 195 | } 196 | 197 | 198 | // Justified button groups 199 | // ---------------------- 200 | 201 | .btn-group-justified { 202 | display: table; 203 | width: 100%; 204 | table-layout: fixed; 205 | border-collapse: separate; 206 | > .btn, 207 | > .btn-group { 208 | float: none; 209 | display: table-cell; 210 | width: 1%; 211 | } 212 | > .btn-group .btn { 213 | width: 100%; 214 | } 215 | 216 | > .btn-group .dropdown-menu { 217 | left: auto; 218 | } 219 | } 220 | 221 | 222 | // Checkbox and radio options 223 | // 224 | // In order to support the browser's form validation feedback, powered by the 225 | // `required` attribute, we have to "hide" the inputs via `clip`. We cannot use 226 | // `display: none;` or `visibility: hidden;` as that also hides the popover. 227 | // Simply visually hiding the inputs via `opacity` would leave them clickable in 228 | // certain cases which is prevented by using `clip` and `pointer-events`. 229 | // This way, we ensure a DOM element is visible to position the popover from. 230 | // 231 | // See https://github.com/twbs/bootstrap/pull/12794 and 232 | // https://github.com/twbs/bootstrap/pull/14559 for more information. 233 | 234 | [data-toggle="buttons"] { 235 | > .btn, 236 | > .btn-group > .btn { 237 | input[type="radio"], 238 | input[type="checkbox"] { 239 | position: absolute; 240 | clip: rect(0,0,0,0); 241 | pointer-events: none; 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/buttons.less: -------------------------------------------------------------------------------- 1 | // 2 | // Buttons 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // -------------------------------------------------- 8 | 9 | .btn { 10 | display: inline-block; 11 | margin-bottom: 0; // For input.btn 12 | font-weight: @btn-font-weight; 13 | text-align: center; 14 | vertical-align: middle; 15 | touch-action: manipulation; 16 | cursor: pointer; 17 | background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 18 | border: 1px solid transparent; 19 | white-space: nowrap; 20 | .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base); 21 | .user-select(none); 22 | 23 | &, 24 | &:active, 25 | &.active { 26 | &:focus, 27 | &.focus { 28 | .tab-focus(); 29 | } 30 | } 31 | 32 | &:hover, 33 | &:focus, 34 | &.focus { 35 | color: @btn-default-color; 36 | text-decoration: none; 37 | } 38 | 39 | &:active, 40 | &.active { 41 | outline: 0; 42 | background-image: none; 43 | .box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); 44 | } 45 | 46 | &.disabled, 47 | &[disabled], 48 | fieldset[disabled] & { 49 | cursor: @cursor-disabled; 50 | .opacity(.65); 51 | .box-shadow(none); 52 | } 53 | 54 | a& { 55 | &.disabled, 56 | fieldset[disabled] & { 57 | pointer-events: none; // Future-proof disabling of clicks on `` elements 58 | } 59 | } 60 | } 61 | 62 | 63 | // Alternate buttons 64 | // -------------------------------------------------- 65 | 66 | .btn-default { 67 | .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); 68 | } 69 | .btn-primary { 70 | .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); 71 | } 72 | // Success appears as green 73 | .btn-success { 74 | .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); 75 | } 76 | // Info appears as blue-green 77 | .btn-info { 78 | .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); 79 | } 80 | // Warning appears as orange 81 | .btn-warning { 82 | .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); 83 | } 84 | // Danger and error appear as red 85 | .btn-danger { 86 | .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); 87 | } 88 | 89 | 90 | // Link buttons 91 | // ------------------------- 92 | 93 | // Make a button look and behave like a link 94 | .btn-link { 95 | color: @link-color; 96 | font-weight: normal; 97 | border-radius: 0; 98 | 99 | &, 100 | &:active, 101 | &.active, 102 | &[disabled], 103 | fieldset[disabled] & { 104 | background-color: transparent; 105 | .box-shadow(none); 106 | } 107 | &, 108 | &:hover, 109 | &:focus, 110 | &:active { 111 | border-color: transparent; 112 | } 113 | &:hover, 114 | &:focus { 115 | color: @link-hover-color; 116 | text-decoration: @link-hover-decoration; 117 | background-color: transparent; 118 | } 119 | &[disabled], 120 | fieldset[disabled] & { 121 | &:hover, 122 | &:focus { 123 | color: @btn-link-disabled-color; 124 | text-decoration: none; 125 | } 126 | } 127 | } 128 | 129 | 130 | // Button Sizes 131 | // -------------------------------------------------- 132 | 133 | .btn-lg { 134 | // line-height: ensure even-numbered height of button next to large input 135 | .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large); 136 | } 137 | .btn-sm { 138 | // line-height: ensure proper height of button next to small input 139 | .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small); 140 | } 141 | .btn-xs { 142 | .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small); 143 | } 144 | 145 | 146 | // Block button 147 | // -------------------------------------------------- 148 | 149 | .btn-block { 150 | display: block; 151 | width: 100%; 152 | } 153 | 154 | // Vertically space out multiple block buttons 155 | .btn-block + .btn-block { 156 | margin-top: 5px; 157 | } 158 | 159 | // Specificity overrides 160 | input[type="submit"], 161 | input[type="reset"], 162 | input[type="button"] { 163 | &.btn-block { 164 | width: 100%; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/carousel.less: -------------------------------------------------------------------------------- 1 | // 2 | // Carousel 3 | // -------------------------------------------------- 4 | 5 | 6 | // Wrapper for the slide container and indicators 7 | .carousel { 8 | position: relative; 9 | } 10 | 11 | .carousel-inner { 12 | position: relative; 13 | overflow: hidden; 14 | width: 100%; 15 | 16 | > .item { 17 | display: none; 18 | position: relative; 19 | .transition(.6s ease-in-out left); 20 | 21 | // Account for jankitude on images 22 | > img, 23 | > a > img { 24 | &:extend(.img-responsive); 25 | line-height: 1; 26 | } 27 | 28 | // WebKit CSS3 transforms for supported devices 29 | @media all and (transform-3d), (-webkit-transform-3d) { 30 | .transition-transform(~'0.6s ease-in-out'); 31 | .backface-visibility(~'hidden'); 32 | .perspective(1000px); 33 | 34 | &.next, 35 | &.active.right { 36 | .translate3d(100%, 0, 0); 37 | left: 0; 38 | } 39 | &.prev, 40 | &.active.left { 41 | .translate3d(-100%, 0, 0); 42 | left: 0; 43 | } 44 | &.next.left, 45 | &.prev.right, 46 | &.active { 47 | .translate3d(0, 0, 0); 48 | left: 0; 49 | } 50 | } 51 | } 52 | 53 | > .active, 54 | > .next, 55 | > .prev { 56 | display: block; 57 | } 58 | 59 | > .active { 60 | left: 0; 61 | } 62 | 63 | > .next, 64 | > .prev { 65 | position: absolute; 66 | top: 0; 67 | width: 100%; 68 | } 69 | 70 | > .next { 71 | left: 100%; 72 | } 73 | > .prev { 74 | left: -100%; 75 | } 76 | > .next.left, 77 | > .prev.right { 78 | left: 0; 79 | } 80 | 81 | > .active.left { 82 | left: -100%; 83 | } 84 | > .active.right { 85 | left: 100%; 86 | } 87 | 88 | } 89 | 90 | // Left/right controls for nav 91 | // --------------------------- 92 | 93 | .carousel-control { 94 | position: absolute; 95 | top: 0; 96 | left: 0; 97 | bottom: 0; 98 | width: @carousel-control-width; 99 | .opacity(@carousel-control-opacity); 100 | font-size: @carousel-control-font-size; 101 | color: @carousel-control-color; 102 | text-align: center; 103 | text-shadow: @carousel-text-shadow; 104 | // We can't have this transition here because WebKit cancels the carousel 105 | // animation if you trip this while in the middle of another animation. 106 | 107 | // Set gradients for backgrounds 108 | &.left { 109 | #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001)); 110 | } 111 | &.right { 112 | left: auto; 113 | right: 0; 114 | #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5)); 115 | } 116 | 117 | // Hover/focus state 118 | &:hover, 119 | &:focus { 120 | outline: 0; 121 | color: @carousel-control-color; 122 | text-decoration: none; 123 | .opacity(.9); 124 | } 125 | 126 | // Toggles 127 | .icon-prev, 128 | .icon-next, 129 | .glyphicon-chevron-left, 130 | .glyphicon-chevron-right { 131 | position: absolute; 132 | top: 50%; 133 | margin-top: -10px; 134 | z-index: 5; 135 | display: inline-block; 136 | } 137 | .icon-prev, 138 | .glyphicon-chevron-left { 139 | left: 50%; 140 | margin-left: -10px; 141 | } 142 | .icon-next, 143 | .glyphicon-chevron-right { 144 | right: 50%; 145 | margin-right: -10px; 146 | } 147 | .icon-prev, 148 | .icon-next { 149 | width: 20px; 150 | height: 20px; 151 | line-height: 1; 152 | font-family: serif; 153 | } 154 | 155 | 156 | .icon-prev { 157 | &:before { 158 | content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) 159 | } 160 | } 161 | .icon-next { 162 | &:before { 163 | content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) 164 | } 165 | } 166 | } 167 | 168 | // Optional indicator pips 169 | // 170 | // Add an unordered list with the following class and add a list item for each 171 | // slide your carousel holds. 172 | 173 | .carousel-indicators { 174 | position: absolute; 175 | bottom: 10px; 176 | left: 50%; 177 | z-index: 15; 178 | width: 60%; 179 | margin-left: -30%; 180 | padding-left: 0; 181 | list-style: none; 182 | text-align: center; 183 | 184 | li { 185 | display: inline-block; 186 | width: 10px; 187 | height: 10px; 188 | margin: 1px; 189 | text-indent: -999px; 190 | border: 1px solid @carousel-indicator-border-color; 191 | border-radius: 10px; 192 | cursor: pointer; 193 | 194 | // IE8-9 hack for event handling 195 | // 196 | // Internet Explorer 8-9 does not support clicks on elements without a set 197 | // `background-color`. We cannot use `filter` since that's not viewed as a 198 | // background color by the browser. Thus, a hack is needed. 199 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer 200 | // 201 | // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we 202 | // set alpha transparency for the best results possible. 203 | background-color: #000 \9; // IE8 204 | background-color: rgba(0,0,0,0); // IE9 205 | } 206 | .active { 207 | margin: 0; 208 | width: 12px; 209 | height: 12px; 210 | background-color: @carousel-indicator-active-bg; 211 | } 212 | } 213 | 214 | // Optional captions 215 | // ----------------------------- 216 | // Hidden by default for smaller viewports 217 | .carousel-caption { 218 | position: absolute; 219 | left: 15%; 220 | right: 15%; 221 | bottom: 20px; 222 | z-index: 10; 223 | padding-top: 20px; 224 | padding-bottom: 20px; 225 | color: @carousel-caption-color; 226 | text-align: center; 227 | text-shadow: @carousel-text-shadow; 228 | & .btn { 229 | text-shadow: none; // No shadow for button elements in carousel-caption 230 | } 231 | } 232 | 233 | 234 | // Scale up controls for tablets and up 235 | @media screen and (min-width: @screen-sm-min) { 236 | 237 | // Scale up the controls a smidge 238 | .carousel-control { 239 | .glyphicon-chevron-left, 240 | .glyphicon-chevron-right, 241 | .icon-prev, 242 | .icon-next { 243 | width: 30px; 244 | height: 30px; 245 | margin-top: -15px; 246 | font-size: 30px; 247 | } 248 | .glyphicon-chevron-left, 249 | .icon-prev { 250 | margin-left: -15px; 251 | } 252 | .glyphicon-chevron-right, 253 | .icon-next { 254 | margin-right: -15px; 255 | } 256 | } 257 | 258 | // Show and left align the captions 259 | .carousel-caption { 260 | left: 20%; 261 | right: 20%; 262 | padding-bottom: 30px; 263 | } 264 | 265 | // Move up the indicators 266 | .carousel-indicators { 267 | bottom: 20px; 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/close.less: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: (@font-size-base * 1.5); 9 | font-weight: @close-font-weight; 10 | line-height: 1; 11 | color: @close-color; 12 | text-shadow: @close-text-shadow; 13 | .opacity(.2); 14 | 15 | &:hover, 16 | &:focus { 17 | color: @close-color; 18 | text-decoration: none; 19 | cursor: pointer; 20 | .opacity(.5); 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 27 | button& { 28 | padding: 0; 29 | cursor: pointer; 30 | background: transparent; 31 | border: 0; 32 | -webkit-appearance: none; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/code.less: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and block) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | kbd, 9 | pre, 10 | samp { 11 | font-family: @font-family-monospace; 12 | } 13 | 14 | // Inline code 15 | code { 16 | padding: 2px 4px; 17 | font-size: 90%; 18 | color: @code-color; 19 | background-color: @code-bg; 20 | border-radius: @border-radius-base; 21 | } 22 | 23 | // User input typically entered via keyboard 24 | kbd { 25 | padding: 2px 4px; 26 | font-size: 90%; 27 | color: @kbd-color; 28 | background-color: @kbd-bg; 29 | border-radius: @border-radius-small; 30 | box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); 31 | 32 | kbd { 33 | padding: 0; 34 | font-size: 100%; 35 | font-weight: bold; 36 | box-shadow: none; 37 | } 38 | } 39 | 40 | // Blocks of code 41 | pre { 42 | display: block; 43 | padding: ((@line-height-computed - 1) / 2); 44 | margin: 0 0 (@line-height-computed / 2); 45 | font-size: (@font-size-base - 1); // 14px to 13px 46 | line-height: @line-height-base; 47 | word-break: break-all; 48 | word-wrap: break-word; 49 | color: @pre-color; 50 | background-color: @pre-bg; 51 | border: 1px solid @pre-border-color; 52 | border-radius: @border-radius-base; 53 | 54 | // Account for some code outputs that place code tags in pre tags 55 | code { 56 | padding: 0; 57 | font-size: inherit; 58 | color: inherit; 59 | white-space: pre-wrap; 60 | background-color: transparent; 61 | border-radius: 0; 62 | } 63 | } 64 | 65 | // Enable scrollable blocks of code 66 | .pre-scrollable { 67 | max-height: @pre-scrollable-max-height; 68 | overflow-y: scroll; 69 | } 70 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/component-animations.less: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | // Heads up! 6 | // 7 | // We don't use the `.opacity()` mixin here since it causes a bug with text 8 | // fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. 9 | 10 | .fade { 11 | opacity: 0; 12 | .transition(opacity .15s linear); 13 | &.in { 14 | opacity: 1; 15 | } 16 | } 17 | 18 | .collapse { 19 | display: none; 20 | 21 | &.in { display: block; } 22 | tr&.in { display: table-row; } 23 | tbody&.in { display: table-row-group; } 24 | } 25 | 26 | .collapsing { 27 | position: relative; 28 | height: 0; 29 | overflow: hidden; 30 | .transition-property(~"height, visibility"); 31 | .transition-duration(.35s); 32 | .transition-timing-function(ease); 33 | } 34 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/dropdowns.less: -------------------------------------------------------------------------------- 1 | // 2 | // Dropdown menus 3 | // -------------------------------------------------- 4 | 5 | 6 | // Dropdown arrow/caret 7 | .caret { 8 | display: inline-block; 9 | width: 0; 10 | height: 0; 11 | margin-left: 2px; 12 | vertical-align: middle; 13 | border-top: @caret-width-base dashed; 14 | border-top: @caret-width-base solid ~"\9"; // IE8 15 | border-right: @caret-width-base solid transparent; 16 | border-left: @caret-width-base solid transparent; 17 | } 18 | 19 | // The dropdown wrapper (div) 20 | .dropup, 21 | .dropdown { 22 | position: relative; 23 | } 24 | 25 | // Prevent the focus on the dropdown toggle when closing dropdowns 26 | .dropdown-toggle:focus { 27 | outline: 0; 28 | } 29 | 30 | // The dropdown menu (ul) 31 | .dropdown-menu { 32 | position: absolute; 33 | top: 100%; 34 | left: 0; 35 | z-index: @zindex-dropdown; 36 | display: none; // none by default, but block on "open" of the menu 37 | float: left; 38 | min-width: 160px; 39 | padding: 5px 0; 40 | margin: 2px 0 0; // override default ul 41 | list-style: none; 42 | font-size: @font-size-base; 43 | text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) 44 | background-color: @dropdown-bg; 45 | border: 1px solid @dropdown-fallback-border; // IE8 fallback 46 | border: 1px solid @dropdown-border; 47 | border-radius: @border-radius-base; 48 | .box-shadow(0 6px 12px rgba(0,0,0,.175)); 49 | background-clip: padding-box; 50 | 51 | // Aligns the dropdown menu to right 52 | // 53 | // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` 54 | &.pull-right { 55 | right: 0; 56 | left: auto; 57 | } 58 | 59 | // Dividers (basically an hr) within the dropdown 60 | .divider { 61 | .nav-divider(@dropdown-divider-bg); 62 | } 63 | 64 | // Links within the dropdown menu 65 | > li > a { 66 | display: block; 67 | padding: 3px 20px; 68 | clear: both; 69 | font-weight: normal; 70 | line-height: @line-height-base; 71 | color: @dropdown-link-color; 72 | white-space: nowrap; // prevent links from randomly breaking onto new lines 73 | } 74 | } 75 | 76 | // Hover/Focus state 77 | .dropdown-menu > li > a { 78 | &:hover, 79 | &:focus { 80 | text-decoration: none; 81 | color: @dropdown-link-hover-color; 82 | background-color: @dropdown-link-hover-bg; 83 | } 84 | } 85 | 86 | // Active state 87 | .dropdown-menu > .active > a { 88 | &, 89 | &:hover, 90 | &:focus { 91 | color: @dropdown-link-active-color; 92 | text-decoration: none; 93 | outline: 0; 94 | background-color: @dropdown-link-active-bg; 95 | } 96 | } 97 | 98 | // Disabled state 99 | // 100 | // Gray out text and ensure the hover/focus state remains gray 101 | 102 | .dropdown-menu > .disabled > a { 103 | &, 104 | &:hover, 105 | &:focus { 106 | color: @dropdown-link-disabled-color; 107 | } 108 | 109 | // Nuke hover/focus effects 110 | &:hover, 111 | &:focus { 112 | text-decoration: none; 113 | background-color: transparent; 114 | background-image: none; // Remove CSS gradient 115 | .reset-filter(); 116 | cursor: @cursor-disabled; 117 | } 118 | } 119 | 120 | // Open state for the dropdown 121 | .open { 122 | // Show the menu 123 | > .dropdown-menu { 124 | display: block; 125 | } 126 | 127 | // Remove the outline when :focus is triggered 128 | > a { 129 | outline: 0; 130 | } 131 | } 132 | 133 | // Menu positioning 134 | // 135 | // Add extra class to `.dropdown-menu` to flip the alignment of the dropdown 136 | // menu with the parent. 137 | .dropdown-menu-right { 138 | left: auto; // Reset the default from `.dropdown-menu` 139 | right: 0; 140 | } 141 | // With v3, we enabled auto-flipping if you have a dropdown within a right 142 | // aligned nav component. To enable the undoing of that, we provide an override 143 | // to restore the default dropdown menu alignment. 144 | // 145 | // This is only for left-aligning a dropdown menu within a `.navbar-right` or 146 | // `.pull-right` nav component. 147 | .dropdown-menu-left { 148 | left: 0; 149 | right: auto; 150 | } 151 | 152 | // Dropdown section headers 153 | .dropdown-header { 154 | display: block; 155 | padding: 3px 20px; 156 | font-size: @font-size-small; 157 | line-height: @line-height-base; 158 | color: @dropdown-header-color; 159 | white-space: nowrap; // as with > li > a 160 | } 161 | 162 | // Backdrop to catch body clicks on mobile, etc. 163 | .dropdown-backdrop { 164 | position: fixed; 165 | left: 0; 166 | right: 0; 167 | bottom: 0; 168 | top: 0; 169 | z-index: (@zindex-dropdown - 10); 170 | } 171 | 172 | // Right aligned dropdowns 173 | .pull-right > .dropdown-menu { 174 | right: 0; 175 | left: auto; 176 | } 177 | 178 | // Allow for dropdowns to go bottom up (aka, dropup-menu) 179 | // 180 | // Just add .dropup after the standard .dropdown class and you're set, bro. 181 | // TODO: abstract this so that the navbar fixed styles are not placed here? 182 | 183 | .dropup, 184 | .navbar-fixed-bottom .dropdown { 185 | // Reverse the caret 186 | .caret { 187 | border-top: 0; 188 | border-bottom: @caret-width-base dashed; 189 | border-bottom: @caret-width-base solid ~"\9"; // IE8 190 | content: ""; 191 | } 192 | // Different positioning for bottom up menu 193 | .dropdown-menu { 194 | top: auto; 195 | bottom: 100%; 196 | margin-bottom: 2px; 197 | } 198 | } 199 | 200 | 201 | // Component alignment 202 | // 203 | // Reiterate per navbar.less and the modified component alignment there. 204 | 205 | @media (min-width: @grid-float-breakpoint) { 206 | .navbar-right { 207 | .dropdown-menu { 208 | .dropdown-menu-right(); 209 | } 210 | // Necessary for overrides of the default right aligned menu. 211 | // Will remove come v4 in all likelihood. 212 | .dropdown-menu-left { 213 | .dropdown-menu-left(); 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/grid.less: -------------------------------------------------------------------------------- 1 | // 2 | // Grid system 3 | // -------------------------------------------------- 4 | 5 | 6 | // Container widths 7 | // 8 | // Set the container width, and override it for fixed navbars in media queries. 9 | 10 | .container { 11 | .container-fixed(); 12 | 13 | @media (min-width: @screen-sm-min) { 14 | width: @container-sm; 15 | } 16 | @media (min-width: @screen-md-min) { 17 | width: @container-md; 18 | } 19 | @media (min-width: @screen-lg-min) { 20 | width: @container-lg; 21 | } 22 | } 23 | 24 | 25 | // Fluid container 26 | // 27 | // Utilizes the mixin meant for fixed width containers, but without any defined 28 | // width for fluid, full width layouts. 29 | 30 | .container-fluid { 31 | .container-fixed(); 32 | } 33 | 34 | 35 | // Row 36 | // 37 | // Rows contain and clear the floats of your columns. 38 | 39 | .row { 40 | .make-row(); 41 | } 42 | 43 | 44 | // Columns 45 | // 46 | // Common styles for small and large grid columns 47 | 48 | .make-grid-columns(); 49 | 50 | 51 | // Extra small grid 52 | // 53 | // Columns, offsets, pushes, and pulls for extra small devices like 54 | // smartphones. 55 | 56 | .make-grid(xs); 57 | 58 | 59 | // Small grid 60 | // 61 | // Columns, offsets, pushes, and pulls for the small device range, from phones 62 | // to tablets. 63 | 64 | @media (min-width: @screen-sm-min) { 65 | .make-grid(sm); 66 | } 67 | 68 | 69 | // Medium grid 70 | // 71 | // Columns, offsets, pushes, and pulls for the desktop device range. 72 | 73 | @media (min-width: @screen-md-min) { 74 | .make-grid(md); 75 | } 76 | 77 | 78 | // Large grid 79 | // 80 | // Columns, offsets, pushes, and pulls for the large desktop device range. 81 | 82 | @media (min-width: @screen-lg-min) { 83 | .make-grid(lg); 84 | } 85 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/input-groups.less: -------------------------------------------------------------------------------- 1 | // 2 | // Input groups 3 | // -------------------------------------------------- 4 | 5 | // Base styles 6 | // ------------------------- 7 | .input-group { 8 | position: relative; // For dropdowns 9 | display: table; 10 | border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table 11 | 12 | // Undo padding and float of grid classes 13 | &[class*="col-"] { 14 | float: none; 15 | padding-left: 0; 16 | padding-right: 0; 17 | } 18 | 19 | .form-control { 20 | // Ensure that the input is always above the *appended* addon button for 21 | // proper border colors. 22 | position: relative; 23 | z-index: 2; 24 | 25 | // IE9 fubars the placeholder attribute in text inputs and the arrows on 26 | // select elements in input groups. To fix it, we float the input. Details: 27 | // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855 28 | float: left; 29 | 30 | width: 100%; 31 | margin-bottom: 0; 32 | } 33 | } 34 | 35 | // Sizing options 36 | // 37 | // Remix the default form control sizing classes into new ones for easier 38 | // manipulation. 39 | 40 | .input-group-lg > .form-control, 41 | .input-group-lg > .input-group-addon, 42 | .input-group-lg > .input-group-btn > .btn { 43 | .input-lg(); 44 | } 45 | .input-group-sm > .form-control, 46 | .input-group-sm > .input-group-addon, 47 | .input-group-sm > .input-group-btn > .btn { 48 | .input-sm(); 49 | } 50 | 51 | 52 | // Display as table-cell 53 | // ------------------------- 54 | .input-group-addon, 55 | .input-group-btn, 56 | .input-group .form-control { 57 | display: table-cell; 58 | 59 | &:not(:first-child):not(:last-child) { 60 | border-radius: 0; 61 | } 62 | } 63 | // Addon and addon wrapper for buttons 64 | .input-group-addon, 65 | .input-group-btn { 66 | width: 1%; 67 | white-space: nowrap; 68 | vertical-align: middle; // Match the inputs 69 | } 70 | 71 | // Text input groups 72 | // ------------------------- 73 | .input-group-addon { 74 | padding: @padding-base-vertical @padding-base-horizontal; 75 | font-size: @font-size-base; 76 | font-weight: normal; 77 | line-height: 1; 78 | color: @input-color; 79 | text-align: center; 80 | background-color: @input-group-addon-bg; 81 | border: 1px solid @input-group-addon-border-color; 82 | border-radius: @border-radius-base; 83 | 84 | // Sizing 85 | &.input-sm { 86 | padding: @padding-small-vertical @padding-small-horizontal; 87 | font-size: @font-size-small; 88 | border-radius: @border-radius-small; 89 | } 90 | &.input-lg { 91 | padding: @padding-large-vertical @padding-large-horizontal; 92 | font-size: @font-size-large; 93 | border-radius: @border-radius-large; 94 | } 95 | 96 | // Nuke default margins from checkboxes and radios to vertically center within. 97 | input[type="radio"], 98 | input[type="checkbox"] { 99 | margin-top: 0; 100 | } 101 | } 102 | 103 | // Reset rounded corners 104 | .input-group .form-control:first-child, 105 | .input-group-addon:first-child, 106 | .input-group-btn:first-child > .btn, 107 | .input-group-btn:first-child > .btn-group > .btn, 108 | .input-group-btn:first-child > .dropdown-toggle, 109 | .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), 110 | .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { 111 | .border-right-radius(0); 112 | } 113 | .input-group-addon:first-child { 114 | border-right: 0; 115 | } 116 | .input-group .form-control:last-child, 117 | .input-group-addon:last-child, 118 | .input-group-btn:last-child > .btn, 119 | .input-group-btn:last-child > .btn-group > .btn, 120 | .input-group-btn:last-child > .dropdown-toggle, 121 | .input-group-btn:first-child > .btn:not(:first-child), 122 | .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { 123 | .border-left-radius(0); 124 | } 125 | .input-group-addon:last-child { 126 | border-left: 0; 127 | } 128 | 129 | // Button input groups 130 | // ------------------------- 131 | .input-group-btn { 132 | position: relative; 133 | // Jankily prevent input button groups from wrapping with `white-space` and 134 | // `font-size` in combination with `inline-block` on buttons. 135 | font-size: 0; 136 | white-space: nowrap; 137 | 138 | // Negative margin for spacing, position for bringing hovered/focused/actived 139 | // element above the siblings. 140 | > .btn { 141 | position: relative; 142 | + .btn { 143 | margin-left: -1px; 144 | } 145 | // Bring the "active" button to the front 146 | &:hover, 147 | &:focus, 148 | &:active { 149 | z-index: 2; 150 | } 151 | } 152 | 153 | // Negative margin to only have a 1px border between the two 154 | &:first-child { 155 | > .btn, 156 | > .btn-group { 157 | margin-right: -1px; 158 | } 159 | } 160 | &:last-child { 161 | > .btn, 162 | > .btn-group { 163 | z-index: 2; 164 | margin-left: -1px; 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/jumbotron.less: -------------------------------------------------------------------------------- 1 | // 2 | // Jumbotron 3 | // -------------------------------------------------- 4 | 5 | 6 | .jumbotron { 7 | padding-top: @jumbotron-padding; 8 | padding-bottom: @jumbotron-padding; 9 | margin-bottom: @jumbotron-padding; 10 | color: @jumbotron-color; 11 | background-color: @jumbotron-bg; 12 | 13 | h1, 14 | .h1 { 15 | color: @jumbotron-heading-color; 16 | } 17 | 18 | p { 19 | margin-bottom: (@jumbotron-padding / 2); 20 | font-size: @jumbotron-font-size; 21 | font-weight: 200; 22 | } 23 | 24 | > hr { 25 | border-top-color: darken(@jumbotron-bg, 10%); 26 | } 27 | 28 | .container &, 29 | .container-fluid & { 30 | border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container 31 | } 32 | 33 | .container { 34 | max-width: 100%; 35 | } 36 | 37 | @media screen and (min-width: @screen-sm-min) { 38 | padding-top: (@jumbotron-padding * 1.6); 39 | padding-bottom: (@jumbotron-padding * 1.6); 40 | 41 | .container &, 42 | .container-fluid & { 43 | padding-left: (@jumbotron-padding * 2); 44 | padding-right: (@jumbotron-padding * 2); 45 | } 46 | 47 | h1, 48 | .h1 { 49 | font-size: @jumbotron-heading-font-size; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/labels.less: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // -------------------------------------------------- 4 | 5 | .label { 6 | display: inline; 7 | padding: .2em .6em .3em; 8 | font-size: 75%; 9 | font-weight: bold; 10 | line-height: 1; 11 | color: @label-color; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | border-radius: .25em; 16 | 17 | // Add hover effects, but only for links 18 | a& { 19 | &:hover, 20 | &:focus { 21 | color: @label-link-hover-color; 22 | text-decoration: none; 23 | cursor: pointer; 24 | } 25 | } 26 | 27 | // Empty labels collapse automatically (not available in IE8) 28 | &:empty { 29 | display: none; 30 | } 31 | 32 | // Quick fix for labels in buttons 33 | .btn & { 34 | position: relative; 35 | top: -1px; 36 | } 37 | } 38 | 39 | // Colors 40 | // Contextual variations (linked labels get darker on :hover) 41 | 42 | .label-default { 43 | .label-variant(@label-default-bg); 44 | } 45 | 46 | .label-primary { 47 | .label-variant(@label-primary-bg); 48 | } 49 | 50 | .label-success { 51 | .label-variant(@label-success-bg); 52 | } 53 | 54 | .label-info { 55 | .label-variant(@label-info-bg); 56 | } 57 | 58 | .label-warning { 59 | .label-variant(@label-warning-bg); 60 | } 61 | 62 | .label-danger { 63 | .label-variant(@label-danger-bg); 64 | } 65 | -------------------------------------------------------------------------------- /app/frameworks/twitter/bootstrap/list-group.less: -------------------------------------------------------------------------------- 1 | // 2 | // List groups 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | // 8 | // Easily usable on