├── .editorconfig ├── .gitattributes ├── .gitignore ├── .npmignore ├── .travis.yml ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE ├── README.md ├── _config.yml ├── composer.json ├── docs ├── LICENSE ├── _includes │ ├── ads.html │ ├── footer.html │ ├── header.html │ ├── nav-components.html │ ├── nav-getting-started.html │ ├── nav-main.html │ └── social-buttons.html ├── _layouts │ ├── default.html │ └── home.html ├── assets │ ├── css │ │ ├── docs.css │ │ ├── docs.min.css │ │ └── pygments-manni.css │ ├── ico │ │ ├── apple-touch-icon-144-precomposed.png │ │ └── favicon.png │ ├── img │ │ ├── bg-1920x1200.jpg │ │ └── bg-3500x2500.jpg │ └── js │ │ ├── application.js │ │ ├── docs.min.js │ │ ├── ie8-responsive-file-warning.js │ │ ├── raw-files.min.js │ │ └── vendor │ │ ├── blob.js │ │ ├── filesaver.js │ │ ├── holder.js │ │ ├── jszip.min.js │ │ ├── less.min.js │ │ └── uglify.min.js ├── components.html ├── dist │ ├── css │ │ ├── jasny-bootstrap.css.map │ │ └── jasny-bootstrap.min.css │ └── js │ │ └── jasny-bootstrap.min.js ├── examples │ ├── navbar-offcanvas │ │ ├── index.html │ │ └── navbar-offcanvas.css │ ├── navmenu-push │ │ ├── index.html │ │ └── navmenu-push.css │ ├── navmenu-reveal │ │ ├── index.html │ │ └── navmenu-reveal.css │ ├── navmenu │ │ ├── index.html │ │ └── navmenu.css │ ├── screenshots │ │ ├── navbar-offcanvas.jpg │ │ ├── navmenu-push.jpg │ │ ├── navmenu-reveal.jpg │ │ ├── navmenu.jpg │ │ └── starter-template.jpg │ └── starter-template │ │ ├── index.html │ │ └── starter-template.css ├── getting-started.html ├── index.html └── jade │ ├── customizer-nav.jade │ └── customizer-variables.jade ├── grunt ├── .jshintrc ├── bs-lessdoc-parser.js ├── bs-raw-files-generator.js └── shrinkwrap.js ├── js ├── .jscsrc ├── .jshintrc ├── fileinput.js ├── offcanvas.js ├── rowlink.js ├── tests │ ├── index.html │ ├── unit │ │ ├── fileinput.js │ │ ├── offcanvas.js │ │ ├── phantom.js │ │ └── rowlink.js │ └── vendor │ │ ├── jquery.js │ │ ├── qunit.css │ │ └── qunit.js └── transition.js ├── less ├── .csscomb.json ├── .csslintrc ├── alerts-fixed.less ├── build │ ├── jasny-bootstrap.less │ ├── mixins.less │ └── variables.less ├── button-labels.less ├── fileinput.less ├── grid-container-smooth.less ├── jasny-bootstrap.less ├── nav-tab-alignment.less ├── navmenu.less ├── offcanvas.less ├── rowlink.less └── variables.less ├── package.js ├── package.json ├── scss ├── _alerts-fixed.scss ├── _button-labels.scss ├── _fileinput.scss ├── _grid-container-smooth.scss ├── _mixins.scss ├── _nav-tab-alignment.scss ├── _navmenu.scss ├── _offcanvas.scss ├── _rowlink.scss ├── _variables.scss ├── build │ ├── _mixins.scss │ ├── _variables.scss │ └── jasny-bootstrap.scss └── jasny-bootstrap.scss └── test-infra ├── README.md ├── npm-shrinkwrap.canonical.json ├── requirements.txt ├── sauce_browsers.yml └── uncached-npm-install.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | *.css text eol=lf 3 | *.html text eol=lf 4 | *.js text eol=lf 5 | *.json text eol=lf 6 | *.less text eol=lf 7 | *.md text eol=lf 8 | *.yml text eol=lf 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore docs files 2 | _gh_pages 3 | _site 4 | dist 5 | .ruby-version 6 | 7 | 8 | # Numerous always-ignore extensions 9 | *.diff 10 | *.err 11 | *.orig 12 | *.log 13 | *.rej 14 | *.swo 15 | *.swp 16 | *.zip 17 | *.vi 18 | *~ 19 | 20 | # OS or Editor folders 21 | .DS_Store 22 | ._* 23 | Thumbs.db 24 | .cache 25 | .project 26 | .settings 27 | .tmproj 28 | *.esproj 29 | nbproject 30 | *.sublime-project 31 | *.sublime-workspace 32 | .idea 33 | 34 | # Komodo 35 | *.komodoproject 36 | .komodotools 37 | 38 | # grunt-html-validation 39 | validation-status.json 40 | validation-report.json 41 | 42 | # Folders to ignore 43 | bower_components 44 | node_modules 45 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Ignore docs files 2 | _gh_pages 3 | _site 4 | .ruby-version 5 | 6 | #ignore dist zip and gz files 7 | /dist/jasny-bootstrap-*.zip 8 | /dist/jasny-bootstrap-*.tar.gz 9 | 10 | # Numerous always-ignore extensions 11 | *.diff 12 | *.err 13 | *.orig 14 | *.log 15 | *.rej 16 | *.swo 17 | *.swp 18 | *.zip 19 | *.vi 20 | *~ 21 | 22 | # OS or Editor folders 23 | .DS_Store 24 | ._* 25 | Thumbs.db 26 | .cache 27 | .project 28 | .settings 29 | .tmproj 30 | *.esproj 31 | nbproject 32 | *.sublime-project 33 | *.sublime-workspace 34 | .idea 35 | 36 | # Komodo 37 | *.komodoproject 38 | .komodotools 39 | 40 | # grunt-html-validation 41 | validation-status.json 42 | validation-report.json 43 | 44 | # Folders to ignore 45 | bower_components 46 | node_modules 47 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4' 4 | install: 5 | - gem install jekyll html-proofer 6 | - npm install -g grunt-cli 7 | - npm install 8 | env: 9 | matrix: 10 | - TWBS_TEST=core 11 | - TWBS_TEST=validate-html 12 | matrix: 13 | fast_finish: true 14 | after_success: 15 | - grunt dist 16 | - cd dist; 17 | - zip -r jasny-bootstrap-${TRAVIS_TAG}.zip * 18 | - tar -zcvf jasny-bootstrap-${TRAVIS_TAG}.tar.gz * 19 | - ls 20 | - cd .. 21 | - git reset --hard 22 | - npm --no-git-tag-version version ${TRAVIS_TAG} 23 | deploy: 24 | - provider: releases 25 | api_key: 26 | secure: "utwXW5WGahq3fXq5q3x5ajdbbj6lUEpHgLW9GVZy5Mf+4MzU4CeZpB3SLfV6KDegzVMZFwd2C6MG/NZZ2Fnqoz9W22DBxMFTPHbmi69IKMd7lHG3/m0bU4Zj/AuS9+Lnky6ilf+j4BWCX4+2XbMxH4/O9oT87R8NGDQvArW2CBk=" 27 | file: 28 | - dist/jasny-bootstrap-${TRAVIS_TAG}.zip 29 | - dist/jasny-bootstrap-${TRAVIS_TAG}.tar.gz 30 | skip_cleanup: true 31 | on: 32 | branch: master 33 | repo: jasny/bootstrap 34 | tags: true 35 | - provider: npm 36 | email: arnold@jasny.net 37 | api_key: 38 | secure: "JG2WD24x0TVSVcG5psFUAgdnWiGDdHeZS9PF+f9WuPzWHiwvMj5JePkPKQEbWuPFZWzpV7y6UGOkjxd87or5WmqVDWcQEn+94OzH1LBIUvlHJJtmyD4BxymEXhy6ftmJyeufTwhbDfNnuh5cDn9J0H5aRl1SZTzwKedGlCrjgiE=" 39 | skip_cleanup: true 40 | on: 41 | branch: master 42 | repo: jasny/bootstrap 43 | tags: true 44 | 45 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Bootstrap 2 | 3 | Looking to contribute something to Bootstrap? **Here's how you can help.** 4 | 5 | 6 | 7 | ## Reporting issues 8 | 9 | We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems that we can fix within the Bootstrap core. Please read the following guidelines before opening any issue. 10 | 11 | 1. **Search for existing issues.** We get a lot of duplicate issues, and you'd help us out a lot by first checking if someone else has reported the same issue. Moreover, the issue may have already been resolved with a fix available. 12 | 2. **Create an isolated and reproducible test case.** Be sure the problem exists in Bootstrap's code with a [reduced test case](http://css-tricks.com/reduced-test-cases/) that should be included in each bug report. 13 | 3. **Include a live example.** Make use of jsFiddle or jsBin to share your isolated test cases. 14 | 4. **Share as much information as possible.** Include operating system and version, browser and version, version of Bootstrap, customized or vanilla build, etc. where appropriate. Also include steps to reproduce the bug. 15 | 16 | 17 | 18 | ## Pull requests 19 | 20 | - CSS changes must be done in `.less` files first, never just the compiled `.css` files 21 | - If modifying the `.less` files, always recompile and commit the compiled files `bootstrap.css` and `bootstrap.min.css` 22 | - Try not to pollute your pull request with unintended changes--keep them simple and small 23 | - Try to share which browsers your code has been tested in before submitting a pull request 24 | - Pull requests should always be against the `master` branch, never against `gh-pages`. 25 | 26 | 27 | 28 | ## Coding standards 29 | 30 | ### HTML 31 | 32 | - Two spaces for indentation, never tabs 33 | - Double quotes only, never single quotes 34 | - Always use proper indentation 35 | - Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags) 36 | - Use CDNs and HTTPS for third-party JS when possible. We don't use protocol-relative URLs in this case because they break when viewing the page locally via `file://`. 37 | 38 | ### CSS 39 | 40 | - Adhere to the [RECESS CSS property order](http://markdotto.com/2011/11/29/css-property-order/) 41 | - Multiple-line approach (one property and value per line) 42 | - Always a space after a property's colon (e.g., `display: block;` and not `display:block;`) 43 | - End all lines with a semi-colon 44 | - For multiple, comma-separated selectors, place each selector on its own line 45 | - Attribute selectors, like `input[type="text"]` should always wrap the attribute's value in double quotes, for consistency and safety (see this [blog post on unquoted attribute values](http://mathiasbynens.be/notes/unquoted-attribute-values) that can lead to XSS attacks). 46 | 47 | ### JS 48 | 49 | - No semicolons 50 | - Comma first 51 | - 2 spaces (no tabs) 52 | - strict mode 53 | - "Attractive" 54 | 55 | 56 | 57 | ## License 58 | 59 | With v3.1, we're moving from the Apache 2 to the MIT license for the Bootstrap code (not the docs). We're in the process of collecting permissions from all Bootstrap contributors with code still part of the project to make this happen. For details, please see [#2054](https://github.com/twbs/bootstrap/issues/2054). 60 | 61 | By contributing your code, you agree to dual-license your contribution under the [Apache 2](https://github.com/twbs/bootstrap/blob/master/LICENSE) and [MIT](https://github.com/twbs/bootstrap/blob/master/MIT) licenses. 62 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Jasny Bootstrap's Gruntfile 3 | * http://jasny.github.io/bootstrap 4 | * Copyright 2013-2014 Arnold Daniels. 5 | * Licensed under Apache License 2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | module.exports = function (grunt) { 9 | 'use strict'; 10 | 11 | // Force use of Unix newlines 12 | grunt.util.linefeed = '\n'; 13 | 14 | RegExp.quote = function (string) { 15 | return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); 16 | }; 17 | 18 | var fs = require('fs'); 19 | var path = require('path'); 20 | var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js'); 21 | var updateShrinkwrap = require('./grunt/shrinkwrap.js'); 22 | 23 | // Project configuration. 24 | grunt.initConfig({ 25 | 26 | // Metadata. 27 | pkg: grunt.file.readJSON('package.json'), 28 | banner: '/*!\n' + 29 | ' * Jasny Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' + 30 | ' * Copyright 2012-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + 31 | ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' + 32 | ' */\n', 33 | jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Jasny Bootstrap\\\'s JavaScript requires jQuery\') }\n\n', 34 | 35 | // Task configuration. 36 | clean: { 37 | dist: ['dist', 'docs/dist'], 38 | jekyll: ['_gh_pages'], 39 | assets: ['assets/css/*.min.css', 'assets/js/*.min.js'] 40 | }, 41 | 42 | jshint: { 43 | options: { 44 | jshintrc: 'js/.jshintrc' 45 | }, 46 | grunt: { 47 | options: { 48 | jshintrc: 'grunt/.jshintrc' 49 | }, 50 | src: ['Gruntfile.js', 'grunt/*.js'] 51 | }, 52 | src: { 53 | src: 'js/*.js' 54 | }, 55 | test: { 56 | src: 'js/tests/unit/*.js' 57 | }, 58 | assets: { 59 | src: ['docs/assets/js/application.js'] 60 | } 61 | }, 62 | 63 | jscs: { 64 | options: { 65 | config: 'js/.jscsrc' 66 | }, 67 | grunt: { 68 | src: ['Gruntfile.js', 'grunt/*.js'] 69 | }, 70 | src: { 71 | src: 'js/*.js' 72 | }, 73 | test: { 74 | src: 'js/tests/unit/*.js' 75 | }, 76 | assets: { 77 | src: ['docs/assets/js/application.js'] 78 | } 79 | }, 80 | 81 | csslint: { 82 | options: { 83 | csslintrc: 'less/.csslintrc' 84 | }, 85 | src: [ 86 | 'dist/css/<%= pkg.name %>.css', 87 | 'docs/assets/css/docs.css', 88 | 'docs/examples/**/*.css' 89 | ] 90 | }, 91 | 92 | concat: { 93 | options: { 94 | banner: '<%= banner %>\n<%= jqueryCheck %>', 95 | stripBanners: false 96 | }, 97 | bootstrap: { 98 | src: [ 99 | 'js/transition.js', 100 | 'js/offcanvas.js', 101 | 'js/rowlink.js', 102 | 'js/inputmask.js', 103 | 'js/fileinput.js' 104 | ], 105 | dest: 'dist/js/<%= pkg.name %>.js' 106 | } 107 | }, 108 | 109 | uglify: { 110 | options: { 111 | report: 'min' 112 | }, 113 | bootstrap: { 114 | options: { 115 | banner: '<%= banner %>' 116 | }, 117 | src: '<%= concat.bootstrap.dest %>', 118 | dest: 'dist/js/<%= pkg.name %>.min.js' 119 | }, 120 | docsJs: { 121 | options: { 122 | preserveComments: 'some' 123 | }, 124 | src: [ 125 | 'docs/assets/js/vendor/holder.js', 126 | 'docs/assets/js/application.js' 127 | ], 128 | dest: 'docs/assets/js/docs.min.js' 129 | } 130 | }, 131 | 132 | less: { 133 | compileCore: { 134 | options: { 135 | strictMath: true, 136 | sourceMap: true, 137 | outputSourceFiles: true, 138 | sourceMapURL: '<%= pkg.name %>.css.map', 139 | sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map' 140 | }, 141 | files: { 142 | 'dist/css/<%= pkg.name %>.css': 'less/build/<%= pkg.name %>.less' 143 | } 144 | }, 145 | minify: { 146 | options: { 147 | cleancss: true, 148 | report: 'min' 149 | }, 150 | files: { 151 | 'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css' 152 | } 153 | } 154 | }, 155 | 156 | cssmin: { 157 | compress: { 158 | options: { 159 | keepSpecialComments: '*', 160 | noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css 161 | report: 'min', 162 | selectorsMergeMode: 'ie8' 163 | }, 164 | src: [ 165 | 'docs/assets/css/docs.css', 166 | 'docs/assets/css/pygments-manni.css' 167 | ], 168 | dest: 'docs/assets/css/docs.min.css' 169 | } 170 | }, 171 | 172 | usebanner: { 173 | dist: { 174 | options: { 175 | position: 'top', 176 | banner: '<%= banner %>' 177 | }, 178 | files: { 179 | src: [ 180 | 'dist/css/<%= pkg.name %>.css', 181 | 'dist/css/<%= pkg.name %>.min.css' 182 | ] 183 | } 184 | } 185 | }, 186 | 187 | csscomb: { 188 | options: { 189 | config: 'less/.csscomb.json' 190 | }, 191 | dist: { 192 | files: { 193 | 'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css' 194 | } 195 | }, 196 | examples: { 197 | expand: true, 198 | cwd: 'docs/examples/', 199 | src: ['**/*.css'], 200 | dest: 'docs/examples/' 201 | } 202 | }, 203 | 204 | copy: { 205 | docs: { 206 | expand: true, 207 | cwd: './dist', 208 | src: [ 209 | '{css,js}/*.min.*', 210 | 'css/*.map' 211 | ], 212 | dest: 'docs/dist' 213 | } 214 | }, 215 | 216 | qunit: { 217 | options: { 218 | inject: 'js/tests/unit/phantom.js' 219 | }, 220 | files: 'js/tests/index.html' 221 | }, 222 | 223 | connect: { 224 | server: { 225 | options: { 226 | port: 3000, 227 | base: '.' 228 | } 229 | } 230 | }, 231 | 232 | jekyll: { 233 | docs: {} 234 | }, 235 | 236 | validation: { 237 | options: { 238 | charset: 'utf-8', 239 | doctype: 'HTML5', 240 | failHard: true, 241 | reset: true, 242 | relaxerror: [ 243 | 'Bad value X-UA-Compatible for attribute http-equiv on element meta.', 244 | 'Element img is missing required attribute src.', 245 | 'This interface to HTML5 document checking is deprecated.', 246 | '\\& did not start a character reference. \\(\\& probably should have been escaped as \\&.\\)' 247 | ] 248 | }, 249 | files: { 250 | src: '_gh_pages/**/*.html' 251 | } 252 | }, 253 | 254 | watch: { 255 | src: { 256 | files: '<%= jshint.src.src %>', 257 | tasks: ['jshint:src', 'qunit'] 258 | }, 259 | test: { 260 | files: '<%= jshint.test.src %>', 261 | tasks: ['jshint:test', 'qunit'] 262 | }, 263 | less: { 264 | files: 'less/*.less', 265 | tasks: 'less' 266 | } 267 | }, 268 | 269 | replace: { 270 | versionNumber: { 271 | src: ['*.js', '*.md', '*.json', '*.yml', 'js/*.js'], 272 | overwrite: true, 273 | replacements: [ 274 | { 275 | from: grunt.option('oldver'), 276 | to: grunt.option('newver') 277 | } 278 | ] 279 | } 280 | }, 281 | 282 | 'saucelabs-qunit': { 283 | all: { 284 | options: { 285 | build: process.env.TRAVIS_JOB_ID, 286 | concurrency: 10, 287 | urls: ['http://127.0.0.1:3000/js/tests/index.html'], 288 | browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml') 289 | } 290 | } 291 | }, 292 | 293 | exec: { 294 | npmUpdate: { 295 | command: 'npm update --silent' 296 | }, 297 | npmShrinkWrap: { 298 | command: 'npm shrinkwrap --dev' 299 | } 300 | } 301 | }); 302 | 303 | 304 | // These plugins provide necessary tasks. 305 | require('load-grunt-tasks')(grunt, { scope: 'devDependencies' }); 306 | 307 | // Docs HTML validation task 308 | grunt.registerTask('validate-html', ['jekyll', 'validation']); 309 | 310 | // Test task. 311 | var testSubtasks = []; 312 | // Skip core tests if running a different subset of the test suite 313 | if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') { 314 | testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'qunit']); 315 | } 316 | // Skip HTML validation if running a different subset of the test suite 317 | if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') { 318 | testSubtasks.push('validate-html'); 319 | } 320 | // Only run Sauce Labs tests if there's a Sauce access key 321 | if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' && 322 | // Skip Sauce if running a different subset of the test suite 323 | (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) { 324 | testSubtasks.push('connect'); 325 | testSubtasks.push('saucelabs-qunit'); 326 | } 327 | grunt.registerTask('test', testSubtasks); 328 | 329 | // JS distribution task. 330 | grunt.registerTask('dist-js', ['concat', 'uglify']); 331 | 332 | // CSS distribution task. 333 | grunt.registerTask('dist-css', ['less', 'cssmin', 'csscomb', 'usebanner']); 334 | 335 | // Docs distribution task. 336 | grunt.registerTask('dist-docs', 'copy:docs'); 337 | 338 | // Full distribution task. 339 | grunt.registerTask('dist', ['clean:dist', 'dist-css', 'dist-js', 'dist-docs']); 340 | 341 | // Default task. 342 | grunt.registerTask('default', ['dist']); 343 | 344 | // Documentation task. 345 | grunt.registerTask('docs', ['jekyll', 'dist-docs']); 346 | 347 | // Version numbering task. 348 | // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z 349 | // This can be overzealous, so its changes should always be manually reviewed! 350 | grunt.registerTask('change-version-number', 'replace'); 351 | 352 | // Task for updating the npm packages used by the Travis build. 353 | grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '∆update-shrinkwrap']); 354 | grunt.registerTask('∆update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); }); 355 | }; 356 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > This extension is for **Bootstrap 4**. Almost all of the components of this extension have been added to Bootstrap 5, making this library redundant. 2 | > Because Bootstrap 4 has reached its end of life, Jasny Bootstrap will no longer be updated. 3 | 4 | # [Jasny Bootstrap](http://jasny.github.io/bootstrap/) 5 | 6 | Jasny Bootstrap is an extension of the famous [Bootstrap](http://getbootstrap.com/), adding the following components: 7 | 8 | * [Button labels](http://jasny.github.io/bootstrap/components/#buttons-labels) 9 | * [Off canvas navmenu](http://jasny.github.io/bootstrap/components/#navmenu) 10 | * [Fixed alerts](http://jasny.github.io/bootstrap/components/#alerts-fixed) 11 | * [Row link](http://jasny.github.io/bootstrap/components/#rowlink) 12 | * [File input widget](http://jasny.github.io/bootstrap/components/#fileinput) 13 | 14 | To get started, check out ! 15 | 16 | 17 | ## Quick start 18 | 19 | Four quick start options are available: 20 | 21 | * [Download the latest release](https://github.com/jasny/bootstrap/releases/download/v4.0.0/jasny-bootstrap-4.0.0-dist.zip). 22 | * Clone the repo: `git clone git://github.com/jasny/bootstrap.git`. 23 | * Use [cdnjs](http://cdnjs.com/libraries/jasny-bootstrap). 24 | * Install with [Meteor](https://meteor.com): `meteor add jasny:bootstrap`. 25 | 26 | Read the [Getting Started page](http://jasny.github.io/bootstrap/getting-started/) for information on the framework contents, templates and examples, and more. 27 | 28 | ### What's included 29 | 30 | Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this: 31 | 32 | ``` 33 | jasny-bootstrap/ 34 | ├── css/ 35 | │ ├── jasny-bootstrap.css 36 | │ ├── jasny-bootstrap.min.css 37 | └── js/ 38 | ├── jasny-bootstrap.js 39 | └── jasny-bootstrap.min.js 40 | ``` 41 | 42 | We provide compiled CSS and JS (`jasny-bootstrap.*`), as well as compiled and minified CSS and JS (`jasny-bootstrap.min.*`). 43 | 44 | Jasny Bootstrap should be loaded after vanilla Bootstrap. 45 | 46 | 47 | ## Bugs and feature requests 48 | 49 | Have a bug or a feature request? [Please open a new issue](https://github.com/jasny/bootstrap/issues). Before opening any issue, please search for existing issues and read the [Issue Guidelines](https://github.com/necolas/issue-guidelines), written by [Nicolas Gallagher](https://github.com/necolas/). 50 | 51 | You may use [this JSFiddle](http://jsfiddle.net/jasny/k9K5d/) as a template for your bug reports. 52 | 53 | 54 | 55 | ## Documentation 56 | 57 | Jasny Bootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](http://jekyllrb.com) and publicly hosted on GitHub Pages at . The docs may also be run locally. 58 | 59 | ### Running documentation locally 60 | 61 | 1. If necessary, [install Jekyll](http://jekyllrb.com/docs/installation) (requires v1.x). 62 | 2. From the root `/bootstrap` directory, run `jekyll serve` in the command line. 63 | - **Windows users:** run `chcp 65001` first to change the command prompt's character encoding ([code page](http://en.wikipedia.org/wiki/Windows_code_page)) to UTF-8 so Jekyll runs without errors. 64 | 3. Open in your browser, and voilà. 65 | 66 | Learn more about using Jekyll by reading its [documentation](http://jekyllrb.com/docs/home/). 67 | 68 | ### Documentation for previous releases 69 | 70 | Documentation for v2.3.1 has been made available for the time being at while folks transition to Bootstrap 3. 71 | 72 | [Previous releases](https://github.com/jasny/bootstrap/releases) and their documentation are also available for download. 73 | 74 | 75 | 76 | ## Compiling CSS and JavaScript 77 | 78 | Bootstrap uses [Grunt](http://gruntjs.com/) with convenient methods for working with the framework. It's how we compile our code, run tests, and more. To use it, install the required dependencies as directed and then run some Grunt commands. 79 | 80 | ### Install Grunt 81 | 82 | From the command line: 83 | 84 | 1. Install `grunt-cli` globally with `npm install -g grunt-cli`. 85 | 2. Navigate to the root `/bootstrap` directory, then run `npm install`. npm will look at [package.json](package.json) and automatically install the necessary local dependencies listed there. 86 | 87 | When completed, you'll be able to run the various Grunt commands provided from the command line. 88 | 89 | **Unfamiliar with `npm`? Don't have node installed?** That's a-okay. npm stands for [node packaged modules](http://npmjs.org/) and is a way to manage development dependencies through node.js. [Download and install node.js](http://nodejs.org/download/) before proceeding. 90 | 91 | ### Available Grunt commands 92 | 93 | #### Build - `grunt` 94 | Run `grunt` to run tests locally and compile the CSS and JavaScript into `/dist`. **Uses [recess](http://twitter.github.io/recess/) and [UglifyJS](http://lisperator.net/uglifyjs/).** 95 | 96 | #### Only compile CSS and JavaScript - `grunt dist` 97 | `grunt dist` creates the `/dist` directory with compiled files. **Uses [recess](http://twitter.github.io/recess/) and [UglifyJS](http://lisperator.net/uglifyjs/).** 98 | 99 | #### Tests - `grunt test` 100 | Runs [JSHint](http://jshint.com) and [QUnit](http://qunitjs.com/) tests headlessly in [PhantomJS](http://phantomjs.org/) (used for CI). 101 | 102 | #### Watch - `grunt watch` 103 | This is a convenience method for watching just Less files and automatically building them whenever you save. 104 | 105 | ### Troubleshooting dependencies 106 | 107 | Should you encounter problems with installing dependencies or running Grunt commands, uninstall all previous dependency versions (global and local). Then, rerun `npm install`. 108 | 109 | 110 | 111 | ## Contributing 112 | 113 | Please read through our [contributing guidelines](https://github.com/jasny/bootstrap/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development. 114 | 115 | More over, if your pull request contains JavaScript patches or features, you must include relevant unit tests. All HTML and CSS should conform to the [Code Guide](http://github.com/mdo/code-guide), maintained by [Mark Otto](http://github.com/mdo). 116 | 117 | Editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . 118 | 119 | ## Community 120 | 121 | Keep track of development and community news. 122 | 123 | * Follow [@ArnoldDaniels on Twitter](http://twitter.com/ArnoldDaniels). 124 | * Have a question that's not a feature request or bug report? [Ask on stackoverflow.](http://stackoverflow.com/) 125 | 126 | 127 | 128 | ## Versioning 129 | 130 | For transparency into our release cycle and in striving to maintain backward compatibility, Jasny Bootstrap is maintained under the Semantic Versioning guidelines. Sometimes we screw up, but we'll adhere to these rules whenever possible. 131 | 132 | Releases will be numbered with the following format: 133 | 134 | `..` 135 | 136 | And constructed with the following guidelines: 137 | 138 | - Breaking backward compatibility **bumps the major** while resetting minor and patch 139 | - New additions without breaking backward compatibility **bumps the minor** while resetting the patch 140 | - Bug fixes and misc changes **bumps only the patch** 141 | 142 | For more information on SemVer, please visit . 143 | 144 | __The major version will follow Bootstrap's major version. This means backward compatibility will only be broken if Bootstrap does so.__ 145 | 146 | 147 | 148 | ## Authors 149 | 150 | **Arnold Daniels** 151 | 152 | + [twitter.com/ArnoldDaniels](https://twitter.com/ArnoldDaniels) 153 | + [github.com/jasny](https://github.com/jasny) 154 | + [jasny.net](http://jasny.net) 155 | + [fiestainfo.com](https://www.fiestainfo.com) 156 | 157 | 158 | ## Copyright and license 159 | 160 | Copyright 2013 Jasny BV under [the Apache 2.0 license](LICENSE). 161 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | markdown: rdiscount 3 | highlighter: true 4 | 5 | # Permalinks 6 | permalink: pretty 7 | 8 | # Server 9 | source: ./docs 10 | destination: ./_gh_pages 11 | host: 0.0.0.0 12 | port: 9001 13 | baseurl: / 14 | url: http://localhost:9001 15 | encoding: UTF-8 16 | 17 | exclude: 18 | - "jade" 19 | - "vendor" 20 | 21 | # Custom vars 22 | current_version: 4.0.0 23 | repo: https://github.com/jasny/bootstrap 24 | 25 | download: 26 | source: https://github.com/jasny/bootstrap/archive/v4.0.0.zip 27 | dist: https://github.com/jasny/bootstrap/releases/download/v4.0.0/jasny-bootstrap-v4.0.0.zip 28 | 29 | cdn: 30 | css: //cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/4.0.0/css/jasny-bootstrap.min.css 31 | js: //cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/4.0.0/js/jasny-bootstrap.min.js 32 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jasny/bootstrap", 3 | "description": "The missing bootstrap components", 4 | "type": "component", 5 | "keywords": ["bootstrap", "css"], 6 | "homepage": "http://jasny.github.io/bootstrap", 7 | "authors": [ 8 | { 9 | "name": "Arnold Daniels", 10 | "email": "arnold@jasny.net" 11 | } 12 | ], 13 | "support": { 14 | "issues": "https://github.com/jasny/bootstrap/issues" 15 | }, 16 | "license": "Apache-2.0", 17 | "require": { 18 | "twbs/bootstrap" : ">=3.1.0" 19 | }, 20 | "extra": { 21 | "component": { 22 | "scripts": [ 23 | "dist/js/jasny-bootstrap.js", 24 | "dist/js/jasny-bootstrap.min.js" 25 | ], 26 | "styles": [ 27 | "dist/css/jasny-bootstrap.css", 28 | "dist/css/jasny-bootstrap.min.css" 29 | ] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/_includes/ads.html: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /docs/_includes/footer.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/_includes/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% if page.title == "Jasny Bootstrap" %} 9 | {{ page.title }} 10 | {% else %} 11 | {{ page.title }} · Jasny Bootstrap 12 | {% endif %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 56 | -------------------------------------------------------------------------------- /docs/_includes/nav-components.html: -------------------------------------------------------------------------------- 1 | 10 | 16 | 22 | 29 | 36 | 43 | 44 | -------------------------------------------------------------------------------- /docs/_includes/nav-getting-started.html: -------------------------------------------------------------------------------- 1 | 4 | 12 | 15 | 18 | 28 | 31 | 34 | 41 | 50 | -------------------------------------------------------------------------------- /docs/_includes/nav-main.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /docs/_includes/social-buttons.html: -------------------------------------------------------------------------------- 1 |
2 | 19 |
20 | -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% include header.html %} 6 | 7 | 8 | 11 | 12 | Skip to main content 13 | 14 | 15 | {% include nav-main.html %} 16 | 17 | 18 |
19 |
20 |

{{ page.title }}

21 |

{{ page.lead }}

22 | {% include ads.html %} 23 |
24 |
25 | 26 |
27 |
28 |
29 | 40 |
41 |
42 | {{ content }} 43 |
44 |
45 | 46 |
47 | 48 | 50 | 69 | 70 | 71 | {% include footer.html %} 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/_layouts/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% include header.html %} 6 | 7 | 8 | Skip to main content 9 | 10 | 11 | {% include nav-main.html %} 12 | 13 | 14 | {{ content }} 15 | 16 |
17 | {% include ads.html %} 18 | 19 | {% include social-buttons.html %} 20 | 21 | 38 |
39 | 40 | 41 | {% include footer.html %} 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/assets/css/pygments-manni.css: -------------------------------------------------------------------------------- 1 | .hll { background-color: #ffffcc } 2 | /*{ background: #f0f3f3; }*/ 3 | .c { color: #999; } /* Comment */ 4 | .err { color: #AA0000; background-color: #FFAAAA } /* Error */ 5 | .k { color: #006699; } /* Keyword */ 6 | .o { color: #555555 } /* Operator */ 7 | .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */ 8 | .cp { color: #009999 } /* Comment.Preproc */ 9 | .c1 { color: #999; } /* Comment.Single */ 10 | .cs { color: #999; } /* Comment.Special */ 11 | .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */ 12 | .ge { font-style: italic } /* Generic.Emph */ 13 | .gr { color: #FF0000 } /* Generic.Error */ 14 | .gh { color: #003300; } /* Generic.Heading */ 15 | .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */ 16 | .go { color: #AAAAAA } /* Generic.Output */ 17 | .gp { color: #000099; } /* Generic.Prompt */ 18 | .gs { } /* Generic.Strong */ 19 | .gu { color: #003300; } /* Generic.Subheading */ 20 | .gt { color: #99CC66 } /* Generic.Traceback */ 21 | .kc { color: #006699; } /* Keyword.Constant */ 22 | .kd { color: #006699; } /* Keyword.Declaration */ 23 | .kn { color: #006699; } /* Keyword.Namespace */ 24 | .kp { color: #006699 } /* Keyword.Pseudo */ 25 | .kr { color: #006699; } /* Keyword.Reserved */ 26 | .kt { color: #007788; } /* Keyword.Type */ 27 | .m { color: #FF6600 } /* Literal.Number */ 28 | .s { color: #d44950 } /* Literal.String */ 29 | .na { color: #4f9fcf } /* Name.Attribute */ 30 | .nb { color: #336666 } /* Name.Builtin */ 31 | .nc { color: #00AA88; } /* Name.Class */ 32 | .no { color: #336600 } /* Name.Constant */ 33 | .nd { color: #9999FF } /* Name.Decorator */ 34 | .ni { color: #999999; } /* Name.Entity */ 35 | .ne { color: #CC0000; } /* Name.Exception */ 36 | .nf { color: #CC00FF } /* Name.Function */ 37 | .nl { color: #9999FF } /* Name.Label */ 38 | .nn { color: #00CCFF; } /* Name.Namespace */ 39 | .nt { color: #2f6f9f; } /* Name.Tag */ 40 | .nv { color: #003333 } /* Name.Variable */ 41 | .ow { color: #000000; } /* Operator.Word */ 42 | .w { color: #bbbbbb } /* Text.Whitespace */ 43 | .mf { color: #FF6600 } /* Literal.Number.Float */ 44 | .mh { color: #FF6600 } /* Literal.Number.Hex */ 45 | .mi { color: #FF6600 } /* Literal.Number.Integer */ 46 | .mo { color: #FF6600 } /* Literal.Number.Oct */ 47 | .sb { color: #CC3300 } /* Literal.String.Backtick */ 48 | .sc { color: #CC3300 } /* Literal.String.Char */ 49 | .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */ 50 | .s2 { color: #CC3300 } /* Literal.String.Double */ 51 | .se { color: #CC3300; } /* Literal.String.Escape */ 52 | .sh { color: #CC3300 } /* Literal.String.Heredoc */ 53 | .si { color: #AA0000 } /* Literal.String.Interpol */ 54 | .sx { color: #CC3300 } /* Literal.String.Other */ 55 | .sr { color: #33AAAA } /* Literal.String.Regex */ 56 | .s1 { color: #CC3300 } /* Literal.String.Single */ 57 | .ss { color: #FFCC33 } /* Literal.String.Symbol */ 58 | .bp { color: #336666 } /* Name.Builtin.Pseudo */ 59 | .vc { color: #003333 } /* Name.Variable.Class */ 60 | .vg { color: #003333 } /* Name.Variable.Global */ 61 | .vi { color: #003333 } /* Name.Variable.Instance */ 62 | .il { color: #FF6600 } /* Literal.Number.Integer.Long */ 63 | 64 | .css .o, 65 | .css .o + .nt, 66 | .css .nt + .nt { color: #999; } 67 | -------------------------------------------------------------------------------- /docs/assets/ico/apple-touch-icon-144-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/assets/ico/apple-touch-icon-144-precomposed.png -------------------------------------------------------------------------------- /docs/assets/ico/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/assets/ico/favicon.png -------------------------------------------------------------------------------- /docs/assets/img/bg-1920x1200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/assets/img/bg-1920x1200.jpg -------------------------------------------------------------------------------- /docs/assets/img/bg-3500x2500.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/assets/img/bg-3500x2500.jpg -------------------------------------------------------------------------------- /docs/assets/js/application.js: -------------------------------------------------------------------------------- 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT 2 | // IT'S ALL JUST JUNK FOR OUR DOCS! 3 | // ++++++++++++++++++++++++++++++++++++++++++ 4 | 5 | /*! 6 | * Copyright 2013 Twitter, Inc. 7 | * 8 | * Licensed under the Creative Commons Attribution 3.0 Unported License. For 9 | * details, see http://creativecommons.org/licenses/by/3.0/. 10 | */ 11 | 12 | 13 | !function ($) { 14 | 15 | $(function() { 16 | 17 | // IE10 viewport hack for Surface/desktop Windows 8 bug 18 | // 19 | // See Getting Started docs for more information 20 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 21 | var msViewportStyle = document.createElement("style"); 22 | msViewportStyle.appendChild( 23 | document.createTextNode( 24 | "@-ms-viewport{width:auto!important}" 25 | ) 26 | ); 27 | document.getElementsByTagName("head")[0]. 28 | appendChild(msViewportStyle); 29 | } 30 | 31 | 32 | var $window = $(window) 33 | var $body = $(document.body) 34 | 35 | var navHeight = $('.navbar').outerHeight(true) + 10 36 | 37 | // scrollspy 38 | $body.scrollspy({ 39 | target: '.bs-sidebar', 40 | offset: navHeight 41 | }) 42 | 43 | $window.on('load', function () { 44 | $body.scrollspy('refresh') 45 | }) 46 | 47 | $('.bs-docs-container [href=#]').click(function (e) { 48 | e.preventDefault() 49 | }) 50 | 51 | $('.bs-sidebar').stick_in_parent({ 52 | offset_top: 56, 53 | spacer: false 54 | }); 55 | }) 56 | 57 | }(jQuery) 58 | -------------------------------------------------------------------------------- /docs/assets/js/ie8-responsive-file-warning.js: -------------------------------------------------------------------------------- 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT 2 | // IT'S JUST JUNK FOR OUR DOCS! 3 | // ++++++++++++++++++++++++++++++++++++++++++ 4 | /*! 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * 7 | * Licensed under the Creative Commons Attribution 3.0 Unported License. For 8 | * details, see http://creativecommons.org/licenses/by/3.0/. 9 | */ 10 | // Intended to prevent false-positive bug reports about responsive styling supposedly not working in IE8. 11 | if (window.location.protocol == 'file:') 12 | alert("ERROR: Bootstrap's responsive CSS is disabled!\nSee getbootstrap.com/getting-started/#respond-file-proto for details.") 13 | -------------------------------------------------------------------------------- /docs/assets/js/vendor/blob.js: -------------------------------------------------------------------------------- 1 | /* Blob.js 2 | * A Blob implementation. 3 | * 2013-12-27 4 | * 5 | * By Eli Grey, http://eligrey.com 6 | * By Devin Samarin, https://github.com/eboyjr 7 | * License: X11/MIT 8 | * See LICENSE.md 9 | */ 10 | 11 | /*global self, unescape */ 12 | /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, 13 | plusplus: true */ 14 | 15 | /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ 16 | 17 | if (!(typeof Blob === "function" || typeof Blob === "object") || typeof URL === "undefined") 18 | if ((typeof Blob === "function" || typeof Blob === "object") && typeof webkitURL !== "undefined") self.URL = webkitURL; 19 | else var Blob = (function (view) { 20 | "use strict"; 21 | 22 | var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) { 23 | var 24 | get_class = function(object) { 25 | return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; 26 | } 27 | , FakeBlobBuilder = function BlobBuilder() { 28 | this.data = []; 29 | } 30 | , FakeBlob = function Blob(data, type, encoding) { 31 | this.data = data; 32 | this.size = data.length; 33 | this.type = type; 34 | this.encoding = encoding; 35 | } 36 | , FBB_proto = FakeBlobBuilder.prototype 37 | , FB_proto = FakeBlob.prototype 38 | , FileReaderSync = view.FileReaderSync 39 | , FileException = function(type) { 40 | this.code = this[this.name = type]; 41 | } 42 | , file_ex_codes = ( 43 | "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " 44 | + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" 45 | ).split(" ") 46 | , file_ex_code = file_ex_codes.length 47 | , real_URL = view.URL || view.webkitURL || view 48 | , real_create_object_URL = real_URL.createObjectURL 49 | , real_revoke_object_URL = real_URL.revokeObjectURL 50 | , URL = real_URL 51 | , btoa = view.btoa 52 | , atob = view.atob 53 | 54 | , ArrayBuffer = view.ArrayBuffer 55 | , Uint8Array = view.Uint8Array 56 | ; 57 | FakeBlob.fake = FB_proto.fake = true; 58 | while (file_ex_code--) { 59 | FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; 60 | } 61 | if (!real_URL.createObjectURL) { 62 | URL = view.URL = {}; 63 | } 64 | URL.createObjectURL = function(blob) { 65 | var 66 | type = blob.type 67 | , data_URI_header 68 | ; 69 | if (type === null) { 70 | type = "application/octet-stream"; 71 | } 72 | if (blob instanceof FakeBlob) { 73 | data_URI_header = "data:" + type; 74 | if (blob.encoding === "base64") { 75 | return data_URI_header + ";base64," + blob.data; 76 | } else if (blob.encoding === "URI") { 77 | return data_URI_header + "," + decodeURIComponent(blob.data); 78 | } if (btoa) { 79 | return data_URI_header + ";base64," + btoa(blob.data); 80 | } else { 81 | return data_URI_header + "," + encodeURIComponent(blob.data); 82 | } 83 | } else if (real_create_object_URL) { 84 | return real_create_object_URL.call(real_URL, blob); 85 | } 86 | }; 87 | URL.revokeObjectURL = function(object_URL) { 88 | if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { 89 | real_revoke_object_URL.call(real_URL, object_URL); 90 | } 91 | }; 92 | FBB_proto.append = function(data/*, endings*/) { 93 | var bb = this.data; 94 | // decode data to a binary string 95 | if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { 96 | var 97 | str = "" 98 | , buf = new Uint8Array(data) 99 | , i = 0 100 | , buf_len = buf.length 101 | ; 102 | for (; i < buf_len; i++) { 103 | str += String.fromCharCode(buf[i]); 104 | } 105 | bb.push(str); 106 | } else if (get_class(data) === "Blob" || get_class(data) === "File") { 107 | if (FileReaderSync) { 108 | var fr = new FileReaderSync; 109 | bb.push(fr.readAsBinaryString(data)); 110 | } else { 111 | // async FileReader won't work as BlobBuilder is sync 112 | throw new FileException("NOT_READABLE_ERR"); 113 | } 114 | } else if (data instanceof FakeBlob) { 115 | if (data.encoding === "base64" && atob) { 116 | bb.push(atob(data.data)); 117 | } else if (data.encoding === "URI") { 118 | bb.push(decodeURIComponent(data.data)); 119 | } else if (data.encoding === "raw") { 120 | bb.push(data.data); 121 | } 122 | } else { 123 | if (typeof data !== "string") { 124 | data += ""; // convert unsupported types to strings 125 | } 126 | // decode UTF-16 to binary string 127 | bb.push(unescape(encodeURIComponent(data))); 128 | } 129 | }; 130 | FBB_proto.getBlob = function(type) { 131 | if (!arguments.length) { 132 | type = null; 133 | } 134 | return new FakeBlob(this.data.join(""), type, "raw"); 135 | }; 136 | FBB_proto.toString = function() { 137 | return "[object BlobBuilder]"; 138 | }; 139 | FB_proto.slice = function(start, end, type) { 140 | var args = arguments.length; 141 | if (args < 3) { 142 | type = null; 143 | } 144 | return new FakeBlob( 145 | this.data.slice(start, args > 1 ? end : this.data.length) 146 | , type 147 | , this.encoding 148 | ); 149 | }; 150 | FB_proto.toString = function() { 151 | return "[object Blob]"; 152 | }; 153 | return FakeBlobBuilder; 154 | }(view)); 155 | 156 | return function Blob(blobParts, options) { 157 | var type = options ? (options.type || "") : ""; 158 | var builder = new BlobBuilder(); 159 | if (blobParts) { 160 | for (var i = 0, len = blobParts.length; i < len; i++) { 161 | builder.append(blobParts[i]); 162 | } 163 | } 164 | return builder.getBlob(type); 165 | }; 166 | }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); 167 | -------------------------------------------------------------------------------- /docs/assets/js/vendor/filesaver.js: -------------------------------------------------------------------------------- 1 | /* FileSaver.js 2 | * A saveAs() FileSaver implementation. 3 | * 2014-01-24 4 | * 5 | * By Eli Grey, http://eligrey.com 6 | * License: X11/MIT 7 | * See LICENSE.md 8 | */ 9 | 10 | /*global self */ 11 | /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, 12 | plusplus: true */ 13 | 14 | /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ 15 | 16 | var saveAs = saveAs 17 | // IE 10+ (native saveAs) 18 | || (navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator)) 19 | // Everyone else 20 | || (function(view) { 21 | "use strict"; 22 | // IE <10 is explicitly unsupported 23 | if (/MSIE [1-9]\./.test(navigator.userAgent)) { 24 | return; 25 | } 26 | var 27 | doc = view.document 28 | // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet 29 | , get_URL = function() { 30 | return view.URL || view.webkitURL || view; 31 | } 32 | , URL = view.URL || view.webkitURL || view 33 | , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") 34 | , can_use_save_link = !view.externalHost && "download" in save_link 35 | , click = function(node) { 36 | var event = doc.createEvent("MouseEvents"); 37 | event.initMouseEvent( 38 | "click", true, false, view, 0, 0, 0, 0, 0 39 | , false, false, false, false, 0, null 40 | ); 41 | node.dispatchEvent(event); 42 | } 43 | , webkit_req_fs = view.webkitRequestFileSystem 44 | , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem 45 | , throw_outside = function (ex) { 46 | (view.setImmediate || view.setTimeout)(function() { 47 | throw ex; 48 | }, 0); 49 | } 50 | , force_saveable_type = "application/octet-stream" 51 | , fs_min_size = 0 52 | , deletion_queue = [] 53 | , process_deletion_queue = function() { 54 | var i = deletion_queue.length; 55 | while (i--) { 56 | var file = deletion_queue[i]; 57 | if (typeof file === "string") { // file is an object URL 58 | URL.revokeObjectURL(file); 59 | } else { // file is a File 60 | file.remove(); 61 | } 62 | } 63 | deletion_queue.length = 0; // clear queue 64 | } 65 | , dispatch = function(filesaver, event_types, event) { 66 | event_types = [].concat(event_types); 67 | var i = event_types.length; 68 | while (i--) { 69 | var listener = filesaver["on" + event_types[i]]; 70 | if (typeof listener === "function") { 71 | try { 72 | listener.call(filesaver, event || filesaver); 73 | } catch (ex) { 74 | throw_outside(ex); 75 | } 76 | } 77 | } 78 | } 79 | , FileSaver = function(blob, name) { 80 | // First try a.download, then web filesystem, then object URLs 81 | var 82 | filesaver = this 83 | , type = blob.type 84 | , blob_changed = false 85 | , object_url 86 | , target_view 87 | , get_object_url = function() { 88 | var object_url = get_URL().createObjectURL(blob); 89 | deletion_queue.push(object_url); 90 | return object_url; 91 | } 92 | , dispatch_all = function() { 93 | dispatch(filesaver, "writestart progress write writeend".split(" ")); 94 | } 95 | // on any filesys errors revert to saving with object URLs 96 | , fs_error = function() { 97 | // don't create more object URLs than needed 98 | if (blob_changed || !object_url) { 99 | object_url = get_object_url(blob); 100 | } 101 | if (target_view) { 102 | target_view.location.href = object_url; 103 | } else { 104 | window.open(object_url, "_blank"); 105 | } 106 | filesaver.readyState = filesaver.DONE; 107 | dispatch_all(); 108 | } 109 | , abortable = function(func) { 110 | return function() { 111 | if (filesaver.readyState !== filesaver.DONE) { 112 | return func.apply(this, arguments); 113 | } 114 | }; 115 | } 116 | , create_if_not_found = {create: true, exclusive: false} 117 | , slice 118 | ; 119 | filesaver.readyState = filesaver.INIT; 120 | if (!name) { 121 | name = "download"; 122 | } 123 | if (can_use_save_link) { 124 | object_url = get_object_url(blob); 125 | // FF for Android has a nasty garbage collection mechanism 126 | // that turns all objects that are not pure javascript into 'deadObject' 127 | // this means `doc` and `save_link` are unusable and need to be recreated 128 | // `view` is usable though: 129 | doc = view.document; 130 | save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"); 131 | save_link.href = object_url; 132 | save_link.download = name; 133 | var event = doc.createEvent("MouseEvents"); 134 | event.initMouseEvent( 135 | "click", true, false, view, 0, 0, 0, 0, 0 136 | , false, false, false, false, 0, null 137 | ); 138 | save_link.dispatchEvent(event); 139 | filesaver.readyState = filesaver.DONE; 140 | dispatch_all(); 141 | return; 142 | } 143 | // Object and web filesystem URLs have a problem saving in Google Chrome when 144 | // viewed in a tab, so I force save with application/octet-stream 145 | // http://code.google.com/p/chromium/issues/detail?id=91158 146 | if (view.chrome && type && type !== force_saveable_type) { 147 | slice = blob.slice || blob.webkitSlice; 148 | blob = slice.call(blob, 0, blob.size, force_saveable_type); 149 | blob_changed = true; 150 | } 151 | // Since I can't be sure that the guessed media type will trigger a download 152 | // in WebKit, I append .download to the filename. 153 | // https://bugs.webkit.org/show_bug.cgi?id=65440 154 | if (webkit_req_fs && name !== "download") { 155 | name += ".download"; 156 | } 157 | if (type === force_saveable_type || webkit_req_fs) { 158 | target_view = view; 159 | } 160 | if (!req_fs) { 161 | fs_error(); 162 | return; 163 | } 164 | fs_min_size += blob.size; 165 | req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { 166 | fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { 167 | var save = function() { 168 | dir.getFile(name, create_if_not_found, abortable(function(file) { 169 | file.createWriter(abortable(function(writer) { 170 | writer.onwriteend = function(event) { 171 | target_view.location.href = file.toURL(); 172 | deletion_queue.push(file); 173 | filesaver.readyState = filesaver.DONE; 174 | dispatch(filesaver, "writeend", event); 175 | }; 176 | writer.onerror = function() { 177 | var error = writer.error; 178 | if (error.code !== error.ABORT_ERR) { 179 | fs_error(); 180 | } 181 | }; 182 | "writestart progress write abort".split(" ").forEach(function(event) { 183 | writer["on" + event] = filesaver["on" + event]; 184 | }); 185 | writer.write(blob); 186 | filesaver.abort = function() { 187 | writer.abort(); 188 | filesaver.readyState = filesaver.DONE; 189 | }; 190 | filesaver.readyState = filesaver.WRITING; 191 | }), fs_error); 192 | }), fs_error); 193 | }; 194 | dir.getFile(name, {create: false}, abortable(function(file) { 195 | // delete file if it already exists 196 | file.remove(); 197 | save(); 198 | }), abortable(function(ex) { 199 | if (ex.code === ex.NOT_FOUND_ERR) { 200 | save(); 201 | } else { 202 | fs_error(); 203 | } 204 | })); 205 | }), fs_error); 206 | }), fs_error); 207 | } 208 | , FS_proto = FileSaver.prototype 209 | , saveAs = function(blob, name) { 210 | return new FileSaver(blob, name); 211 | } 212 | ; 213 | FS_proto.abort = function() { 214 | var filesaver = this; 215 | filesaver.readyState = filesaver.DONE; 216 | dispatch(filesaver, "abort"); 217 | }; 218 | FS_proto.readyState = FS_proto.INIT = 0; 219 | FS_proto.WRITING = 1; 220 | FS_proto.DONE = 2; 221 | 222 | FS_proto.error = 223 | FS_proto.onwritestart = 224 | FS_proto.onprogress = 225 | FS_proto.onwrite = 226 | FS_proto.onabort = 227 | FS_proto.onerror = 228 | FS_proto.onwriteend = 229 | null; 230 | 231 | view.addEventListener("unload", process_deletion_queue, false); 232 | return saveAs; 233 | }( 234 | typeof self !== "undefined" && self 235 | || typeof window !== "undefined" && window 236 | || this.content 237 | )); 238 | // `self` is undefined in Firefox for Android content script context 239 | // while `this` is nsIContentFrameMessageManager 240 | // with an attribute `content` that corresponds to the window 241 | 242 | if (typeof module !== "undefined") module.exports = saveAs; 243 | -------------------------------------------------------------------------------- /docs/examples/navbar-offcanvas/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Navbar Template for Bootstrap 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 66 | 67 | 68 |
69 |

Offcanvas Navbar example

70 |

This example demonstrates using the offcanvas plugin with the navbar.

71 |
72 | 73 |

74 | By default the navbar is show on the right side of the screen. You can show it on the left side instead by 75 | adding .navmenu-fixed-left to the .navbar-offcanvas. 76 |

77 |
78 | 79 | 80 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /docs/examples/navbar-offcanvas/navbar-offcanvas.css: -------------------------------------------------------------------------------- 1 | body { 2 | left: auto!important; 3 | padding-top: 80px; 4 | padding-bottom: 20px; 5 | } 6 | 7 | @media (min-width: 992px) { 8 | .navbar { 9 | padding-right: 15px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/examples/navmenu-push/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Off Canvas Push Menu Template for Bootstrap 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 56 | 57 | 62 | 63 |
64 | 67 |

This example demonstrates the use of the offcanvas plugin with a push effect.

68 |

You get the push effect by setting the canvas option to 'body'.

69 |

Also take a look at the example for a navmenu with slide in effect and reveal effect.

70 |
71 | 72 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/examples/navmenu-push/navmenu-push.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | padding: 70px 0 0 0; 7 | } 8 | 9 | .navbar-toggle { 10 | float: left; 11 | margin-left: 15px; 12 | } 13 | 14 | @media (min-width: 0) { 15 | .navbar-toggle { 16 | display: block; /* force showing the toggle */ 17 | } 18 | } 19 | 20 | @media (min-width: 992px) { 21 | body { 22 | padding: 0; 23 | } 24 | .navbar { 25 | right: auto; 26 | background: none; 27 | border: none; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docs/examples/navmenu-reveal/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Off Canvas Reveal Menu Template for Bootstrap 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 56 | 57 |
58 | 63 | 64 |
65 | 68 |

This example demonstrates the use of the offcanvas plugin with a reveal effect.

69 |

On the contrary of the push effect, the menu doesn't move with the canvas.

70 |

You get the reveal effect by wrapping the content in a div and setting the canvas option to target that div.

71 |

Note that in this example, the navmenu doesn't have the offcanvas class, but is placed under the canvas by setting the z-index.

72 |

Also take a look at the examples for a navmenu with slide in effect and push effect.

73 |
74 |
75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/examples/navmenu-reveal/navmenu-reveal.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | body { 5 | padding: 20px 0 0 0; 6 | } 7 | 8 | .navmenu { 9 | z-index: 1; 10 | } 11 | 12 | .canvas { 13 | position: relative; 14 | left: 0; 15 | z-index: 2; 16 | min-height: 100%; 17 | padding: 50px 0 0 0; 18 | background: #fff; 19 | } 20 | 21 | @media (min-width: 992px) { 22 | body { 23 | padding: 0; 24 | } 25 | .navbar { 26 | right: auto; 27 | background: none; 28 | border: none; 29 | } 30 | .canvas { 31 | padding: 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/examples/navmenu/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Off Canvas Slide-in Menu Template for Bootstrap 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 55 | 56 | 62 | 63 |
64 | 67 |

This example shows the navmenu element. If the viewport is less than 992px the menu will be placed the off canvas and will be shown with a slide in effect.

68 |

Also take a look at the examples for a navmenu with push effect and reveal effect.

69 |
70 | 71 | 72 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/examples/navmenu/navmenu.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | body { 5 | padding: 70px 0 0 0; 6 | } 7 | 8 | .navmenu { 9 | padding-top: 50px; 10 | } 11 | 12 | .navbar { 13 | display: block; 14 | text-align: center; 15 | } 16 | .navbar-brand { 17 | display: inline-block; 18 | float: none; 19 | } 20 | .navbar-toggler { 21 | position: absolute; 22 | float: left; 23 | } 24 | 25 | .container { 26 | max-width: 100%; 27 | } 28 | 29 | @media (min-width: 1px) { 30 | .navbar-toggler { 31 | display: block !important; 32 | } 33 | } 34 | 35 | @media (min-width: 992px) { 36 | body { 37 | padding: 0 0 0 300px; 38 | } 39 | .navmenu { 40 | padding-top: 0; 41 | } 42 | .navbar { 43 | display: none !important; /* IE8 fix */ 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/examples/screenshots/navbar-offcanvas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/examples/screenshots/navbar-offcanvas.jpg -------------------------------------------------------------------------------- /docs/examples/screenshots/navmenu-push.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/examples/screenshots/navmenu-push.jpg -------------------------------------------------------------------------------- /docs/examples/screenshots/navmenu-reveal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/examples/screenshots/navmenu-reveal.jpg -------------------------------------------------------------------------------- /docs/examples/screenshots/navmenu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/examples/screenshots/navmenu.jpg -------------------------------------------------------------------------------- /docs/examples/screenshots/starter-template.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jasny/bootstrap/7258cacb830b884214ef9df85a2169e885756404/docs/examples/screenshots/starter-template.jpg -------------------------------------------------------------------------------- /docs/examples/starter-template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Starter Template for Bootstrap 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 49 | 50 |
51 | 52 |
53 |

Bootstrap starter template

54 |

Use this document as a way to quickly start any new project.
All you get is this text and a mostly barebones HTML document.

55 |
56 | 57 |
58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /docs/examples/starter-template/starter-template.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | padding-top: 50px; 4 | } 5 | .starter-template 6 | { 7 | padding: 40px 15px; 8 | text-align: center; 9 | } 10 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | title: Jasny Bootstrap 4 | --- 5 | 6 |
7 |
8 |

{{ page.title }}

9 |

The missing components for your favorite front-end framework.

10 |

11 | Download 12 | or Download source 13 |

14 |
15 |
16 | -------------------------------------------------------------------------------- /docs/jade/customizer-nav.jade: -------------------------------------------------------------------------------- 1 | // NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template. 2 | li 3 | a(href='#less') Less components 4 | li 5 | a(href='#plugins') jQuery plugins 6 | li 7 | a(href='#less-variables') Less variables 8 | ul.nav 9 | each section in sections 10 | if section.customizable 11 | li 12 | a(href='#'+section.id)= section.heading 13 | li 14 | a(href='#download') Download 15 | // NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template. 16 | -------------------------------------------------------------------------------- /docs/jade/customizer-variables.jade: -------------------------------------------------------------------------------- 1 | // NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-variables.jade template. 2 | each section in sections 3 | if section.customizable 4 | h2(id=section.id)= section.heading 5 | if section.docstring 6 | p!= section.docstring.html 7 | each subsection in section.subsections 8 | if subsection.heading 9 | h3(id=subsection.id)= subsection.heading 10 | div.row 11 | each variable in subsection.variables 12 | div.bs-customizer-input 13 | label(for="input-" + variable.name)= variable.name 14 | input.form-control( 15 | id="input-" + variable.name 16 | type="text" 17 | value=variable.defaultValue 18 | data-var=variable.name) 19 | if variable.docstring 20 | p.help-block!= variable.docstring.html 21 | // NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-variables.jade template. 22 | -------------------------------------------------------------------------------- /grunt/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi": false, 3 | "camelcase": true, 4 | "curly": true, 5 | "eqeqeq": true, 6 | "immed": true, 7 | "indent": 2, 8 | "newcap": true, 9 | "noarg": true, 10 | "nonbsp": true, 11 | "quotmark": "single", 12 | "undef": true, 13 | "strict": true, 14 | "trailing": true, 15 | "node" : true 16 | } 17 | -------------------------------------------------------------------------------- /grunt/bs-lessdoc-parser.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grunt task for parsing Less docstrings 3 | * http://getbootstrap.com 4 | * Copyright 2014 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 'use strict'; 8 | 9 | var markdown = require('markdown').markdown; 10 | 11 | function markdown2html(markdownString) { 12 | // the slice removes the

...

wrapper output by Markdown processor 13 | return markdown.toHTML(markdownString.trim()).slice(3, -4); 14 | } 15 | 16 | 17 | /* 18 | Mini-language: 19 | //== This is a normal heading, which starts a section. Sections group variables together. 20 | //## Optional description for the heading 21 | 22 | //=== This is a subheading. 23 | 24 | //** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `` stuff. 25 | @foo: #ffff; 26 | 27 | //-- This is a heading for a section whose variables shouldn't be customizable 28 | 29 | All other lines are ignored completely. 30 | */ 31 | 32 | 33 | var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/; 34 | var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/; 35 | var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/; 36 | var SECTION_DOCSTRING = /^[/]{2}#{2}(.*)$/; 37 | var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]+);[ ]*$/; 38 | var VAR_DOCSTRING = /^[/]{2}[*]{2}(.*)$/; 39 | 40 | function Section(heading, customizable) { 41 | this.heading = heading.trim(); 42 | this.id = this.heading.replace(/\s+/g, '-').toLowerCase(); 43 | this.customizable = customizable; 44 | this.docstring = null; 45 | this.subsections = []; 46 | } 47 | 48 | Section.prototype.addSubSection = function (subsection) { 49 | this.subsections.push(subsection); 50 | }; 51 | 52 | function SubSection(heading) { 53 | this.heading = heading.trim(); 54 | this.id = this.heading.replace(/\s+/g, '-').toLowerCase(); 55 | this.variables = []; 56 | } 57 | 58 | SubSection.prototype.addVar = function (variable) { 59 | this.variables.push(variable); 60 | }; 61 | 62 | function VarDocstring(markdownString) { 63 | this.html = markdown2html(markdownString); 64 | } 65 | 66 | function SectionDocstring(markdownString) { 67 | this.html = markdown2html(markdownString); 68 | } 69 | 70 | function Variable(name, defaultValue) { 71 | this.name = name; 72 | this.defaultValue = defaultValue; 73 | this.docstring = null; 74 | } 75 | 76 | function Tokenizer(fileContent) { 77 | this._lines = fileContent.split('\n'); 78 | this._next = undefined; 79 | } 80 | 81 | Tokenizer.prototype.unshift = function (token) { 82 | if (this._next !== undefined) { 83 | throw new Error('Attempted to unshift twice!'); 84 | } 85 | this._next = token; 86 | }; 87 | 88 | Tokenizer.prototype._shift = function () { 89 | // returning null signals EOF 90 | // returning undefined means the line was ignored 91 | if (this._next !== undefined) { 92 | var result = this._next; 93 | this._next = undefined; 94 | return result; 95 | } 96 | if (this._lines.length <= 0) { 97 | return null; 98 | } 99 | var line = this._lines.shift(); 100 | var match = null; 101 | match = SUBSECTION_HEADING.exec(line); 102 | if (match !== null) { 103 | return new SubSection(match[1]); 104 | } 105 | match = CUSTOMIZABLE_HEADING.exec(line); 106 | if (match !== null) { 107 | return new Section(match[1], true); 108 | } 109 | match = UNCUSTOMIZABLE_HEADING.exec(line); 110 | if (match !== null) { 111 | return new Section(match[1], false); 112 | } 113 | match = SECTION_DOCSTRING.exec(line); 114 | if (match !== null) { 115 | return new SectionDocstring(match[1]); 116 | } 117 | match = VAR_DOCSTRING.exec(line); 118 | if (match !== null) { 119 | return new VarDocstring(match[1]); 120 | } 121 | var commentStart = line.lastIndexOf('//'); 122 | var varLine = (commentStart === -1) ? line : line.slice(0, commentStart); 123 | match = VAR_ASSIGNMENT.exec(varLine); 124 | if (match !== null) { 125 | return new Variable(match[1], match[2]); 126 | } 127 | return undefined; 128 | }; 129 | 130 | Tokenizer.prototype.shift = function () { 131 | while (true) { 132 | var result = this._shift(); 133 | if (result === undefined) { 134 | continue; 135 | } 136 | return result; 137 | } 138 | }; 139 | 140 | function Parser(fileContent) { 141 | this._tokenizer = new Tokenizer(fileContent); 142 | } 143 | 144 | Parser.prototype.parseFile = function () { 145 | var sections = []; 146 | while (true) { 147 | var section = this.parseSection(); 148 | if (section === null) { 149 | if (this._tokenizer.shift() !== null) { 150 | throw new Error('Unexpected unparsed section of file remains!'); 151 | } 152 | return sections; 153 | } 154 | sections.push(section); 155 | } 156 | }; 157 | 158 | Parser.prototype.parseSection = function () { 159 | var section = this._tokenizer.shift(); 160 | if (section === null) { 161 | return null; 162 | } 163 | if (!(section instanceof Section)) { 164 | throw new Error('Expected section heading; got: ' + JSON.stringify(section)); 165 | } 166 | var docstring = this._tokenizer.shift(); 167 | if (docstring instanceof SectionDocstring) { 168 | section.docstring = docstring; 169 | } 170 | else { 171 | this._tokenizer.unshift(docstring); 172 | } 173 | this.parseSubSections(section); 174 | 175 | return section; 176 | }; 177 | 178 | Parser.prototype.parseSubSections = function (section) { 179 | while (true) { 180 | var subsection = this.parseSubSection(); 181 | if (subsection === null) { 182 | if (section.subsections.length === 0) { 183 | // Presume an implicit initial subsection 184 | subsection = new SubSection(''); 185 | this.parseVars(subsection); 186 | } 187 | else { 188 | break; 189 | } 190 | } 191 | section.addSubSection(subsection); 192 | } 193 | 194 | if (section.subsections.length === 1 && !(section.subsections[0].heading) && section.subsections[0].variables.length === 0) { 195 | // Ignore lone empty implicit subsection 196 | section.subsections = []; 197 | } 198 | }; 199 | 200 | Parser.prototype.parseSubSection = function () { 201 | var subsection = this._tokenizer.shift(); 202 | if (subsection instanceof SubSection) { 203 | this.parseVars(subsection); 204 | return subsection; 205 | } 206 | this._tokenizer.unshift(subsection); 207 | return null; 208 | }; 209 | 210 | Parser.prototype.parseVars = function (subsection) { 211 | while (true) { 212 | var variable = this.parseVar(); 213 | if (variable === null) { 214 | return; 215 | } 216 | subsection.addVar(variable); 217 | } 218 | }; 219 | 220 | Parser.prototype.parseVar = function () { 221 | var docstring = this._tokenizer.shift(); 222 | if (!(docstring instanceof VarDocstring)) { 223 | this._tokenizer.unshift(docstring); 224 | docstring = null; 225 | } 226 | var variable = this._tokenizer.shift(); 227 | if (variable instanceof Variable) { 228 | variable.docstring = docstring; 229 | return variable; 230 | } 231 | this._tokenizer.unshift(variable); 232 | return null; 233 | }; 234 | 235 | 236 | module.exports = Parser; 237 | -------------------------------------------------------------------------------- /grunt/bs-raw-files-generator.js: -------------------------------------------------------------------------------- 1 | /* global btoa: true */ 2 | /*! 3 | * Bootstrap Grunt task for generating raw-files.min.js for the Customizer 4 | * http://getbootstrap.com 5 | * Copyright 2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | */ 8 | 'use strict'; 9 | 10 | var btoa = require('btoa'); 11 | var fs = require('fs'); 12 | 13 | function getFiles(type, subdirs, exclude) { 14 | var files = {}; 15 | exclude = exclude || []; 16 | 17 | subdirs.forEach(function (subdir) { 18 | var sub = subdir ? subdir + '/' : ''; 19 | fs.readdirSync(type + '/' + sub) 20 | .filter(function (path) { 21 | return new RegExp('\\.' + type + '$').test(path) && exclude.indexOf(sub + path) === -1; 22 | }) 23 | .forEach(function (path) { 24 | var fullPath = type + '/' + sub + path; 25 | files[sub + path] = fs.readFileSync(fullPath, 'utf8'); 26 | }); 27 | }); 28 | 29 | return 'var __' + type + ' = ' + JSON.stringify(files) + '\n'; 30 | } 31 | 32 | module.exports = function generateRawFilesJs(banner) { 33 | if (!banner) { 34 | banner = ''; 35 | } 36 | var files = banner + getFiles('js', ['']) + getFiles('less', ['', 'build'], ['build/jasny-bootstrap.less']); 37 | fs.writeFileSync('docs/assets/js/raw-files.min.js', files); 38 | }; 39 | -------------------------------------------------------------------------------- /grunt/shrinkwrap.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grunt task for generating npm-shrinkwrap.canonical.json 3 | * http://getbootstrap.com 4 | * Copyright 2014 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | /* 8 | This Grunt task updates the npm-shrinkwrap.canonical.json file that's used as the key for Bootstrap's npm packages cache. 9 | This task should be run and the updated file should be committed whenever Bootstrap's dependencies change. 10 | */ 11 | 'use strict'; 12 | 13 | var canonicallyJsonStringify = require('canonical-json'); 14 | var NON_CANONICAL_FILE = 'npm-shrinkwrap.json'; 15 | var DEST_FILE = 'test-infra/npm-shrinkwrap.canonical.json'; 16 | 17 | 18 | function updateShrinkwrap(grunt) { 19 | // Assumption: Non-canonical shrinkwrap already generated by prerequisite Grunt task 20 | var shrinkwrapData = grunt.file.readJSON(NON_CANONICAL_FILE); 21 | grunt.log.writeln('Deleting ' + NON_CANONICAL_FILE.cyan + '...'); 22 | grunt.file.delete(NON_CANONICAL_FILE); 23 | // Output as Canonical JSON in correct location 24 | grunt.file.write(DEST_FILE, canonicallyJsonStringify(shrinkwrapData)); 25 | grunt.log.writeln('File ' + DEST_FILE.cyan + ' updated.'); 26 | } 27 | 28 | 29 | module.exports = updateShrinkwrap; 30 | -------------------------------------------------------------------------------- /js/.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "disallowEmptyBlocks": true, 3 | "disallowKeywords": ["with"], 4 | "disallowMixedSpacesAndTabs": true, 5 | "disallowMultipleLineStrings": true, 6 | "disallowMultipleVarDecl": true, 7 | "disallowQuotedKeysInObjects": "allButReserved", 8 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 9 | "disallowSpaceBeforeBinaryOperators": [","], 10 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 11 | "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, 12 | "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, 13 | "disallowSpacesInsideArrayBrackets": true, 14 | "disallowSpacesInsideParentheses": true, 15 | "disallowTrailingComma": true, 16 | "disallowTrailingWhitespace": true, 17 | "requireCamelCaseOrUpperCaseIdentifiers": true, 18 | "requireCapitalizedConstructors": true, 19 | "requireCommaBeforeLineBreak": true, 20 | "requireDollarBeforejQueryAssignment": true, 21 | "requireDotNotation": true, 22 | "requireLineFeedAtFileEnd": true, 23 | "requirePaddingNewLinesAfterUseStrict": true, 24 | "requirePaddingNewLinesBeforeExport": true, 25 | "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], 26 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], 27 | "requireSpaceAfterLineComment": true, 28 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], 29 | "requireSpaceBetweenArguments": true, 30 | "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningCurlyBrace": true, "beforeOpeningRoundBrace": true }, 31 | "requireSpacesInConditionalExpression": true, 32 | "requireSpacesInForStatement": true, 33 | "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, 34 | "requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true }, 35 | "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, 36 | "requireSpacesInsideObjectBrackets": "allButNested", 37 | "validateAlignedFunctionParameters": true, 38 | "validateIndentation": 2, 39 | "validateLineBreaks": "LF", 40 | "validateNewlineAfterArrayElements": true, 41 | "validateQuoteMarks": "'" 42 | } 43 | 44 | -------------------------------------------------------------------------------- /js/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi" : true, 3 | "boss" : true, 4 | "browser" : true, 5 | "curly" : false, 6 | "debug" : true, 7 | "devel" : true, 8 | "eqeqeq" : false, 9 | "eqnull" : true, 10 | "expr" : true, 11 | "laxbreak" : true, 12 | "laxcomma" : true, 13 | "validthis": true 14 | } -------------------------------------------------------------------------------- /js/rowlink.js: -------------------------------------------------------------------------------- 1 | /* ============================================================ 2 | * Bootstrap: rowlink.js v4.0.0 3 | * http://jasny.github.io/bootstrap/javascript/#rowlink 4 | * ============================================================ 5 | * Copyright 2012-2014 Arnold Daniels 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ============================================================ */ 19 | 20 | +function ($) { "use strict"; 21 | 22 | var Rowlink = function (element, options) { 23 | this.$element = $(element) 24 | this.options = $.extend({}, Rowlink.DEFAULTS, options) 25 | 26 | this.$element.on('click.bs.rowlink mouseup.bs.rowlink', 'td:not(.rowlink-skip)', $.proxy(this.click, this)) 27 | } 28 | 29 | Rowlink.DEFAULTS = { 30 | target: "a" 31 | } 32 | 33 | Rowlink.prototype.click = function(e, ctrlKey) { 34 | var target = $(e.currentTarget).closest('tr').find(this.options.target)[0] 35 | 36 | if (typeof target === 'undefined' || $(e.target)[0] === target) return 37 | if (e.type === 'mouseup' && e.which !== 2) return 38 | 39 | e.preventDefault(); 40 | ctrlKey = ctrlKey || e.ctrlKey || (e.type === 'mouseup' && e.which === 2) 41 | 42 | if (!ctrlKey && target.click) { 43 | target.click() 44 | } else if (document.createEvent) { 45 | var evt = new MouseEvent("click", { 46 | view: window, 47 | bubbles: true, 48 | cancelable: true, 49 | ctrlKey: ctrlKey 50 | }); 51 | target.dispatchEvent(evt); 52 | } 53 | } 54 | 55 | 56 | // ROWLINK PLUGIN DEFINITION 57 | // =========================== 58 | 59 | var old = $.fn.rowlink 60 | 61 | $.fn.rowlink = function (options) { 62 | return this.each(function () { 63 | var $this = $(this) 64 | var data = $this.data('bs.rowlink') 65 | if (!data) $this.data('bs.rowlink', (data = new Rowlink(this, options))) 66 | }) 67 | } 68 | 69 | $.fn.rowlink.Constructor = Rowlink 70 | 71 | 72 | // ROWLINK NO CONFLICT 73 | // ==================== 74 | 75 | $.fn.rowlink.noConflict = function () { 76 | $.fn.rowlink = old 77 | return this 78 | } 79 | 80 | 81 | // ROWLINK DATA-API 82 | // ================== 83 | 84 | $(document).on('click.bs.rowlink.data-api mouseup.bs.rowlink.data-api', '[data-link="row"]', function (e) { 85 | if (e.type === 'mouseup' && e.which !== 2) return 86 | if ($(e.target).closest('.rowlink-skip').length !== 0) return 87 | 88 | var $this = $(this) 89 | if ($this.data('bs.rowlink')) return 90 | $this.rowlink($this.data()) 91 | 92 | var ctrlKey = e.ctrlKey || e.which === 2 93 | $(e.target).trigger('click.bs.rowlink', [ctrlKey]) 94 | }) 95 | 96 | }(window.jQuery); 97 | -------------------------------------------------------------------------------- /js/tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bootstrap Plugin Test Suite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /js/tests/unit/fileinput.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module('fileinput') 4 | 5 | test('should provide no conflict', function () { 6 | var fileinput = $.fn.fileinput.noConflict() 7 | ok(!$.fn.fileinput, 'fileinput was set back to undefined (org value)') 8 | $.fn.fileinput = fileinput 9 | }) 10 | 11 | test('should be defined on jquery object', function () { 12 | ok($(document.body).fileinput, 'fileinput method is defined') 13 | }) 14 | 15 | test('should return element', function () { 16 | ok($(document.body).fileinput()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | // TODO: add fileinput tests 20 | }) 21 | -------------------------------------------------------------------------------- /js/tests/unit/offcanvas.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module('offcanvas') 4 | 5 | test('should provide no conflict', function () { 6 | var offcanvas = $.fn.offcanvas.noConflict() 7 | ok(!$.fn.offcanvas, 'offcanvas was set back to undefined (org value)') 8 | $.fn.offcanvas = offcanvas 9 | }) 10 | 11 | test('should be defined on jquery object', function () { 12 | ok($(document.body).offcanvas, 'offcanvas method is defined') 13 | }) 14 | 15 | test('should return element', function () { 16 | ok($(document.body).offcanvas()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | // TODO: add offcanvas tests 20 | }) 21 | -------------------------------------------------------------------------------- /js/tests/unit/phantom.js: -------------------------------------------------------------------------------- 1 | /* 2 | * grunt-contrib-qunit 3 | * http://gruntjs.com/ 4 | * 5 | * Copyright (c) 2013 'Cowboy' Ben Alman, contributors 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | /*global QUnit:true, alert:true*/ 10 | (function () { 11 | 'use strict'; 12 | 13 | // Don't re-order tests. 14 | QUnit.config.reorder = false 15 | // Run tests serially, not in parallel. 16 | QUnit.config.autorun = false 17 | 18 | // Send messages to the parent PhantomJS process via alert! Good times!! 19 | function sendMessage() { 20 | var args = [].slice.call(arguments) 21 | alert(JSON.stringify(args)) 22 | } 23 | 24 | // These methods connect QUnit to PhantomJS. 25 | QUnit.log = function (obj) { 26 | // What is this I don’t even 27 | if (obj.message === '[object Object], undefined:undefined') { return } 28 | // Parse some stuff before sending it. 29 | var actual = QUnit.jsDump.parse(obj.actual) 30 | var expected = QUnit.jsDump.parse(obj.expected) 31 | // Send it. 32 | sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source) 33 | } 34 | 35 | QUnit.testStart = function (obj) { 36 | sendMessage('qunit.testStart', obj.name) 37 | } 38 | 39 | QUnit.testDone = function (obj) { 40 | sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total) 41 | } 42 | 43 | QUnit.moduleStart = function (obj) { 44 | sendMessage('qunit.moduleStart', obj.name) 45 | } 46 | 47 | QUnit.begin = function () { 48 | sendMessage('qunit.begin') 49 | console.log('Starting test suite') 50 | console.log('================================================\n') 51 | } 52 | 53 | QUnit.moduleDone = function (opts) { 54 | if (opts.failed === 0) { 55 | console.log('\r\u2714 All tests passed in "' + opts.name + '" module') 56 | } else { 57 | console.log('\u2716 ' + opts.failed + ' tests failed in "' + opts.name + '" module') 58 | } 59 | sendMessage('qunit.moduleDone', opts.name, opts.failed, opts.passed, opts.total) 60 | } 61 | 62 | QUnit.done = function (opts) { 63 | console.log('\n================================================') 64 | console.log('Tests completed in ' + opts.runtime + ' milliseconds') 65 | console.log(opts.passed + ' tests of ' + opts.total + ' passed, ' + opts.failed + ' failed.') 66 | sendMessage('qunit.done', opts.failed, opts.passed, opts.total, opts.runtime) 67 | } 68 | 69 | }()) 70 | -------------------------------------------------------------------------------- /js/tests/unit/rowlink.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module('rowlink') 4 | 5 | test('should provide no conflict', function () { 6 | var rowlink = $.fn.rowlink.noConflict() 7 | ok(!$.fn.rowlink, 'rowlink was set back to undefined (org value)') 8 | $.fn.rowlink = rowlink 9 | }) 10 | 11 | test('should be defined on jquery object', function () { 12 | ok($(document.body).rowlink, 'rowlink method is defined') 13 | }) 14 | 15 | test('should return element', function () { 16 | ok($(document.body).rowlink()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | // TODO: add rowlink tests 20 | }) 21 | -------------------------------------------------------------------------------- /js/tests/vendor/qunit.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * QUnit 1.13.0 3 | * http://qunitjs.com/ 4 | * 5 | * Copyright 2013 jQuery Foundation and other contributors 6 | * Released under the MIT license 7 | * http://jquery.org/license 8 | * 9 | * Date: 2014-01-04T17:09Z 10 | */ 11 | 12 | /** Font Family and Sizes */ 13 | 14 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { 15 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; 16 | } 17 | 18 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } 19 | #qunit-tests { font-size: smaller; } 20 | 21 | 22 | /** Resets */ 23 | 24 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { 25 | margin: 0; 26 | padding: 0; 27 | } 28 | 29 | 30 | /** Header */ 31 | 32 | #qunit-header { 33 | padding: 0.5em 0 0.5em 1em; 34 | 35 | color: #8699a4; 36 | background-color: #0d3349; 37 | 38 | font-size: 1.5em; 39 | line-height: 1em; 40 | font-weight: normal; 41 | 42 | border-radius: 5px 5px 0 0; 43 | -moz-border-radius: 5px 5px 0 0; 44 | -webkit-border-top-right-radius: 5px; 45 | -webkit-border-top-left-radius: 5px; 46 | } 47 | 48 | #qunit-header a { 49 | text-decoration: none; 50 | color: #c2ccd1; 51 | } 52 | 53 | #qunit-header a:hover, 54 | #qunit-header a:focus { 55 | color: #fff; 56 | } 57 | 58 | #qunit-testrunner-toolbar label { 59 | display: inline-block; 60 | padding: 0 .5em 0 .1em; 61 | } 62 | 63 | #qunit-banner { 64 | height: 5px; 65 | } 66 | 67 | #qunit-testrunner-toolbar { 68 | padding: 0.5em 0 0.5em 2em; 69 | color: #5E740B; 70 | background-color: #eee; 71 | overflow: hidden; 72 | } 73 | 74 | #qunit-userAgent { 75 | padding: 0.5em 0 0.5em 2.5em; 76 | background-color: #2b81af; 77 | color: #fff; 78 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; 79 | } 80 | 81 | #qunit-modulefilter-container { 82 | float: right; 83 | } 84 | 85 | /** Tests: Pass/Fail */ 86 | 87 | #qunit-tests { 88 | list-style-position: inside; 89 | } 90 | 91 | #qunit-tests li { 92 | padding: 0.4em 0.5em 0.4em 2.5em; 93 | border-bottom: 1px solid #fff; 94 | list-style-position: inside; 95 | } 96 | 97 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { 98 | display: none; 99 | } 100 | 101 | #qunit-tests li strong { 102 | cursor: pointer; 103 | } 104 | 105 | #qunit-tests li a { 106 | padding: 0.5em; 107 | color: #c2ccd1; 108 | text-decoration: none; 109 | } 110 | #qunit-tests li a:hover, 111 | #qunit-tests li a:focus { 112 | color: #000; 113 | } 114 | 115 | #qunit-tests li .runtime { 116 | float: right; 117 | font-size: smaller; 118 | } 119 | 120 | .qunit-assert-list { 121 | margin-top: 0.5em; 122 | padding: 0.5em; 123 | 124 | background-color: #fff; 125 | 126 | border-radius: 5px; 127 | -moz-border-radius: 5px; 128 | -webkit-border-radius: 5px; 129 | } 130 | 131 | .qunit-collapsed { 132 | display: none; 133 | } 134 | 135 | #qunit-tests table { 136 | border-collapse: collapse; 137 | margin-top: .2em; 138 | } 139 | 140 | #qunit-tests th { 141 | text-align: right; 142 | vertical-align: top; 143 | padding: 0 .5em 0 0; 144 | } 145 | 146 | #qunit-tests td { 147 | vertical-align: top; 148 | } 149 | 150 | #qunit-tests pre { 151 | margin: 0; 152 | white-space: pre-wrap; 153 | word-wrap: break-word; 154 | } 155 | 156 | #qunit-tests del { 157 | background-color: #e0f2be; 158 | color: #374e0c; 159 | text-decoration: none; 160 | } 161 | 162 | #qunit-tests ins { 163 | background-color: #ffcaca; 164 | color: #500; 165 | text-decoration: none; 166 | } 167 | 168 | /*** Test Counts */ 169 | 170 | #qunit-tests b.counts { color: black; } 171 | #qunit-tests b.passed { color: #5E740B; } 172 | #qunit-tests b.failed { color: #710909; } 173 | 174 | #qunit-tests li li { 175 | padding: 5px; 176 | background-color: #fff; 177 | border-bottom: none; 178 | list-style-position: inside; 179 | } 180 | 181 | /*** Passing Styles */ 182 | 183 | #qunit-tests li li.pass { 184 | color: #3c510c; 185 | background-color: #fff; 186 | border-left: 10px solid #C6E746; 187 | } 188 | 189 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } 190 | #qunit-tests .pass .test-name { color: #366097; } 191 | 192 | #qunit-tests .pass .test-actual, 193 | #qunit-tests .pass .test-expected { color: #999999; } 194 | 195 | #qunit-banner.qunit-pass { background-color: #C6E746; } 196 | 197 | /*** Failing Styles */ 198 | 199 | #qunit-tests li li.fail { 200 | color: #710909; 201 | background-color: #fff; 202 | border-left: 10px solid #EE5757; 203 | white-space: pre; 204 | } 205 | 206 | #qunit-tests > li:last-child { 207 | border-radius: 0 0 5px 5px; 208 | -moz-border-radius: 0 0 5px 5px; 209 | -webkit-border-bottom-right-radius: 5px; 210 | -webkit-border-bottom-left-radius: 5px; 211 | } 212 | 213 | #qunit-tests .fail { color: #000000; background-color: #EE5757; } 214 | #qunit-tests .fail .test-name, 215 | #qunit-tests .fail .module-name { color: #000000; } 216 | 217 | #qunit-tests .fail .test-actual { color: #EE5757; } 218 | #qunit-tests .fail .test-expected { color: green; } 219 | 220 | #qunit-banner.qunit-fail { background-color: #EE5757; } 221 | 222 | 223 | /** Result */ 224 | 225 | #qunit-testresult { 226 | padding: 0.5em 0.5em 0.5em 2.5em; 227 | 228 | color: #2b81af; 229 | background-color: #D2E0E6; 230 | 231 | border-bottom: 1px solid white; 232 | } 233 | #qunit-testresult .module-name { 234 | font-weight: bold; 235 | } 236 | 237 | /** Fixture */ 238 | 239 | #qunit-fixture { 240 | position: absolute; 241 | top: -10000px; 242 | left: -10000px; 243 | width: 1000px; 244 | height: 1000px; 245 | } 246 | -------------------------------------------------------------------------------- /js/transition.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: transition.js v4.0.0 3 | * http://getbootstrap.com/javascript/#transitions 4 | * ======================================================================== 5 | * Copyright 2011-2014 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 | if ($.support.transition !== undefined) return // Prevent conflict with vanilla Bootstrap 36 | 37 | // http://blog.alexmaccaw.com/css-transitions 38 | $.fn.emulateTransitionEnd = function (duration) { 39 | var called = false, $el = this 40 | $(this).one($.support.transition.end, function () { called = true }) 41 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 42 | setTimeout(callback, duration) 43 | return this 44 | } 45 | 46 | $(function () { 47 | $.support.transition = transitionEnd() 48 | }) 49 | 50 | }(window.jQuery); 51 | -------------------------------------------------------------------------------- /less/.csscomb.json: -------------------------------------------------------------------------------- 1 | { 2 | "always-semicolon": true, 3 | "block-indent": 2, 4 | "colon-space": true, 5 | "color-case": "lower", 6 | "color-shorthand": true, 7 | "combinator-space": true, 8 | "element-case": "lower", 9 | "eof-newline": true, 10 | "leading-zero": false, 11 | "remove-empty-rulesets": true, 12 | "rule-indent": 2, 13 | "stick-brace": true, 14 | "strip-spaces": true, 15 | "unitless-zero": true, 16 | "vendor-prefix-align": true, 17 | "sort-order": [ 18 | [ 19 | "position", 20 | "top", 21 | "right", 22 | "bottom", 23 | "left", 24 | "z-index", 25 | "display", 26 | "float", 27 | "width", 28 | "min-width", 29 | "max-width", 30 | "height", 31 | "min-height", 32 | "max-height", 33 | "-webkit-box-sizing", 34 | "-moz-box-sizing", 35 | "box-sizing", 36 | "-webkit-appearance", 37 | "padding", 38 | "padding-top", 39 | "padding-right", 40 | "padding-bottom", 41 | "padding-left", 42 | "margin", 43 | "margin-top", 44 | "margin-right", 45 | "margin-bottom", 46 | "margin-left", 47 | "overflow", 48 | "overflow-x", 49 | "overflow-y", 50 | "-webkit-overflow-scrolling", 51 | "-ms-overflow-x", 52 | "-ms-overflow-y", 53 | "-ms-overflow-style", 54 | "clip", 55 | "clear", 56 | "font", 57 | "font-family", 58 | "font-size", 59 | "font-style", 60 | "font-weight", 61 | "font-variant", 62 | "font-size-adjust", 63 | "font-stretch", 64 | "font-effect", 65 | "font-emphasize", 66 | "font-emphasize-position", 67 | "font-emphasize-style", 68 | "font-smooth", 69 | "-webkit-hyphens", 70 | "-moz-hyphens", 71 | "hyphens", 72 | "line-height", 73 | "color", 74 | "text-align", 75 | "-webkit-text-align-last", 76 | "-moz-text-align-last", 77 | "-ms-text-align-last", 78 | "text-align-last", 79 | "text-emphasis", 80 | "text-emphasis-color", 81 | "text-emphasis-style", 82 | "text-emphasis-position", 83 | "text-decoration", 84 | "text-indent", 85 | "text-justify", 86 | "text-outline", 87 | "-ms-text-overflow", 88 | "text-overflow", 89 | "text-overflow-ellipsis", 90 | "text-overflow-mode", 91 | "text-shadow", 92 | "text-transform", 93 | "text-wrap", 94 | "-webkit-text-size-adjust", 95 | "-ms-text-size-adjust", 96 | "letter-spacing", 97 | "-ms-word-break", 98 | "word-break", 99 | "word-spacing", 100 | "-ms-word-wrap", 101 | "word-wrap", 102 | "-moz-tab-size", 103 | "-o-tab-size", 104 | "tab-size", 105 | "white-space", 106 | "vertical-align", 107 | "list-style", 108 | "list-style-position", 109 | "list-style-type", 110 | "list-style-image", 111 | "pointer-events", 112 | "cursor", 113 | "visibility", 114 | "zoom", 115 | "flex-direction", 116 | "flex-order", 117 | "flex-pack", 118 | "flex-align", 119 | "table-layout", 120 | "empty-cells", 121 | "caption-side", 122 | "border-spacing", 123 | "border-collapse", 124 | "content", 125 | "quotes", 126 | "counter-reset", 127 | "counter-increment", 128 | "resize", 129 | "-webkit-user-select", 130 | "-moz-user-select", 131 | "-ms-user-select", 132 | "-o-user-select", 133 | "user-select", 134 | "nav-index", 135 | "nav-up", 136 | "nav-right", 137 | "nav-down", 138 | "nav-left", 139 | "background", 140 | "background-color", 141 | "background-image", 142 | "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient", 143 | "filter:progid:DXImageTransform.Microsoft.gradient", 144 | "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader", 145 | "filter", 146 | "background-repeat", 147 | "background-attachment", 148 | "background-position", 149 | "background-position-x", 150 | "background-position-y", 151 | "-webkit-background-clip", 152 | "-moz-background-clip", 153 | "background-clip", 154 | "background-origin", 155 | "-webkit-background-size", 156 | "-moz-background-size", 157 | "-o-background-size", 158 | "background-size", 159 | "border", 160 | "border-color", 161 | "border-style", 162 | "border-width", 163 | "border-top", 164 | "border-top-color", 165 | "border-top-style", 166 | "border-top-width", 167 | "border-right", 168 | "border-right-color", 169 | "border-right-style", 170 | "border-right-width", 171 | "border-bottom", 172 | "border-bottom-color", 173 | "border-bottom-style", 174 | "border-bottom-width", 175 | "border-left", 176 | "border-left-color", 177 | "border-left-style", 178 | "border-left-width", 179 | "border-radius", 180 | "border-top-left-radius", 181 | "border-top-right-radius", 182 | "border-bottom-right-radius", 183 | "border-bottom-left-radius", 184 | "-webkit-border-image", 185 | "-moz-border-image", 186 | "-o-border-image", 187 | "border-image", 188 | "-webkit-border-image-source", 189 | "-moz-border-image-source", 190 | "-o-border-image-source", 191 | "border-image-source", 192 | "-webkit-border-image-slice", 193 | "-moz-border-image-slice", 194 | "-o-border-image-slice", 195 | "border-image-slice", 196 | "-webkit-border-image-width", 197 | "-moz-border-image-width", 198 | "-o-border-image-width", 199 | "border-image-width", 200 | "-webkit-border-image-outset", 201 | "-moz-border-image-outset", 202 | "-o-border-image-outset", 203 | "border-image-outset", 204 | "-webkit-border-image-repeat", 205 | "-moz-border-image-repeat", 206 | "-o-border-image-repeat", 207 | "border-image-repeat", 208 | "outline", 209 | "outline-width", 210 | "outline-style", 211 | "outline-color", 212 | "outline-offset", 213 | "-webkit-box-shadow", 214 | "-moz-box-shadow", 215 | "box-shadow", 216 | "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity", 217 | "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha", 218 | "opacity", 219 | "-ms-interpolation-mode", 220 | "-webkit-transition", 221 | "-moz-transition", 222 | "-ms-transition", 223 | "-o-transition", 224 | "transition", 225 | "-webkit-transition-delay", 226 | "-moz-transition-delay", 227 | "-ms-transition-delay", 228 | "-o-transition-delay", 229 | "transition-delay", 230 | "-webkit-transition-timing-function", 231 | "-moz-transition-timing-function", 232 | "-ms-transition-timing-function", 233 | "-o-transition-timing-function", 234 | "transition-timing-function", 235 | "-webkit-transition-duration", 236 | "-moz-transition-duration", 237 | "-ms-transition-duration", 238 | "-o-transition-duration", 239 | "transition-duration", 240 | "-webkit-transition-property", 241 | "-moz-transition-property", 242 | "-ms-transition-property", 243 | "-o-transition-property", 244 | "transition-property", 245 | "-webkit-transform", 246 | "-moz-transform", 247 | "-ms-transform", 248 | "-o-transform", 249 | "transform", 250 | "-webkit-transform-origin", 251 | "-moz-transform-origin", 252 | "-ms-transform-origin", 253 | "-o-transform-origin", 254 | "transform-origin", 255 | "-webkit-animation", 256 | "-moz-animation", 257 | "-ms-animation", 258 | "-o-animation", 259 | "animation", 260 | "-webkit-animation-name", 261 | "-moz-animation-name", 262 | "-ms-animation-name", 263 | "-o-animation-name", 264 | "animation-name", 265 | "-webkit-animation-duration", 266 | "-moz-animation-duration", 267 | "-ms-animation-duration", 268 | "-o-animation-duration", 269 | "animation-duration", 270 | "-webkit-animation-play-state", 271 | "-moz-animation-play-state", 272 | "-ms-animation-play-state", 273 | "-o-animation-play-state", 274 | "animation-play-state", 275 | "-webkit-animation-timing-function", 276 | "-moz-animation-timing-function", 277 | "-ms-animation-timing-function", 278 | "-o-animation-timing-function", 279 | "animation-timing-function", 280 | "-webkit-animation-delay", 281 | "-moz-animation-delay", 282 | "-ms-animation-delay", 283 | "-o-animation-delay", 284 | "animation-delay", 285 | "-webkit-animation-iteration-count", 286 | "-moz-animation-iteration-count", 287 | "-ms-animation-iteration-count", 288 | "-o-animation-iteration-count", 289 | "animation-iteration-count", 290 | "-webkit-animation-direction", 291 | "-moz-animation-direction", 292 | "-ms-animation-direction", 293 | "-o-animation-direction", 294 | "animation-direction" 295 | ] 296 | ] 297 | } 298 | -------------------------------------------------------------------------------- /less/.csslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "adjoining-classes": false, 3 | "box-sizing": false, 4 | "box-model": false, 5 | "compatible-vendor-prefixes": false, 6 | "fallback-colors": false, 7 | "floats": false, 8 | "font-sizes": false, 9 | "gradients": false, 10 | "important": false, 11 | "known-properties": false, 12 | "outline-none": false, 13 | "qualified-headings": false, 14 | "regex-selectors": false, 15 | "shorthand": false, 16 | "text-indent": false, 17 | "unique-headings": false, 18 | "universal-selector": false, 19 | "unqualified-attributes": false 20 | } 21 | -------------------------------------------------------------------------------- /less/alerts-fixed.less: -------------------------------------------------------------------------------- 1 | // Fixed alerts 2 | // Position to the top or bottom. 3 | // ------------------------------------------------ 4 | 5 | .alert-fixed-top, 6 | .alert-fixed-bottom { 7 | position: fixed; 8 | width: 100%; 9 | z-index: @zindex-alert-fixed; 10 | border-radius: 0; 11 | margin: 0; 12 | left: 0; 13 | 14 | @media (min-width: @alert-fixed-width) { 15 | width: @alert-fixed-width; 16 | left: 50%; 17 | margin-left: (-1 * (@alert-fixed-width / 2)); 18 | } 19 | } 20 | 21 | .alert-fixed-top { 22 | top: 0; 23 | border-width: 0 0 1px 0; 24 | 25 | @media (min-width: @alert-fixed-width) { 26 | .border-bottom-radius(@alert-border-radius); 27 | border-width: 0 1px 1px 1px; 28 | } 29 | } 30 | 31 | .alert-fixed-bottom { 32 | bottom: 0; 33 | border-width: 1px 0 0 0; 34 | 35 | @media (min-width: @alert-fixed-width) { 36 | .border-top-radius(@alert-border-radius); 37 | border-width: 1px 1px 0 1px; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /less/build/jasny-bootstrap.less: -------------------------------------------------------------------------------- 1 | // Jasny Bootstrap with default variables 2 | 3 | @import "variables.less"; 4 | @import "mixins.less"; 5 | @import "../jasny-bootstrap.less"; 6 | -------------------------------------------------------------------------------- /less/build/mixins.less: -------------------------------------------------------------------------------- 1 | // 2 | // These mixins are used when Jasny Bootstrap is 3 | // built without importing vanilla Bootstrap. 4 | // -------------------------------------------------- 5 | 6 | 7 | // CSS3 PROPERTIES 8 | // -------------------------------------------------- 9 | 10 | // Single side border-radius 11 | .border-top-radius(@radius) { 12 | border-top-right-radius: @radius; 13 | border-top-left-radius: @radius; 14 | } 15 | .border-right-radius(@radius) { 16 | border-bottom-right-radius: @radius; 17 | border-top-right-radius: @radius; 18 | } 19 | .border-bottom-radius(@radius) { 20 | border-bottom-right-radius: @radius; 21 | border-bottom-left-radius: @radius; 22 | } 23 | .border-left-radius(@radius) { 24 | border-bottom-left-radius: @radius; 25 | border-top-left-radius: @radius; 26 | } 27 | 28 | // Drop shadows 29 | .box-shadow(@shadow) { 30 | -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1 31 | box-shadow: @shadow; 32 | } 33 | .transition(@transition) { 34 | -webkit-transition: @transition; 35 | -o-transition: @transition; 36 | transition: @transition; 37 | } 38 | 39 | // Transition 40 | .transition-property(@transition-property) { 41 | -webkit-transition-property: @transition-property; 42 | transition-property: @transition-property; 43 | } 44 | .transition-delay(@transition-delay) { 45 | -webkit-transition-delay: @transition-delay; 46 | transition-delay: @transition-delay; 47 | } 48 | .transition-duration(@transition-duration) { 49 | -webkit-transition-duration: @transition-duration; 50 | transition-duration: @transition-duration; 51 | } 52 | .transition-timing-function(@timing-function) { 53 | -webkit-transition-timing-function: @timing-function; 54 | transition-timing-function: @timing-function; 55 | } 56 | .transition-transform(@transition) { 57 | -webkit-transition: -webkit-transform @transition; 58 | -moz-transition: -moz-transform @transition; 59 | -o-transition: -o-transform @transition; 60 | transition: transform @transition; 61 | } -------------------------------------------------------------------------------- /less/build/variables.less: -------------------------------------------------------------------------------- 1 | // 2 | // These variables are used when Jasny Bootstrap is built 3 | // without importing vanilla Bootstrap. 4 | // -------------------------------------------------------- 5 | 6 | //-- Colors 7 | // 8 | //## Gray colors for use across Bootstrap. 9 | 10 | @gray-darker: lighten(#000, 13.5%); // #222 11 | @gray-dark: lighten(#000, 20%); // #333 12 | @gray: lighten(#000, 33.5%); // #555 13 | @gray-light: lighten(#000, 60%); // #999 14 | @gray-lighter: lighten(#000, 93.5%); // #eee 15 | 16 | //-- Typography 17 | // 18 | //## Font size and line-height. 19 | 20 | @font-size-base: 14px; 21 | @font-size-large: ceil((@font-size-base * 1.25)); // ~18px 22 | @font-size-small: ceil((@font-size-base * 0.85)); // ~12px 23 | 24 | //** Unit-less `line-height` for use in components like buttons. 25 | @line-height-base: 1.428571429; // 20/14 26 | //** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc. 27 | @line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px 28 | 29 | 30 | //== Components 31 | // 32 | //## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start). 33 | 34 | @padding-base-vertical: 6px; 35 | @padding-base-horizontal: 12px; 36 | 37 | @padding-large-vertical: 10px; 38 | @padding-large-horizontal: 16px; 39 | 40 | @padding-small-vertical: 5px; 41 | @padding-small-horizontal: 10px; 42 | 43 | @padding-xs-vertical: 1px; 44 | @padding-xs-horizontal: 5px; 45 | 46 | @line-height-large: 1.33; 47 | @line-height-small: 1.5; 48 | 49 | @border-radius-base: 4px; 50 | @border-radius-large: 6px; 51 | @border-radius-small: 3px; 52 | 53 | 54 | //== Tables 55 | // 56 | //## Customizes the `.table` component with basic values, each used across all table variations. 57 | 58 | //** Background color used for `.table-hover`. 59 | @table-bg-hover: #f5f5f5; 60 | 61 | 62 | //-- Z-index master list 63 | // 64 | // Warning: Avoid customizing these values. They're used for a bird's eye view 65 | // of components dependent on the z-axis and are designed to all work together. 66 | // 67 | // Note: These variables are not generated into the Customizer. 68 | 69 | @zindex-navmenu-fixed: 1030; 70 | @zindex-alert-fixed: 1035; 71 | 72 | @zindex-modal: 1050; 73 | 74 | 75 | //== Media queries breakpoints 76 | // 77 | //## Define the breakpoints at which your layout will change, adapting to different screen sizes. 78 | 79 | // Extra small screen / phone 80 | @screen-xs: 480px; 81 | 82 | // Small screen / tablet 83 | @screen-sm: 768px; 84 | 85 | // Medium screen / desktop 86 | @screen-md: 992px; 87 | 88 | // Large screen / wide desktop 89 | @screen-lg: 1200px; 90 | 91 | //-- So media queries don't overlap when required, provide a maximum 92 | // 93 | // Note: These variables are not generated into the Customizer. 94 | @screen-xs-min: @screen-xs; 95 | @screen-sm-min: @screen-sm; 96 | @screen-md-min: @screen-md; 97 | @screen-lg-min: @screen-lg; 98 | 99 | @screen-xs-max: (@screen-sm-min - 1); 100 | @screen-sm-max: (@screen-md-min - 1); 101 | @screen-md-max: (@screen-lg-min - 1); 102 | 103 | //-- 104 | @container-lg: ((1140px + @grid-gutter-width)); 105 | 106 | //== Grid system 107 | // 108 | //## Define your custom responsive grid. 109 | 110 | //** Padding between columns. Gets divided in half for the left and right. 111 | @grid-gutter-width: 30px; 112 | //** Point at which the navbar becomes uncollapsed. 113 | @grid-float-breakpoint: 768px; 114 | 115 | //** Maximum with of a smooth container. 116 | @container-smooth: @container-lg; 117 | 118 | //== Navbar 119 | // 120 | //## 121 | 122 | // Basics of a navbar 123 | @navbar-height: 50px; 124 | @navbar-padding-horizontal: floor((@grid-gutter-width / 2)); 125 | @navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2); 126 | 127 | 128 | //== Navmenu 129 | // 130 | //## 131 | 132 | // Basics of a navmenu 133 | @navmenu-width: 300px; 134 | @navmenu-margin-vertical: (0.5 * @line-height-computed); 135 | @navmenu-default-color: #777; 136 | @navmenu-default-bg: #f8f8f8; 137 | @navmenu-default-border: darken(@navmenu-default-bg, 6.5%); 138 | 139 | // Navmenu links 140 | @navmenu-default-link-color: #777; 141 | @navmenu-default-link-hover-color: #333; 142 | @navmenu-default-link-hover-bg: transparent; 143 | @navmenu-default-link-active-color: #555; 144 | @navmenu-default-link-active-bg: darken(@navmenu-default-bg, 6.5%); 145 | @navmenu-default-link-disabled-color: #ccc; 146 | @navmenu-default-link-disabled-bg: transparent; 147 | 148 | // Navmenu brand label 149 | @navmenu-default-brand-color: @navmenu-default-link-color; 150 | @navmenu-default-brand-hover-color: darken(@navmenu-default-link-color, 10%); 151 | @navmenu-default-brand-hover-bg: transparent; 152 | 153 | 154 | // Inverted navmenu 155 | // 156 | // Reset inverted navmenu basics 157 | @navmenu-inverse-color: @gray-light; 158 | @navmenu-inverse-bg: #222; 159 | @navmenu-inverse-border: darken(@navmenu-inverse-bg, 10%); 160 | 161 | // Inverted navmenu links 162 | @navmenu-inverse-link-color: @gray-light; 163 | @navmenu-inverse-link-hover-color: #fff; 164 | @navmenu-inverse-link-hover-bg: transparent; 165 | @navmenu-inverse-link-active-color: @navmenu-inverse-link-hover-color; 166 | @navmenu-inverse-link-active-bg: darken(@navmenu-inverse-bg, 10%); 167 | @navmenu-inverse-link-disabled-color: #444; 168 | @navmenu-inverse-link-disabled-bg: transparent; 169 | 170 | // Inverted navmenu brand label 171 | @navmenu-inverse-brand-color: @navmenu-inverse-link-color; 172 | @navmenu-inverse-brand-hover-color: #fff; 173 | @navmenu-inverse-brand-hover-bg: transparent; 174 | 175 | // Inverted navmenu search 176 | // Normal navmenu needs no special styles or vars 177 | @navmenu-inverse-search-bg: lighten(@navmenu-inverse-bg, 25%); 178 | @navmenu-inverse-search-bg-focus: #fff; 179 | @navmenu-inverse-search-border: @navmenu-inverse-bg; 180 | @navmenu-inverse-search-placeholder-color: #ccc; 181 | 182 | 183 | //== Navs 184 | // 185 | //## 186 | 187 | @nav-link-padding: 10px 15px; 188 | @nav-tabs-active-link-hover-border-color: #ddd; 189 | @nav-tabs-border-color: #ddd; 190 | 191 | 192 | //== Form states and alerts 193 | // 194 | //## Define colors for form feedback states and, by default, alerts. 195 | 196 | @state-success-text: #3c763d; 197 | @state-success-bg: #dff0d8; 198 | @state-success-border: darken(spin(@state-success-bg, -10), 5%); 199 | 200 | @state-info-text: #31708f; 201 | @state-info-bg: #d9edf7; 202 | @state-info-border: darken(spin(@state-info-bg, -10), 7%); 203 | 204 | @state-warning-text: #8a6d3b; 205 | @state-warning-bg: #fcf8e3; 206 | @state-warning-border: darken(spin(@state-warning-bg, -10), 5%); 207 | 208 | @state-danger-text: #a94442; 209 | @state-danger-bg: #f2dede; 210 | @state-danger-border: darken(spin(@state-danger-bg, -10), 5%); 211 | 212 | 213 | //== Alerts 214 | // 215 | //## Define alert colors, border radius, and padding. 216 | 217 | @alert-border-radius: @border-radius-base; 218 | @alert-fixed-width: @screen-md; 219 | -------------------------------------------------------------------------------- /less/button-labels.less: -------------------------------------------------------------------------------- 1 | // Labels for buttons 2 | // -------------------------------------------------- 3 | 4 | .button-label-size(@padding-vertical; @padding-horizontal; @border-radius) { 5 | padding: (@padding-vertical - 1px) @padding-horizontal (@padding-vertical + 1px) @padding-horizontal; 6 | left: (-1 * @padding-horizontal); 7 | border-radius: (@border-radius - 1px) 0 0 (@border-radius - 1px); 8 | 9 | &.btn-label-right { 10 | left: auto; 11 | right: (-1 * @padding-horizontal); 12 | border-radius: 0 (@border-radius - 1px) (@border-radius - 1px) 0; 13 | } 14 | } 15 | 16 | .btn-labeled { 17 | padding-top: 0; 18 | padding-bottom: 0; 19 | 20 | &.btn-block { 21 | text-indent: -12px; 22 | line-height: 32px; 23 | 24 | &.btn-lg { 25 | line-height: 42px; 26 | text-indent: -16px; 27 | } 28 | 29 | &.btn-sm { 30 | line-height: 30px; 31 | text-indent: -10px; 32 | } 33 | 34 | &.btn-xs { 35 | line-height: 22px; 36 | text-indent: -5px; 37 | } 38 | 39 | .btn-label { 40 | float: left; 41 | line-height: 20px; 42 | text-indent: 0; 43 | } 44 | } 45 | } 46 | 47 | .btn-label { 48 | position: relative; 49 | background: transparent; 50 | background: rgba(0, 0, 0, 0.15); 51 | display: inline-block; 52 | .button-label-size(@padding-base-vertical; @padding-base-horizontal; @border-radius-base); 53 | } 54 | 55 | .btn-lg .btn-label { 56 | .button-label-size(@padding-large-vertical; @padding-large-horizontal; @border-radius-large); 57 | } 58 | .btn-sm .btn-label { 59 | .button-label-size(@padding-small-vertical; @padding-small-horizontal; @border-radius-small); 60 | } 61 | .btn-xs .btn-label { 62 | .button-label-size(1px; 5px; @border-radius-small); 63 | } 64 | //Fix bootstrap grouped buttons 65 | .btn-group { 66 | .btn-labeled:not(:first-child) .btn-label:not(.btn-label-right) { 67 | .border-left-radius(0px); 68 | } 69 | .btn-labeled:not(:last-child) .btn-label.btn-label-right { 70 | .border-right-radius(0px); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /less/fileinput.less: -------------------------------------------------------------------------------- 1 | // Fileinput.less 2 | // CSS for file upload button and fileinput widget 3 | // ------------------------------------------------ 4 | 5 | .btn-file { 6 | overflow: hidden; 7 | position: relative; 8 | vertical-align: middle; 9 | > input { 10 | position: absolute; 11 | top: 0; 12 | right: 0; 13 | margin: 0; 14 | opacity: 0; 15 | filter: alpha(opacity=0); 16 | font-size: 23px; 17 | height: 100%; 18 | width: 100%; 19 | direction: ltr; 20 | cursor: pointer; 21 | 22 | &::-webkit-file-upload-button { 23 | cursor: pointer; 24 | } 25 | } 26 | } 27 | 28 | .fileinput { 29 | margin-bottom: 9px; 30 | display: inline-block; 31 | max-width: 100vw; 32 | .form-control { 33 | padding-top: 7px; 34 | padding-bottom: 5px; 35 | display: inline-block; 36 | margin-bottom: 0px; 37 | vertical-align: middle; 38 | cursor: text; 39 | } 40 | .img-thumbnail { 41 | overflow: hidden; 42 | display: inline-block; 43 | margin-bottom: 5px; 44 | vertical-align: middle; 45 | text-align: center; 46 | > img { 47 | max-height: 100%; 48 | max-width: 100%; 49 | height: auto; 50 | margin-right: auto; 51 | margin-left: auto; 52 | display: block; 53 | } 54 | } 55 | .btn { 56 | vertical-align: middle; 57 | } 58 | .form-group { 59 | overflow: hidden; 60 | .fileinput-filename { 61 | width: 90%; 62 | width: calc(100% - 20px); 63 | } 64 | } 65 | } 66 | .fileinput-exists .fileinput-new, 67 | .fileinput-new .fileinput-exists { 68 | display: none; 69 | } 70 | 71 | //close X button alignment 72 | .fileinput-exists.close { 73 | float: none; 74 | } 75 | 76 | .fileinput-inline .fileinput-controls { 77 | display: inline; 78 | } 79 | 80 | .fileinput-filename { 81 | display: inline-block; 82 | overflow: hidden; 83 | vertical-align: middle; 84 | white-space: nowrap; 85 | text-overflow: ellipsis; 86 | max-width: 65%; 87 | } 88 | 89 | .form-control .fileinput-filename { 90 | vertical-align: bottom; 91 | white-space: nowrap; 92 | width: 100%; 93 | max-width: 100%; 94 | position: absolute; 95 | left: 0; 96 | padding-left: 10px; 97 | } 98 | 99 | .form-control .fileinput-filename.with-icon { 100 | padding-left: 30px; 101 | } 102 | 103 | .fileinput.input-group { 104 | display: flex; 105 | 106 | > * { 107 | position: relative; 108 | z-index: 2; 109 | } 110 | > .btn-file { 111 | z-index: 1; 112 | } 113 | } 114 | 115 | .fileinput .input-group-append .input-group-text:hover { 116 | background: #d9dcdf; 117 | cursor: pointer; 118 | } 119 | 120 | .form-group.has-warning .fileinput { 121 | .fileinput-preview { 122 | color: @state-warning-text; 123 | } 124 | .img-thumbnail { 125 | border-color: @state-warning-border; 126 | } 127 | } 128 | .form-group.has-error .fileinput { 129 | .fileinput-preview { 130 | color: @state-danger-text; 131 | } 132 | .img-thumbnail { 133 | border-color: @state-danger-border; 134 | } 135 | } 136 | .form-group.has-success .fileinput { 137 | .fileinput-preview { 138 | color: @state-success-text; 139 | } 140 | .img-thumbnail { 141 | border-color: @state-success-border; 142 | } 143 | } 144 | 145 | 146 | // Input group fixes 147 | 148 | .input-group-addon:not(:first-child) { 149 | border-left: 0; 150 | } 151 | -------------------------------------------------------------------------------- /less/grid-container-smooth.less: -------------------------------------------------------------------------------- 1 | // Smooth sizing container 2 | // ------------------------- 3 | 4 | .container-smooth { 5 | max-width: @container-lg; 6 | 7 | @media (min-width: 1px) { 8 | width: auto; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /less/jasny-bootstrap.less: -------------------------------------------------------------------------------- 1 | // Vanilla Bootstrap's "variables.less" should already be imported 2 | /*! 3 | * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap) 4 | * Copyright 2012-2015 Arnold Daniels 5 | * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE) 6 | * 7 | */ 8 | // Core variables and mixins 9 | @import "variables.less"; 10 | 11 | // Core CSS 12 | @import "grid-container-smooth.less"; 13 | @import "button-labels.less"; 14 | 15 | // Components 16 | @import "nav-tab-alignment.less"; 17 | @import "navmenu.less"; 18 | @import "alerts-fixed.less"; 19 | 20 | // Components w/ JavaScript 21 | @import "offcanvas.less"; 22 | @import "rowlink.less"; 23 | @import "fileinput.less"; 24 | -------------------------------------------------------------------------------- /less/nav-tab-alignment.less: -------------------------------------------------------------------------------- 1 | // Alignment options 2 | // ------------------------- 3 | 4 | // bottom 5 | .nav-tabs-bottom { 6 | border-bottom: 0; 7 | border-top: 1px solid @nav-tabs-border-color; 8 | 9 | > li { 10 | margin-bottom: 0; 11 | margin-top: -1px; 12 | 13 | > a { 14 | border-radius: 0 0 @border-radius-base @border-radius-base; 15 | } 16 | 17 | > a:hover, 18 | > a:focus, 19 | &.active > a, 20 | &.active > a:hover, 21 | &.active > a:focus { 22 | border: 1px solid @nav-tabs-active-link-hover-border-color; 23 | border-top-color: transparent; 24 | } 25 | } 26 | } 27 | 28 | // left 29 | .nav-tabs-left { 30 | border-bottom: 0; 31 | border-right: 1px solid @nav-tabs-border-color; 32 | 33 | > li { 34 | margin-bottom: 0; 35 | margin-right: -1px; 36 | float: none; 37 | 38 | > a { 39 | border-radius: @border-radius-base 0 0 @border-radius-base; 40 | margin-right: 0; 41 | margin-bottom: 2px; 42 | } 43 | 44 | > a:hover, 45 | > a:focus, 46 | &.active > a, 47 | &.active > a:hover, 48 | &.active > a:focus { 49 | border: 1px solid @nav-tabs-active-link-hover-border-color; 50 | border-right-color: transparent; 51 | } 52 | } 53 | 54 | .row > & { 55 | padding-right: 0; 56 | padding-left: (@grid-gutter-width / 2); 57 | margin-right: -1px; 58 | position: relative; 59 | z-index: 1; 60 | 61 | & + .tab-content { 62 | border-left: 1px solid @nav-tabs-active-link-hover-border-color; 63 | } 64 | } 65 | } 66 | 67 | // right 68 | .nav-tabs-right { 69 | border-bottom: 0; 70 | border-left: 1px solid @nav-tabs-border-color; 71 | 72 | > li { 73 | margin-bottom: 0; 74 | margin-left: -1px; 75 | float: none; 76 | 77 | > a { 78 | border-radius: 0 @border-radius-base @border-radius-base 0; 79 | margin-left: 0; 80 | margin-bottom: 2px; 81 | } 82 | 83 | > a:hover, 84 | > a:focus, 85 | &.active > a, 86 | &.active > a:hover, 87 | &.active > a:focus { 88 | border: 1px solid @nav-tabs-active-link-hover-border-color; 89 | border-left-color: transparent; 90 | } 91 | } 92 | 93 | .row > & { 94 | padding-left: 0; 95 | padding-right: (@grid-gutter-width / 2); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /less/navmenu.less: -------------------------------------------------------------------------------- 1 | // Navmenu and offcanvas navbar 2 | // -------------------------------------------------- 3 | 4 | 5 | // Wrapper and base class 6 | // 7 | // Provide a static navmenu from which we expand to create the fixed navmenu 8 | // variations. 9 | 10 | .navmenu, 11 | .navbar-offcanvas { 12 | width: @navmenu-width; 13 | height: auto; 14 | border-width: 1px; 15 | border-style: solid; 16 | border-radius: @border-radius-base; 17 | } 18 | // Fixed iphone with disableScrolling 19 | .lockIphone { 20 | position: fixed; 21 | overflow: hidden; 22 | height: 100%; 23 | -webkit-overflow-scrolling: auto; 24 | } 25 | // Fix the bug for bootstrap 3.2.0 (https://github.com/jasny/bootstrap/issues/355) 26 | .navbar-fixed-top, 27 | .navbar-fixed-bottom { 28 | -webkit-transform: none; 29 | -o-transform: none; 30 | transform: none; 31 | } 32 | 33 | .navmenu-fixed-left, 34 | .navmenu-fixed-right, 35 | .navbar-offcanvas { 36 | position: fixed; 37 | z-index: @zindex-navmenu-fixed; 38 | top: 0; 39 | bottom: 0; 40 | overflow-y: auto; 41 | border-radius: 0; 42 | } 43 | 44 | .navmenu-fixed-left, 45 | .navmenu-fixed-right { 46 | .dropdown .dropdown-menu { 47 | position: static !important; 48 | float: none; 49 | transform: none !important; 50 | background: rgba(0, 0, 0, .02); 51 | border-left: none; 52 | border-right: none; 53 | border-radius: 0; 54 | 55 | .nav-link { 56 | padding: .35rem 1rem .35rem 1.3rem; 57 | } 58 | } 59 | } 60 | 61 | .navmenu-fixed-left, 62 | .navbar-offcanvas.navmenu-fixed-left { 63 | left: 0; 64 | right: auto!important; 65 | border-width: 0 1px 0 0; 66 | } 67 | .navmenu-fixed-right, 68 | .navbar-offcanvas { 69 | left: auto!important; 70 | right: 0; 71 | border-width: 0 0 0 1px; 72 | } 73 | 74 | .navmenu-nav { 75 | margin-bottom: @navmenu-margin-vertical; 76 | 77 | &.dropdown-menu { 78 | position: static!important; 79 | transform: none!important; 80 | margin: 0; 81 | padding-top: 0; 82 | float: none; 83 | border: none; 84 | .box-shadow(none); 85 | border-radius: 0; 86 | 87 | li > a { 88 | white-space: normal; 89 | } 90 | } 91 | } 92 | 93 | .navbar-offcanvas { 94 | .navbar-nav { 95 | margin: 0; 96 | } 97 | 98 | @media (min-width: @grid-float-breakpoint) { 99 | width: auto; 100 | border-top: 0; 101 | box-shadow: none; 102 | 103 | &.offcanvas { 104 | position: static; 105 | display: block !important; 106 | height: auto !important; 107 | padding-bottom: 0; // Override default setting 108 | overflow: visible !important; 109 | } 110 | 111 | // Account for first and last children spacing 112 | .navbar-nav.navbar-left:first-child { 113 | margin-left: -@navbar-padding-horizontal; 114 | } 115 | .navbar-nav.navbar-right:last-child { 116 | margin-right: -@navbar-padding-horizontal; 117 | } 118 | 119 | .navmenu-brand { 120 | display: none; 121 | } 122 | } 123 | } 124 | 125 | // Brand/project name 126 | 127 | .navmenu-brand { 128 | display: block; 129 | font-size: @font-size-large; 130 | line-height: @line-height-computed; 131 | padding: @nav-link-padding; 132 | &:hover, 133 | &:focus { 134 | text-decoration: none; 135 | } 136 | margin: @navmenu-margin-vertical 0; 137 | } 138 | 139 | // Alternate navmenus 140 | // -------------------------------------------------- 141 | 142 | // Default navmenu 143 | .navmenu-default, 144 | .navbar-default .navbar-offcanvas { 145 | background-color: @navmenu-default-bg; 146 | border-color: @navmenu-default-border; 147 | 148 | .navmenu-brand { 149 | color: @navmenu-default-brand-color; 150 | &:hover, 151 | &:focus { 152 | color: @navmenu-default-brand-hover-color; 153 | background-color: @navmenu-default-brand-hover-bg; 154 | } 155 | } 156 | 157 | .navmenu-text { 158 | color: @navmenu-default-color; 159 | } 160 | 161 | .navmenu-nav { 162 | // Caret should match text color on hover 163 | > .dropdown > a:hover .caret, 164 | > .dropdown > a:focus .caret { 165 | border-top-color: @navmenu-default-link-hover-color; 166 | border-bottom-color: @navmenu-default-link-hover-color; 167 | } 168 | 169 | // Remove background color from open dropdown 170 | > .open > a { 171 | &, 172 | &:hover, 173 | &:focus { 174 | background-color: @navmenu-default-link-active-bg; 175 | color: @navmenu-default-link-active-color; 176 | .caret { 177 | border-top-color: @navmenu-default-link-active-color; 178 | border-bottom-color: @navmenu-default-link-active-color; 179 | } 180 | } 181 | } 182 | > .dropdown > a .caret { 183 | border-top-color: @navmenu-default-link-color; 184 | border-bottom-color: @navmenu-default-link-color; 185 | } 186 | &.dropdown-menu { 187 | background-color: @navmenu-default-link-active-bg; 188 | & > .divider { 189 | background-color: @navmenu-default-bg; 190 | } 191 | > .active > a { 192 | &, 193 | &:hover, 194 | &:focus { 195 | background-color: darken(@navmenu-default-link-active-bg, 6.5%); 196 | } 197 | } 198 | } 199 | 200 | > li > a { 201 | color: @navmenu-default-link-color; 202 | &:hover, 203 | &:focus { 204 | color: @navmenu-default-link-hover-color; 205 | background-color: @navmenu-default-link-hover-bg; 206 | } 207 | } 208 | > .active > a { 209 | &, 210 | &:hover, 211 | &:focus { 212 | color: @navmenu-default-link-active-color; 213 | background-color: @navmenu-default-link-active-bg; 214 | } 215 | } 216 | > .disabled > a { 217 | &, 218 | &:hover, 219 | &:focus { 220 | color: @navmenu-default-link-disabled-color; 221 | background-color: @navmenu-default-link-disabled-bg; 222 | } 223 | } 224 | } 225 | } 226 | 227 | // Inverse navmenu 228 | .navmenu-inverse, 229 | .navbar-inverse .navbar-offcanvas { 230 | background-color: @navmenu-inverse-bg; 231 | border-color: @navmenu-inverse-border; 232 | 233 | .navmenu-brand { 234 | color: @navmenu-inverse-brand-color; 235 | &:hover, 236 | &:focus { 237 | color: @navmenu-inverse-brand-hover-color; 238 | background-color: @navmenu-inverse-brand-hover-bg; 239 | } 240 | } 241 | 242 | .navmenu-text { 243 | color: @navmenu-inverse-color; 244 | } 245 | 246 | .navmenu-nav { 247 | // Caret should match text color on hover 248 | > .dropdown > a:hover .caret, 249 | > .dropdown > a:focus .caret { 250 | border-top-color: @navmenu-inverse-link-hover-color; 251 | border-bottom-color: @navmenu-inverse-link-hover-color; 252 | } 253 | 254 | // Remove background color from open dropdown 255 | > .open > a { 256 | &, 257 | &:hover, 258 | &:focus { 259 | background-color: @navmenu-inverse-link-active-bg; 260 | color: @navmenu-inverse-link-active-color; 261 | .caret { 262 | border-top-color: @navmenu-inverse-link-active-color; 263 | border-bottom-color: @navmenu-inverse-link-active-color; 264 | } 265 | } 266 | } 267 | > .dropdown > a .caret { 268 | border-top-color: @navmenu-inverse-link-color; 269 | border-bottom-color: @navmenu-inverse-link-color; 270 | } 271 | &.dropdown-menu { 272 | background-color: @navmenu-inverse-link-active-bg; 273 | & > .divider { 274 | background-color: @navmenu-inverse-bg; 275 | } 276 | > .active > a { 277 | &, 278 | &:hover, 279 | &:focus { 280 | background-color: darken(@navmenu-inverse-link-active-bg, 6.5%); 281 | } 282 | } 283 | } 284 | 285 | > li > a { 286 | color: @navmenu-inverse-link-color; 287 | &:hover, 288 | &:focus { 289 | color: @navmenu-inverse-link-hover-color; 290 | background-color: @navmenu-inverse-link-hover-bg; 291 | } 292 | } 293 | > .active > a { 294 | &, 295 | &:hover, 296 | &:focus { 297 | color: @navmenu-inverse-link-active-color; 298 | background-color: @navmenu-inverse-link-active-bg; 299 | } 300 | } 301 | > .disabled > a { 302 | &, 303 | &:hover, 304 | &:focus { 305 | color: @navmenu-inverse-link-disabled-color; 306 | background-color: @navmenu-inverse-link-disabled-bg; 307 | } 308 | } 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /less/offcanvas.less: -------------------------------------------------------------------------------- 1 | // Off canvas navigation 2 | // -------------------------------------------------- 3 | 4 | .offcanvas { 5 | display: none; 6 | &.in { 7 | display: block; 8 | } 9 | 10 | .dropdown .dropdown-menu { 11 | position: static !important; 12 | float: none; 13 | transform: none !important; 14 | background: rgba(0, 0, 0, .02); 15 | border-left: none; 16 | border-right: none; 17 | border-radius: 0; 18 | 19 | .nav-link { 20 | padding: .35rem 1rem .35rem 1.3rem; 21 | } 22 | } 23 | } 24 | 25 | @media (max-width: @screen-xs-max) { 26 | .offcanvas-xs { 27 | .offcanvas; 28 | } 29 | } 30 | @media (max-width: @screen-sm-max) { 31 | .offcanvas-sm { 32 | .offcanvas; 33 | } 34 | } 35 | @media (max-width: @screen-md-max) { 36 | .offcanvas-md { 37 | .offcanvas; 38 | } 39 | } 40 | .offcanvas-lg { 41 | .offcanvas; 42 | } 43 | 44 | .canvas-sliding { 45 | -webkit-transition: top 0.35s, left 0.35s, bottom 0.35s, right 0.35s; 46 | transition: top 0.35s, left 0.35s, bottom 0.35s, right 0.35s; 47 | } 48 | 49 | .offcanvas-clone { 50 | height: 0px !important; 51 | width: 0px !important; 52 | overflow: hidden !important; 53 | border: none !important; 54 | margin: 0px !important; 55 | padding: 0px !important; 56 | position: absolute !important; 57 | top: auto !important; 58 | left: auto !important; 59 | bottom: 0px !important; 60 | right: 0px !important; 61 | opacity: 0 !important; 62 | } 63 | 64 | .modal-backdrop.allow-navbar { 65 | z-index: 1029; 66 | } 67 | 68 | .limit-backdrop { 69 | overflow: hidden!important; 70 | 71 | .modal-backdrop { 72 | position: absolute; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /less/rowlink.less: -------------------------------------------------------------------------------- 1 | // Rowlink 2 | // -------------------------------------------------- 3 | 4 | .table.rowlink, 5 | .table .rowlink { 6 | td:not(.rowlink-skip) { 7 | cursor: pointer; 8 | 9 | a { 10 | color: inherit; 11 | font: inherit; 12 | text-decoration: inherit; 13 | } 14 | } 15 | } 16 | 17 | .table-hover.rowlink, 18 | .table-hover .rowlink { 19 | tr:hover td { 20 | background-color: darken(@table-bg-hover, 15%); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /less/variables.less: -------------------------------------------------------------------------------- 1 | // 2 | // Variables 3 | // 4 | // Either vanilla Bootstrap's "variables.less" or this package's 5 | // "default-variables.less" should be loaded before this file. 6 | // ------------------------------------------------------------- 7 | 8 | @zindex-navmenu-fixed: (@zindex-modal + 1); 9 | @zindex-alert-fixed: 1035; 10 | 11 | @container-smooth: @container-lg; 12 | 13 | @alert-fixed-width: @screen-md-min; 14 | 15 | 16 | //== Navmenu 17 | 18 | // Basics of a navmenu 19 | @navmenu-width: 300px; 20 | @navmenu-margin-vertical: (0.5 * @line-height-computed); 21 | @navmenu-default-color: #777; 22 | @navmenu-default-bg: #f8f8f8; 23 | @navmenu-default-border: darken(@navmenu-default-bg, 6.5%); 24 | 25 | // Navmenu links 26 | @navmenu-default-link-color: #777; 27 | @navmenu-default-link-hover-color: #333; 28 | @navmenu-default-link-hover-bg: transparent; 29 | @navmenu-default-link-active-color: #555; 30 | @navmenu-default-link-active-bg: darken(@navmenu-default-bg, 6.5%); 31 | @navmenu-default-link-disabled-color: #ccc; 32 | @navmenu-default-link-disabled-bg: transparent; 33 | 34 | // Navmenu brand label 35 | @navmenu-default-brand-color: @navmenu-default-link-color; 36 | @navmenu-default-brand-hover-color: darken(@navmenu-default-link-color, 10%); 37 | @navmenu-default-brand-hover-bg: transparent; 38 | 39 | 40 | // Inverted navmenu 41 | // 42 | // Reset inverted navmenu basics 43 | @navmenu-inverse-color: @gray-light; 44 | @navmenu-inverse-bg: #222; 45 | @navmenu-inverse-border: darken(@navmenu-inverse-bg, 10%); 46 | 47 | // Inverted navmenu links 48 | @navmenu-inverse-link-color: @gray-light; 49 | @navmenu-inverse-link-hover-color: #fff; 50 | @navmenu-inverse-link-hover-bg: transparent; 51 | @navmenu-inverse-link-active-color: @navmenu-inverse-link-hover-color; 52 | @navmenu-inverse-link-active-bg: darken(@navmenu-inverse-bg, 10%); 53 | @navmenu-inverse-link-disabled-color: #444; 54 | @navmenu-inverse-link-disabled-bg: transparent; 55 | 56 | // Inverted navmenu brand label 57 | @navmenu-inverse-brand-color: @navmenu-inverse-link-color; 58 | @navmenu-inverse-brand-hover-color: #fff; 59 | @navmenu-inverse-brand-hover-bg: transparent; 60 | 61 | // Inverted navmenu search 62 | // Normal navmenu needs no special styles or vars 63 | @navmenu-inverse-search-bg: lighten(@navmenu-inverse-bg, 25%); 64 | @navmenu-inverse-search-bg-focus: #fff; 65 | @navmenu-inverse-search-border: @navmenu-inverse-bg; 66 | @navmenu-inverse-search-placeholder-color: #ccc; 67 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | // package metadata file for Meteor.js 2 | 3 | Package.describe({ 4 | name: 'jasny:bootstrap', // http://atmospherejs.com/jasny/bootstrap 5 | version: '4.0.0', 6 | summary: 'Jasny Bootstrap (official): The missing components for your favorite front-end framework.', 7 | git: 'https://github.com/jasny/bootstrap.git', 8 | documentation: 'README.md' 9 | }); 10 | 11 | Package.onUse(function (api) { 12 | api.versionsFrom('METEOR@1.0'); 13 | 14 | api.use('jquery', 'client'); 15 | 16 | api.addFiles([ 17 | 'dist/css/jasny-bootstrap.css', 18 | 'dist/js/jasny-bootstrap.js' 19 | ], 'client'); 20 | }); 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jasny-bootstrap", 3 | "npmName": "jasny-bootstrap", 4 | "description": "Additional features and components for Bootstrap", 5 | "version": "4.0.0", 6 | "main": "./dist/js/jasny-bootstrap.js", 7 | "keywords": [ 8 | "bootstrap", 9 | "css" 10 | ], 11 | "homepage": "http://jasny.github.io/bootstrap", 12 | "author": "Arnold Daniels", 13 | "scripts": { 14 | "test": "grunt test" 15 | }, 16 | "style": "./dist/css/jasny-bootstrap.css", 17 | "less": "./less/jasny-bootstrap.less", 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/jasny/bootstrap.git" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/jasny/bootstrap/issues" 24 | }, 25 | "license": "Apache-2.0", 26 | "devDependencies": { 27 | "btoa": "~1.1.1", 28 | "canonical-json": "~0.0.3", 29 | "grunt": "~0.4.5", 30 | "grunt-banner": "~0.4.0", 31 | "grunt-contrib-clean": "~0.6.0", 32 | "grunt-contrib-concat": "~0.5.0", 33 | "grunt-contrib-connect": "~0.11.0", 34 | "grunt-contrib-copy": "~0.8.0", 35 | "grunt-contrib-csslint": "~0.5.0", 36 | "grunt-contrib-cssmin": "~0.13.0", 37 | "grunt-contrib-jade": "~0.15.0", 38 | "grunt-contrib-jshint": "~0.11.0", 39 | "grunt-contrib-less": "~1.0", 40 | "grunt-contrib-qunit": "~0.7.0", 41 | "grunt-contrib-uglify": "~0.9.0", 42 | "grunt-contrib-watch": "~0.6.0", 43 | "grunt-csscomb": "~3.0.0", 44 | "grunt-exec": "~0.4.2", 45 | "grunt-html-validation": "~0.1.13", 46 | "grunt-jekyll": "~0.4.1", 47 | "grunt-jscs": "~2.0.0", 48 | "grunt-saucelabs": "~8.6.0", 49 | "grunt-text-replace": "~0.4.0", 50 | "load-grunt-tasks": "~3.2", 51 | "markdown": "~0.5.0" 52 | }, 53 | "jspm": { 54 | "main": "js/jasny-bootstrap", 55 | "directories": { 56 | "example": "examples", 57 | "lib": "dist" 58 | }, 59 | "shim": { 60 | "js/jasny-bootstrap": { 61 | "imports": "jquery", 62 | "exports": "$" 63 | } 64 | }, 65 | "buildConfig": { 66 | "uglify": true 67 | } 68 | }, 69 | "npmFileMap": [ 70 | { 71 | "basePath": "dist", 72 | "files": [ 73 | "**/*" 74 | ] 75 | } 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /scss/_alerts-fixed.scss: -------------------------------------------------------------------------------- 1 | // Fixed alerts 2 | // Position to the top or bottom. 3 | // ------------------------------------------------ 4 | 5 | .alert-fixed-top, 6 | .alert-fixed-bottom { 7 | position: fixed; 8 | width: 100%; 9 | z-index: $zindex-alert-fixed; 10 | border-radius: 0; 11 | margin: 0; 12 | left: 0; 13 | 14 | @media (min-width: $alert-fixed-width) { 15 | width: $alert-fixed-width; 16 | left: 50%; 17 | margin-left: (-1 * ($alert-fixed-width / 2)); 18 | } 19 | } 20 | 21 | .alert-fixed-top { 22 | top: 0; 23 | border-width: 0 0 1px 0; 24 | 25 | @media (min-width: $alert-fixed-width) { 26 | @include border-bottom-radius($alert-border-radius); 27 | border-width: 0 1px 1px 1px; 28 | } 29 | } 30 | 31 | .alert-fixed-bottom { 32 | bottom: 0; 33 | border-width: 1px 0 0 0; 34 | 35 | @media (min-width: $alert-fixed-width) { 36 | @include border-top-radius($alert-border-radius); 37 | border-width: 1px 1px 0 1px; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /scss/_button-labels.scss: -------------------------------------------------------------------------------- 1 | // Labels for buttons 2 | // -------------------------------------------------- 3 | 4 | @mixin button-label-size($padding-vertical, $padding-horizontal, $border-radius) { 5 | padding: $padding-vertical $padding-horizontal; 6 | left: (-1 * $padding-horizontal); 7 | border-radius: ($border-radius - 1px) 0 0 ($border-radius - 1px); 8 | 9 | &.btn-label-right { 10 | left: auto; 11 | right: (-1 * $padding-horizontal); 12 | border-radius: 0 ($border-radius - 1px) ($border-radius - 1px) 0; 13 | } 14 | } 15 | 16 | 17 | .btn-labeled { 18 | padding-top: 0; 19 | padding-bottom: 0; 20 | } 21 | 22 | .btn-label { 23 | position: relative; 24 | background: transparent; 25 | background: rgba(0, 0, 0, 0.15); 26 | display: inline-block; 27 | @include button-label-size($padding-base-vertical, $padding-base-horizontal, $border-radius-base); 28 | } 29 | 30 | .btn-lg .btn-label { 31 | @include button-label-size($padding-large-vertical, $padding-large-horizontal, $border-radius-large); 32 | } 33 | .btn-sm .btn-label { 34 | @include button-label-size($padding-small-vertical, $padding-small-horizontal, $border-radius-small); 35 | } 36 | .btn-xs .btn-label { 37 | @include button-label-size(1px, 5px, $border-radius-small); 38 | } 39 | //Fix bootstrap grouped buttons 40 | .btn-group { 41 | .btn-labeled:not(:first-child) .btn-label:not(.btn-label-right) { 42 | @include border-left-radius(0px); 43 | } 44 | .btn-labeled:not(:last-child) .btn-label.btn-label-right { 45 | @include border-right-radius(0px); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /scss/_fileinput.scss: -------------------------------------------------------------------------------- 1 | // Fileinput 2 | // CSS for file upload button and fileinput widget 3 | // ------------------------------------------------ 4 | 5 | .btn-file { 6 | overflow: hidden; 7 | position: relative; 8 | vertical-align: middle; 9 | > input { 10 | position: absolute; 11 | top: 0; 12 | right: 0; 13 | margin: 0; 14 | opacity: 0; 15 | filter: alpha(opacity=0); 16 | font-size: 23px; 17 | height: 100%; 18 | width: 100%; 19 | direction: ltr; 20 | cursor: pointer; 21 | 22 | &::-webkit-file-upload-button { 23 | cursor: pointer; 24 | } 25 | } 26 | } 27 | 28 | .fileinput { 29 | margin-bottom: 9px; 30 | display: inline-block; 31 | max-width: 100vw; 32 | .form-control { 33 | padding-top: 7px; 34 | padding-bottom: 5px; 35 | display: inline-block; 36 | margin-bottom: 0px; 37 | vertical-align: middle; 38 | cursor: text; 39 | } 40 | .thumbnail { 41 | overflow: hidden; 42 | display: inline-block; 43 | margin-bottom: 5px; 44 | vertical-align: middle; 45 | text-align: center; 46 | > img { 47 | max-height: 100%; 48 | } 49 | } 50 | .btn { 51 | vertical-align: middle; 52 | } 53 | .form-group { 54 | overflow: hidden; 55 | .fileinput-filename { 56 | width: 90%; 57 | width: calc(100% - 20px); 58 | } 59 | } 60 | } 61 | .fileinput-exists .fileinput-new, 62 | .fileinput-new .fileinput-exists { 63 | display: none; 64 | } 65 | 66 | //close X button alignment 67 | .fileinput-exists.close { 68 | float: none; 69 | } 70 | 71 | .fileinput-inline .fileinput-controls { 72 | display: inline; 73 | } 74 | 75 | .fileinput-filename { 76 | display: inline-block; 77 | overflow: hidden; 78 | vertical-align: middle; 79 | white-space: nowrap; 80 | text-overflow: ellipsis; 81 | max-width: 65%; 82 | } 83 | 84 | .form-control .fileinput-filename { 85 | vertical-align: bottom; 86 | white-space: nowrap; 87 | width: 100%; 88 | max-width: 100%; 89 | position: absolute; 90 | left: 0; 91 | padding-left: 30px; 92 | } 93 | 94 | .fileinput.input-group { 95 | display: table; 96 | 97 | > * { 98 | position: relative; 99 | z-index: 2; 100 | } 101 | > .btn-file { 102 | z-index: 1; 103 | } 104 | } 105 | 106 | // Not 100% correct, but helps in typical use case 107 | .fileinput-new.input-group .btn-file, 108 | .fileinput-new .input-group .btn-file { 109 | border-radius: 0 $border-radius-base $border-radius-base 0; 110 | 111 | &.btn-xs, 112 | &.btn-sm { 113 | border-radius: 0 $border-radius-small $border-radius-small 0; 114 | } 115 | &.btn-lg { 116 | border-radius: 0 $border-radius-large $border-radius-large 0; 117 | } 118 | } 119 | 120 | .form-group.has-warning .fileinput { 121 | .fileinput-preview { 122 | color: $state-warning-text; 123 | } 124 | .thumbnail { 125 | border-color: $state-warning-border; 126 | } 127 | } 128 | .form-group.has-error .fileinput { 129 | .fileinput-preview { 130 | color: $state-danger-text; 131 | } 132 | .thumbnail { 133 | border-color: $state-danger-border; 134 | } 135 | } 136 | .form-group.has-success .fileinput { 137 | .fileinput-preview { 138 | color: $state-success-text; 139 | } 140 | .thumbnail { 141 | border-color: $state-success-border; 142 | } 143 | } 144 | 145 | 146 | // Input group fixes 147 | 148 | .input-group-addon:not(:first-child) { 149 | border-left: 0; 150 | } 151 | -------------------------------------------------------------------------------- /scss/_grid-container-smooth.scss: -------------------------------------------------------------------------------- 1 | // Smooth sizing container 2 | // ------------------------- 3 | 4 | .container-smooth { 5 | max-width: $container-lg; 6 | 7 | @media (min-width: 1px) { 8 | width: auto; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // 2 | // These mixins are used when Jasny Bootstrap is 3 | // built without importing Twitter Bootstrap. 4 | // -------------------------------------------------- 5 | 6 | 7 | // CSS3 PROPERTIES 8 | // -------------------------------------------------- 9 | 10 | // Single side border-radius 11 | @mixin border-top-radius($radius) { 12 | border-top-right-radius: $radius; 13 | border-top-left-radius: $radius; 14 | } 15 | @mixin border-right-radius($radius) { 16 | border-bottom-right-radius: $radius; 17 | border-top-right-radius: $radius; 18 | } 19 | @mixin border-bottom-radius($radius) { 20 | border-bottom-right-radius: $radius; 21 | border-bottom-left-radius: $radius; 22 | } 23 | @mixin border-left-radius($radius) { 24 | border-bottom-left-radius: $radius; 25 | border-top-left-radius: $radius; 26 | } 27 | 28 | // Drop shadows 29 | @mixin box-shadow($shadow) { 30 | -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1 31 | box-shadow: $shadow; 32 | } 33 | @mixin transition($transition) { 34 | -webkit-transition: $transition; 35 | -o-transition: $transition; 36 | transition: $transition; 37 | } 38 | 39 | // Transition 40 | @mixin transition-property($transition-property) { 41 | -webkit-transition-property: $transition-property; 42 | transition-property: $transition-property; 43 | } 44 | @mixin transition-delay($transition-delay) { 45 | -webkit-transition-delay: $transition-delay; 46 | transition-delay: $transition-delay; 47 | } 48 | @mixin transition-duration($transition-duration) { 49 | -webkit-transition-duration: $transition-duration; 50 | transition-duration: $transition-duration; 51 | } 52 | @mixin transition-timing-function($timing-function) { 53 | -webkit-transition-timing-function: $timing-function; 54 | transition-timing-function: $timing-function; 55 | } 56 | @mixin transition-transform($transition) { 57 | -webkit-transition: -webkit-transform $transition; 58 | -moz-transition: -moz-transform $transition; 59 | -o-transition: -o-transform $transition; 60 | transition: transform $transition; 61 | } -------------------------------------------------------------------------------- /scss/_nav-tab-alignment.scss: -------------------------------------------------------------------------------- 1 | // Alignment options 2 | // ------------------------- 3 | 4 | // bottom 5 | .nav-tabs-bottom { 6 | border-bottom: 0; 7 | border-top: 1px solid $nav-tabs-border-color; 8 | 9 | > li { 10 | margin-bottom: 0; 11 | margin-top: -1px; 12 | 13 | > a { 14 | border-radius: 0 0 $border-radius-base $border-radius-base; 15 | } 16 | 17 | > a:hover, 18 | > a:focus, 19 | &.active > a, 20 | &.active > a:hover, 21 | &.active > a:focus { 22 | border: 1px solid $nav-tabs-active-link-hover-border-color; 23 | border-top-color: transparent; 24 | } 25 | } 26 | } 27 | 28 | // left 29 | .nav-tabs-left { 30 | border-bottom: 0; 31 | border-right: 1px solid $nav-tabs-border-color; 32 | 33 | > li { 34 | margin-bottom: 0; 35 | margin-right: -1px; 36 | float: none; 37 | 38 | > a { 39 | border-radius: $border-radius-base 0 0 $border-radius-base; 40 | margin-right: 0; 41 | margin-bottom: 2px; 42 | } 43 | 44 | > a:hover, 45 | > a:focus, 46 | &.active > a, 47 | &.active > a:hover, 48 | &.active > a:focus { 49 | border: 1px solid $nav-tabs-active-link-hover-border-color; 50 | border-right-color: transparent; 51 | } 52 | } 53 | 54 | .row > & { 55 | padding-right: 0; 56 | padding-left: ($grid-gutter-width / 2); 57 | margin-right: -1px; 58 | position: relative; 59 | z-index: 1; 60 | 61 | & + .tab-content { 62 | border-left: 1px solid $nav-tabs-active-link-hover-border-color; 63 | } 64 | } 65 | } 66 | 67 | // right 68 | .nav-tabs-right { 69 | border-bottom: 0; 70 | border-left: 1px solid $nav-tabs-border-color; 71 | 72 | > li { 73 | margin-bottom: 0; 74 | margin-left: -1px; 75 | float: none; 76 | 77 | > a { 78 | border-radius: 0 $border-radius-base $border-radius-base 0; 79 | margin-left: 0; 80 | margin-bottom: 2px; 81 | } 82 | 83 | > a:hover, 84 | > a:focus, 85 | &.active > a, 86 | &.active > a:hover, 87 | &.active > a:focus { 88 | border: 1px solid $nav-tabs-active-link-hover-border-color; 89 | border-left-color: transparent; 90 | } 91 | } 92 | 93 | .row > & { 94 | padding-left: 0; 95 | padding-right: ($grid-gutter-width / 2); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /scss/_navmenu.scss: -------------------------------------------------------------------------------- 1 | // Navmenu and offcanvas navbar 2 | // -------------------------------------------------- 3 | 4 | 5 | // Wrapper and base class 6 | // 7 | // Provide a static navmenu from which we expand to create the fixed navmenu 8 | // variations. 9 | 10 | .navmenu, 11 | .navbar-offcanvas { 12 | width: $navmenu-width; 13 | height: auto; 14 | border-width: 1px; 15 | border-style: solid; 16 | border-radius: $border-radius-base; 17 | } 18 | // Fixed iphone with disableScrolling 19 | .lockIphone { 20 | position: fixed; 21 | overflow: hidden; 22 | height: 100%; 23 | -webkit-overflow-scrolling: auto; 24 | } 25 | // Fix the bug for bootstrap 3.2.0 (https://github.com/jasny/bootstrap/issues/355) 26 | .navbar-fixed-top, 27 | .navbar-fixed-bottom { 28 | -webkit-transform: none; 29 | -o-transform: none; 30 | transform: none; 31 | } 32 | 33 | .navmenu-fixed-left, 34 | .navmenu-fixed-right, 35 | .navbar-offcanvas { 36 | position: fixed; 37 | z-index: $zindex-navmenu-fixed; 38 | top: 0; 39 | bottom: 0; 40 | overflow-y: auto; 41 | border-radius: 0; 42 | } 43 | .navmenu-fixed-left, 44 | .navbar-offcanvas.navmenu-fixed-left { 45 | left: 0; 46 | right: auto; 47 | border-width: 0 1px 0 0; 48 | } 49 | .navmenu-fixed-right, 50 | .navbar-offcanvas { 51 | left: auto; 52 | right: 0; 53 | border-width: 0 0 0 1px; 54 | } 55 | 56 | .navmenu-nav { 57 | margin-bottom: $navmenu-margin-vertical; 58 | 59 | &.dropdown-menu { 60 | position: static; 61 | margin: 0; 62 | padding-top: 0; 63 | float: none; 64 | border: none; 65 | @include box-shadow(none); 66 | border-radius: 0; 67 | 68 | li > a { 69 | white-space: normal; 70 | } 71 | } 72 | } 73 | 74 | .navbar-offcanvas { 75 | .navbar-nav { 76 | margin: 0; 77 | } 78 | 79 | @media (min-width: $grid-float-breakpoint) { 80 | width: auto; 81 | border-top: 0; 82 | box-shadow: none; 83 | 84 | &.offcanvas { 85 | position: static; 86 | display: block !important; 87 | height: auto !important; 88 | padding-bottom: 0; // Override default setting 89 | overflow: visible !important; 90 | } 91 | 92 | // Account for first and last children spacing 93 | .navbar-nav.navbar-left:first-child { 94 | margin-left: -$navbar-padding-horizontal; 95 | } 96 | .navbar-nav.navbar-right:last-child { 97 | margin-right: -$navbar-padding-horizontal; 98 | } 99 | 100 | .navmenu-brand { 101 | display: none; 102 | } 103 | } 104 | } 105 | 106 | // Brand/project name 107 | 108 | .navmenu-brand { 109 | display: block; 110 | font-size: $font-size-large; 111 | line-height: $line-height-computed; 112 | padding: $nav-link-padding; 113 | &:hover, 114 | &:focus { 115 | text-decoration: none; 116 | } 117 | margin: $navmenu-margin-vertical 0; 118 | } 119 | 120 | // Alternate navmenus 121 | // -------------------------------------------------- 122 | 123 | // Default navmenu 124 | .navmenu-default, 125 | .navbar-default .navbar-offcanvas { 126 | background-color: $navmenu-default-bg; 127 | border-color: $navmenu-default-border; 128 | 129 | .navmenu-brand { 130 | color: $navmenu-default-brand-color; 131 | &:hover, 132 | &:focus { 133 | color: $navmenu-default-brand-hover-color; 134 | background-color: $navmenu-default-brand-hover-bg; 135 | } 136 | } 137 | 138 | .navmenu-text { 139 | color: $navmenu-default-color; 140 | } 141 | 142 | .navmenu-nav { 143 | // Caret should match text color on hover 144 | > .dropdown > a:hover .caret, 145 | > .dropdown > a:focus .caret { 146 | border-top-color: $navmenu-default-link-hover-color; 147 | border-bottom-color: $navmenu-default-link-hover-color; 148 | } 149 | 150 | // Remove background color from open dropdown 151 | > .open > a { 152 | &, 153 | &:hover, 154 | &:focus { 155 | background-color: $navmenu-default-link-active-bg; 156 | color: $navmenu-default-link-active-color; 157 | .caret { 158 | border-top-color: $navmenu-default-link-active-color; 159 | border-bottom-color: $navmenu-default-link-active-color; 160 | } 161 | } 162 | } 163 | > .dropdown > a .caret { 164 | border-top-color: $navmenu-default-link-color; 165 | border-bottom-color: $navmenu-default-link-color; 166 | } 167 | &.dropdown-menu { 168 | background-color: $navmenu-default-link-active-bg; 169 | & > .divider { 170 | background-color: $navmenu-default-bg; 171 | } 172 | > .active > a { 173 | &, 174 | &:hover, 175 | &:focus { 176 | background-color: darken($navmenu-default-link-active-bg, 6.5%); 177 | } 178 | } 179 | } 180 | 181 | > li > a { 182 | color: $navmenu-default-link-color; 183 | &:hover, 184 | &:focus { 185 | color: $navmenu-default-link-hover-color; 186 | background-color: $navmenu-default-link-hover-bg; 187 | } 188 | } 189 | > .active > a { 190 | &, 191 | &:hover, 192 | &:focus { 193 | color: $navmenu-default-link-active-color; 194 | background-color: $navmenu-default-link-active-bg; 195 | } 196 | } 197 | > .disabled > a { 198 | &, 199 | &:hover, 200 | &:focus { 201 | color: $navmenu-default-link-disabled-color; 202 | background-color: $navmenu-default-link-disabled-bg; 203 | } 204 | } 205 | } 206 | } 207 | 208 | // Inverse navmenu 209 | .navmenu-inverse, 210 | .navbar-inverse .navbar-offcanvas { 211 | background-color: $navmenu-inverse-bg; 212 | border-color: $navmenu-inverse-border; 213 | 214 | .navmenu-brand { 215 | color: $navmenu-inverse-brand-color; 216 | &:hover, 217 | &:focus { 218 | color: $navmenu-inverse-brand-hover-color; 219 | background-color: $navmenu-inverse-brand-hover-bg; 220 | } 221 | } 222 | 223 | .navmenu-text { 224 | color: $navmenu-inverse-color; 225 | } 226 | 227 | .navmenu-nav { 228 | // Caret should match text color on hover 229 | > .dropdown > a:hover .caret, 230 | > .dropdown > a:focus .caret { 231 | border-top-color: $navmenu-inverse-link-hover-color; 232 | border-bottom-color: $navmenu-inverse-link-hover-color; 233 | } 234 | 235 | // Remove background color from open dropdown 236 | > .open > a { 237 | &, 238 | &:hover, 239 | &:focus { 240 | background-color: $navmenu-inverse-link-active-bg; 241 | color: $navmenu-inverse-link-active-color; 242 | .caret { 243 | border-top-color: $navmenu-inverse-link-active-color; 244 | border-bottom-color: $navmenu-inverse-link-active-color; 245 | } 246 | } 247 | } 248 | > .dropdown > a .caret { 249 | border-top-color: $navmenu-inverse-link-color; 250 | border-bottom-color: $navmenu-inverse-link-color; 251 | } 252 | &.dropdown-menu { 253 | background-color: $navmenu-inverse-link-active-bg; 254 | & > .divider { 255 | background-color: $navmenu-inverse-bg; 256 | } 257 | > .active > a { 258 | &, 259 | &:hover, 260 | &:focus { 261 | background-color: darken($navmenu-inverse-link-active-bg, 6.5%); 262 | } 263 | } 264 | } 265 | 266 | > li > a { 267 | color: $navmenu-inverse-link-color; 268 | &:hover, 269 | &:focus { 270 | color: $navmenu-inverse-link-hover-color; 271 | background-color: $navmenu-inverse-link-hover-bg; 272 | } 273 | } 274 | > .active > a { 275 | &, 276 | &:hover, 277 | &:focus { 278 | color: $navmenu-inverse-link-active-color; 279 | background-color: $navmenu-inverse-link-active-bg; 280 | } 281 | } 282 | > .disabled > a { 283 | &, 284 | &:hover, 285 | &:focus { 286 | color: $navmenu-inverse-link-disabled-color; 287 | background-color: $navmenu-inverse-link-disabled-bg; 288 | } 289 | } 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /scss/_offcanvas.scss: -------------------------------------------------------------------------------- 1 | // Off canvas navigation 2 | // -------------------------------------------------- 3 | 4 | @mixin offcanvas { 5 | display: none; 6 | &.in { 7 | display: block; 8 | } 9 | } 10 | 11 | .offcanvas { 12 | @include offcanvas; 13 | } 14 | 15 | @media (max-width: $screen-xs-max) { 16 | .offcanvas-xs { 17 | @include offcanvas; 18 | } 19 | } 20 | @media (max-width: $screen-sm-max) { 21 | .offcanvas-sm { 22 | @include offcanvas; 23 | } 24 | } 25 | @media (max-width: $screen-md-max) { 26 | .offcanvas-md { 27 | @include offcanvas; 28 | } 29 | } 30 | .offcanvas-lg { 31 | @include offcanvas; 32 | } 33 | 34 | .canvas-sliding { 35 | -webkit-transition: top 0.35s, left 0.35s, bottom 0.35s, right 0.35s; 36 | transition: top 0.35s, left 0.35s, bottom 0.35s, right 0.35s; 37 | } 38 | 39 | .offcanvas-clone { 40 | height: 0px !important; 41 | width: 0px !important; 42 | overflow: hidden !important; 43 | border: none !important; 44 | margin: 0px !important; 45 | padding: 0px !important; 46 | position: absolute !important; 47 | top: auto !important; 48 | left: auto !important; 49 | bottom: 0px !important; 50 | right: 0px !important; 51 | opacity: 0 !important; 52 | } 53 | 54 | .modal-backdrop.allow-navbar { 55 | z-index: 1029; 56 | } 57 | 58 | .limit-backdrop { 59 | overflow: hidden!important; 60 | 61 | .modal-backdrop { 62 | position: absolute; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /scss/_rowlink.scss: -------------------------------------------------------------------------------- 1 | // Rowlink 2 | // -------------------------------------------------- 3 | 4 | .table.rowlink, 5 | .table .rowlink { 6 | td:not(.rowlink-skip) { 7 | cursor: pointer; 8 | 9 | a { 10 | color: inherit; 11 | font: inherit; 12 | text-decoration: inherit; 13 | } 14 | } 15 | } 16 | 17 | .table-hover.rowlink, 18 | .table-hover .rowlink { 19 | tr:hover td { 20 | background-color: darken($table-bg-hover, 15%); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scss/_variables.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Variables 3 | // 4 | // Either vanilla Bootstrap's "variables.less" or this package's 5 | // "default-variables.less" should be loaded before this file. 6 | // ------------------------------------------------------------- 7 | 8 | $zindex-navmenu-fixed: $zindex-modal; 9 | $zindex-alert-fixed: 1035; 10 | 11 | $container-smooth: $container-lg; 12 | 13 | $alert-fixed-width: $screen-md-min; 14 | 15 | 16 | //== Navmenu 17 | 18 | // Basics of a navmenu 19 | $navmenu-width: 300px; 20 | $navmenu-margin-vertical: (0.5 * $line-height-computed); 21 | $navmenu-default-color: #777; 22 | $navmenu-default-bg: #f8f8f8; 23 | $navmenu-default-border: darken($navmenu-default-bg, 6.5%); 24 | 25 | // Navmenu links 26 | $navmenu-default-link-color: #777; 27 | $navmenu-default-link-hover-color: #333; 28 | $navmenu-default-link-hover-bg: transparent; 29 | $navmenu-default-link-active-color: #555; 30 | $navmenu-default-link-active-bg: darken($navmenu-default-bg, 6.5%); 31 | $navmenu-default-link-disabled-color: #ccc; 32 | $navmenu-default-link-disabled-bg: transparent; 33 | 34 | // Navmenu brand label 35 | $navmenu-default-brand-color: $navmenu-default-link-color; 36 | $navmenu-default-brand-hover-color: darken($navmenu-default-link-color, 10%); 37 | $navmenu-default-brand-hover-bg: transparent; 38 | 39 | 40 | // Inverted navmenu 41 | // 42 | // Reset inverted navmenu basics 43 | $navmenu-inverse-color: $gray-light; 44 | $navmenu-inverse-bg: #222; 45 | $navmenu-inverse-border: darken($navmenu-inverse-bg, 10%); 46 | 47 | // Inverted navmenu links 48 | $navmenu-inverse-link-color: $gray-light; 49 | $navmenu-inverse-link-hover-color: #fff; 50 | $navmenu-inverse-link-hover-bg: transparent; 51 | $navmenu-inverse-link-active-color: $navmenu-inverse-link-hover-color; 52 | $navmenu-inverse-link-active-bg: darken($navmenu-inverse-bg, 10%); 53 | $navmenu-inverse-link-disabled-color: #444; 54 | $navmenu-inverse-link-disabled-bg: transparent; 55 | 56 | // Inverted navmenu brand label 57 | $navmenu-inverse-brand-color: $navmenu-inverse-link-color; 58 | $navmenu-inverse-brand-hover-color: #fff; 59 | $navmenu-inverse-brand-hover-bg: transparent; 60 | 61 | // Inverted navmenu search 62 | // Normal navmenu needs no special styles or vars 63 | $navmenu-inverse-search-bg: lighten($navmenu-inverse-bg, 25%); 64 | $navmenu-inverse-search-bg-focus: #fff; 65 | $navmenu-inverse-search-border: $navmenu-inverse-bg; 66 | $navmenu-inverse-search-placeholder-color: #ccc; 67 | -------------------------------------------------------------------------------- /scss/build/_mixins.scss: -------------------------------------------------------------------------------- 1 | // 2 | // These mixins are used when Jasny Bootstrap is 3 | // built without importing vanilla Bootstrap@mixin 4 | // -------------------------------------------------- 5 | 6 | 7 | // CSS3 PROPERTIES 8 | // -------------------------------------------------- 9 | 10 | // Single side border-radius 11 | @mixin border-top-radius($radius) { 12 | border-top-right-radius: $radius; 13 | border-top-left-radius: $radius; 14 | } 15 | @mixin border-right-radius($radius) { 16 | border-bottom-right-radius: $radius; 17 | border-top-right-radius: $radius; 18 | } 19 | @mixin border-bottom-radius($radius) { 20 | border-bottom-right-radius: $radius; 21 | border-bottom-left-radius: $radius; 22 | } 23 | @mixin border-left-radius($radius) { 24 | border-bottom-left-radius: $radius; 25 | border-top-left-radius: $radius; 26 | } 27 | 28 | // Drop shadows 29 | @mixin box-shadow($shadow) { 30 | -webkit-box-shadow: $shadow; // iOS <4@mixin 3 & Android <4@mixin 1 31 | box-shadow: $shadow; 32 | } 33 | @mixin transition($transition) { 34 | -webkit-transition: $transition; 35 | -o-transition: $transition; 36 | transition: $transition; 37 | } 38 | 39 | // Transition 40 | @mixin transition-property($transition-property) { 41 | -webkit-transition-property: $transition-property; 42 | transition-property: $transition-property; 43 | } 44 | @mixin transition-delay($transition-delay) { 45 | -webkit-transition-delay: $transition-delay; 46 | transition-delay: $transition-delay; 47 | } 48 | @mixin transition-duration($transition-duration) { 49 | -webkit-transition-duration: $transition-duration; 50 | transition-duration: $transition-duration; 51 | } 52 | @mixin transition-timing-function($timing-function) { 53 | -webkit-transition-timing-function: $timing-function; 54 | transition-timing-function: $timing-function; 55 | } 56 | @mixin transition-transform($transition) { 57 | -webkit-transition: -webkit-transform $transition; 58 | -moz-transition: -moz-transform $transition; 59 | -o-transition: -o-transform $transition; 60 | transition: transform $transition; 61 | } -------------------------------------------------------------------------------- /scss/build/_variables.scss: -------------------------------------------------------------------------------- 1 | // 2 | // These variables are used when Jasny Bootstrap is built 3 | // without importing vanilla Bootstrap. 4 | // -------------------------------------------------------- 5 | 6 | //-- Colors 7 | // 8 | //## Gray colors for use across Bootstrap. 9 | 10 | $gray-darker: lighten(#000, 13.5%); // #222 11 | $gray-dark: lighten(#000, 20%); // #333 12 | $gray: lighten(#000, 33.5%); // #555 13 | $gray-light: lighten(#000, 60%); // #999 14 | $gray-lighter: lighten(#000, 93.5%); // #eee 15 | 16 | //-- Typography 17 | // 18 | //## Font size and line-height. 19 | 20 | $font-size-base: 14px; 21 | $font-size-large: ceil(($font-size-base * 1.25)); // ~18px 22 | $font-size-small: ceil(($font-size-base * 0.85)); // ~12px 23 | 24 | //** Unit-less `line-height` for use in components like buttons. 25 | $line-height-base: 1.428571429; // 20/14 26 | //** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc. 27 | $line-height-computed: floor(($font-size-base * $line-height-base)); // ~20px 28 | 29 | 30 | //== Components 31 | // 32 | //## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start). 33 | 34 | $padding-base-vertical: 6px; 35 | $padding-base-horizontal: 12px; 36 | 37 | $padding-large-vertical: 10px; 38 | $padding-large-horizontal: 16px; 39 | 40 | $padding-small-vertical: 5px; 41 | $padding-small-horizontal: 10px; 42 | 43 | $padding-xs-vertical: 1px; 44 | $padding-xs-horizontal: 5px; 45 | 46 | $line-height-large: 1.33; 47 | $line-height-small: 1.5; 48 | 49 | $border-radius-base: 4px; 50 | $border-radius-large: 6px; 51 | $border-radius-small: 3px; 52 | 53 | 54 | //== Tables 55 | // 56 | //## Customizes the `.table` component with basic values, each used across all table variations. 57 | 58 | //** Background color used for `.table-hover`. 59 | $table-bg-hover: #f5f5f5; 60 | 61 | 62 | //-- Z-index master list 63 | // 64 | // Warning: Avoid customizing these values. They're used for a bird's eye view 65 | // of components dependent on the z-axis and are designed to all work together. 66 | // 67 | // Note: These variables are not generated into the Customizer. 68 | 69 | $zindex-navmenu-fixed: 1030; 70 | $zindex-alert-fixed: 1035; 71 | 72 | $zindex-modal: 1050; 73 | 74 | 75 | //== Media queries breakpoints 76 | // 77 | //## Define the breakpoints at which your layout will change, adapting to different screen sizes. 78 | 79 | // Extra small screen / phone 80 | $screen-xs: 480px; 81 | 82 | // Small screen / tablet 83 | $screen-sm: 768px; 84 | 85 | // Medium screen / desktop 86 | $screen-md: 992px; 87 | 88 | // Large screen / wide desktop 89 | $screen-lg: 1200px; 90 | 91 | //-- So media queries don't overlap when required, provide a maximum 92 | // 93 | // Note: These variables are not generated into the Customizer. 94 | $screen-xs-min: $screen-xs; 95 | $screen-sm-min: $screen-sm; 96 | $screen-md-min: $screen-md; 97 | $screen-lg-min: $screen-lg; 98 | 99 | $screen-xs-max: ($screen-sm-min - 1); 100 | $screen-sm-max: ($screen-md-min - 1); 101 | $screen-md-max: ($screen-lg-min - 1); 102 | 103 | //== Grid system 104 | // 105 | //## Define your custom responsive grid. 106 | 107 | //** Padding between columns. Gets divided in half for the left and right. 108 | $grid-gutter-width: 30px; 109 | //** Point at which the navbar becomes uncollapsed. 110 | $grid-float-breakpoint: 768px; 111 | 112 | //-- 113 | $container-lg: ((1140px + $grid-gutter-width)); 114 | //** Maximum with of a smooth container. 115 | $container-smooth: $container-lg; 116 | 117 | //== Navbar 118 | // 119 | //## 120 | 121 | // Basics of a navbar 122 | $navbar-height: 50px; 123 | $navbar-padding-horizontal: floor(($grid-gutter-width / 2)); 124 | $navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2); 125 | 126 | 127 | //== Navmenu 128 | // 129 | //## 130 | 131 | // Basics of a navmenu 132 | $navmenu-width: 300px; 133 | $navmenu-margin-vertical: (0.5 * $line-height-computed); 134 | $navmenu-default-color: #777; 135 | $navmenu-default-bg: #f8f8f8; 136 | $navmenu-default-border: darken($navmenu-default-bg, 6.5%); 137 | 138 | // Navmenu links 139 | $navmenu-default-link-color: #777; 140 | $navmenu-default-link-hover-color: #333; 141 | $navmenu-default-link-hover-bg: transparent; 142 | $navmenu-default-link-active-color: #555; 143 | $navmenu-default-link-active-bg: darken($navmenu-default-bg, 6.5%); 144 | $navmenu-default-link-disabled-color: #ccc; 145 | $navmenu-default-link-disabled-bg: transparent; 146 | 147 | // Navmenu brand label 148 | $navmenu-default-brand-color: $navmenu-default-link-color; 149 | $navmenu-default-brand-hover-color: darken($navmenu-default-link-color, 10%); 150 | $navmenu-default-brand-hover-bg: transparent; 151 | 152 | 153 | // Inverted navmenu 154 | // 155 | // Reset inverted navmenu basics 156 | $navmenu-inverse-color: $gray-light; 157 | $navmenu-inverse-bg: #222; 158 | $navmenu-inverse-border: darken($navmenu-inverse-bg, 10%); 159 | 160 | // Inverted navmenu links 161 | $navmenu-inverse-link-color: $gray-light; 162 | $navmenu-inverse-link-hover-color: #fff; 163 | $navmenu-inverse-link-hover-bg: transparent; 164 | $navmenu-inverse-link-active-color: $navmenu-inverse-link-hover-color; 165 | $navmenu-inverse-link-active-bg: darken($navmenu-inverse-bg, 10%); 166 | $navmenu-inverse-link-disabled-color: #444; 167 | $navmenu-inverse-link-disabled-bg: transparent; 168 | 169 | // Inverted navmenu brand label 170 | $navmenu-inverse-brand-color: $navmenu-inverse-link-color; 171 | $navmenu-inverse-brand-hover-color: #fff; 172 | $navmenu-inverse-brand-hover-bg: transparent; 173 | 174 | // Inverted navmenu search 175 | // Normal navmenu needs no special styles or vars 176 | $navmenu-inverse-search-bg: lighten($navmenu-inverse-bg, 25%); 177 | $navmenu-inverse-search-bg-focus: #fff; 178 | $navmenu-inverse-search-border: $navmenu-inverse-bg; 179 | $navmenu-inverse-search-placeholder-color: #ccc; 180 | 181 | 182 | //== Navs 183 | // 184 | //## 185 | 186 | $nav-link-padding: 10px 15px; 187 | $nav-tabs-active-link-hover-border-color: #ddd; 188 | $nav-tabs-border-color: #ddd; 189 | 190 | 191 | //== Form states and alerts 192 | // 193 | //## Define colors for form feedback states and, by default, alerts. 194 | 195 | $state-success-text: #3c763d; 196 | $state-success-bg: #dff0d8; 197 | $state-success-border: darken(adjust-hue($state-success-bg, -10), 5%); 198 | 199 | $state-info-text: #31708f; 200 | $state-info-bg: #d9edf7; 201 | $state-info-border: darken(adjust-hue($state-info-bg, -10), 7%); 202 | 203 | $state-warning-text: #8a6d3b; 204 | $state-warning-bg: #fcf8e3; 205 | $state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%); 206 | 207 | $state-danger-text: #a94442; 208 | $state-danger-bg: #f2dede; 209 | $state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%); 210 | 211 | 212 | //== Alerts 213 | // 214 | //## Define alert colors, border radius, and padding. 215 | 216 | $alert-border-radius: $border-radius-base; 217 | $alert-fixed-width: $screen-md; 218 | -------------------------------------------------------------------------------- /scss/build/jasny-bootstrap.scss: -------------------------------------------------------------------------------- 1 | // Jasny Bootstrap with default variables 2 | 3 | @import "variables"; 4 | @import "mixins"; 5 | @import "../jasny-bootstrap"; 6 | -------------------------------------------------------------------------------- /scss/jasny-bootstrap.scss: -------------------------------------------------------------------------------- 1 | // Vanilla Bootstrap's "variables.scss" should already be imported 2 | /*! 3 | * Jasny Bootstrap v3.1.3 (http://jasny.github.io/bootstrap) 4 | * Copyright 2012-2015 Arnold Daniels 5 | * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE) 6 | * 7 | */ 8 | 9 | // Core variables 10 | @import "variables"; 11 | 12 | // Core CSS 13 | @import "grid-container-smooth"; 14 | @import "button-labels"; 15 | 16 | // Components 17 | @import "nav-tab-alignment"; 18 | @import "navmenu"; 19 | @import "alerts-fixed"; 20 | 21 | // Components w/ JavaScript 22 | @import "offcanvas"; 23 | @import "rowlink"; 24 | @import "fileinput"; 25 | -------------------------------------------------------------------------------- /test-infra/README.md: -------------------------------------------------------------------------------- 1 | ## What does `s3_cache.py` do? 2 | 3 | ### In general 4 | `s3_cache.py` maintains a cache, stored in an Amazon S3 (Simple Storage Service) bucket, of a given directory whose contents are considered non-critical and are completely & solely determined by (and should be able to be regenerated from) a single given file. 5 | 6 | The SHA-256 hash of the single file is used as the key for the cache. The directory is stored as a gzipped tarball. 7 | 8 | All the tarballs are stored in S3's Reduced Redundancy Storage (RRS) storage class, since this is cheaper and the data is non-critical. 9 | 10 | `s3_cache.py` itself never deletes cache entries; deletion should either be done manually or using automatic S3 lifecycle rules on the bucket. 11 | 12 | Similar to git, `s3_cache.py` makes the assumption that [SHA-256 will effectively never have a collision](http://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice). 13 | 14 | 15 | ### For Bootstrap specifically 16 | `s3_cache.py` is used to cache the npm packages that our Grunt tasks depend on and the RubyGems that Jekyll depends on. (Jekyll is needed to compile our docs to HTML so that we can run them thru an HTML5 validator.) 17 | 18 | For npm, the `node_modules` directory is cached based on our `npm-shrinkwrap.canonical.json` file. 19 | 20 | For RubyGems, the `gemdir` of the current RVM-selected Ruby is cached based on the `pseudo_Gemfile.lock` file generated by our Travis build script. 21 | `pseudo_Gemfile.lock` contains the versions of Ruby and Jekyll that we're using (read our `.travis.yml` for details). 22 | 23 | 24 | ## Why is `s3_cache.py` necessary? 25 | `s3_cache.py` is used to speed up Bootstrap's Travis builds. Installing npm packages and RubyGems used to take up a significant fraction of our total build times. Also, at the time that `s3_cache.py` was written, npm was occasionally unreliable. 26 | 27 | Travis does offer built-in caching on their paid plans, but this do-it-ourselves S3 solution is significantly cheaper since we only need caching and not Travis' other paid features. 28 | 29 | 30 | ## Setup 31 | 32 | ### Overview 33 | 1. Create an Amazon Web Services (AWS) account. 34 | 2. Create an Identity & Access Management (IAM) user, and note their credentials. 35 | 3. Create an S3 bucket. 36 | 4. Set permissions on the bucket to grant the user read+write access. 37 | 5. Set the user credentials as secure Travis environment variables. 38 | 39 | ### In detail 40 | 1. Create an AWS account. 41 | 2. Login to the [AWS Management Console](https://console.aws.amazon.com). 42 | 3. Go to the IAM Management Console. 43 | 4. Create a new user (named e.g. `travis-ci`) and generate an access key for them. Note both the Access Key ID and the Secret Access Key. 44 | 5. Note the user's ARN (Amazon Resource Name), which can be found in the "Summary" tab of the user browser. This will be of the form: `arn:aws:iam::XXXXXXXXXXXXXX:user/the-username-goes-here` 45 | 6. Note the user's access key, which can be found in the "Security Credentials" tab of the user browser. 46 | 7. Go to the S3 Management Console. 47 | 8. Create a new bucket. For a non-publicly-accessible bucket (like Bootstrap uses), it's recommended that the bucket name be random to increase security. On most *nix machines, you can easily generate a random UUID to use as the bucket name using Python: 48 | 49 | ```bash 50 | python -c "import uuid; print(uuid.uuid4())" 51 | ``` 52 | 53 | 9. Determine and note what your bucket's ARN is. The ARN for an S3 bucket is of the form: `arn:aws:s3:::the-bucket-name-goes-here` 54 | 10. In the bucket's Properties pane, in the "Permissions" section, click the "Edit bucket policy" button. 55 | 11. Input and submit an IAM Policy that grants the user at least read+write rights to the bucket. AWS has a policy generator and some examples to help with crafting the policy. Here's the policy that Bootstrap uses, with the sensitive bits censored: 56 | 57 | ```json 58 | { 59 | "Version": "2012-10-17", 60 | "Id": "PolicyTravisReadWriteNoAdmin", 61 | "Statement": [ 62 | { 63 | "Sid": "StmtXXXXXXXXXXXXXX", 64 | "Effect": "Allow", 65 | "Principal": { 66 | "AWS": "arn:aws:iam::XXXXXXXXXXXXXX:user/travis-ci" 67 | }, 68 | "Action": [ 69 | "s3:AbortMultipartUpload", 70 | "s3:GetObjectVersion", 71 | "s3:ListBucket", 72 | "s3:DeleteObject", 73 | "s3:DeleteObjectVersion", 74 | "s3:GetObject", 75 | "s3:PutObject" 76 | ], 77 | "Resource": [ 78 | "arn:aws:s3:::XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", 79 | "arn:aws:s3:::XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/*" 80 | ] 81 | } 82 | ] 83 | } 84 | ``` 85 | 86 | 12. If you want deletion from the cache to be done automatically based on age (like Bootstrap does): In the bucket's Properties pane, in the "Lifecycle" section, add a rule to expire/delete files based on creation date. 87 | 13. Install the [`travis` RubyGem](https://github.com/travis-ci/travis): `gem install travis` 88 | 14. Encrypt the environment variables: 89 | 90 | ```bash 91 | travis encrypt --repo twbs/bootstrap "AWS_ACCESS_KEY_ID=XXX" 92 | travis encrypt --repo twbs/bootstrap "AWS_SECRET_ACCESS_KEY=XXX" 93 | travis encrypt --repo twbs/bootstrap "TWBS_S3_BUCKET=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" 94 | ``` 95 | 96 | 14. Add the resulting secure environment variables to `.travis.yml`. 97 | 98 | 99 | ## Usage 100 | Read `s3_cache.py`'s source code and Bootstrap's `.travis.yml` for how to invoke and make use of `s3_cache.py`. 101 | -------------------------------------------------------------------------------- /test-infra/requirements.txt: -------------------------------------------------------------------------------- 1 | boto==2.20.0 2 | -------------------------------------------------------------------------------- /test-infra/sauce_browsers.yml: -------------------------------------------------------------------------------- 1 | [ 2 | # Docs: https://saucelabs.com/docs/platforms/webdriver 3 | 4 | { 5 | browserName: "safari", 6 | platform: "OS X 10.9" 7 | }, 8 | # { 9 | # browserName: "googlechrome", 10 | # platform: "OS X 10.9", 11 | # version: "31" 12 | # }, 13 | { 14 | browserName: "firefox", 15 | platform: "OS X 10.9" 16 | }, 17 | 18 | # Mac Opera not currently supported by Sauce Labs 19 | 20 | { 21 | browserName: "internet explorer", 22 | version: "11", 23 | platform: "Windows 8.1" 24 | }, 25 | { 26 | browserName: "internet explorer", 27 | version: "10", 28 | platform: "Windows 8" 29 | }, 30 | # { 31 | # browserName: "internet explorer", 32 | # version: "9", 33 | # platform: "Windows 7" 34 | # }, 35 | # { 36 | # browserName: "internet explorer", 37 | # version: "8", 38 | # platform: "Windows 7" 39 | # }, 40 | 41 | # { # Unofficial 42 | # browserName: "internet explorer", 43 | # version: "7", 44 | # platform: "Windows XP" 45 | # }, 46 | 47 | { 48 | browserName: "googlechrome", 49 | platform: "Windows 8.1" 50 | }, 51 | { 52 | browserName: "firefox", 53 | platform: "Windows 8.1" 54 | }, 55 | 56 | # Win Opera 15+ not currently supported by Sauce Labs 57 | 58 | { 59 | browserName: "iphone", 60 | platform: "OS X 10.9", 61 | version: "7" 62 | }, 63 | 64 | # iOS Chrome not currently supported by Sauce Labs 65 | 66 | # Linux (unofficial) 67 | { 68 | browserName: "googlechrome", 69 | platform: "Linux" 70 | }, 71 | { 72 | browserName: "firefox", 73 | platform: "Linux" 74 | } 75 | 76 | # Android Chrome not currently supported by Sauce Labs 77 | 78 | # { # Android Browser (super-unofficial) 79 | # browserName: "android", 80 | # version: "4.0", 81 | # platform: "Linux" 82 | # } 83 | ] 84 | -------------------------------------------------------------------------------- /test-infra/uncached-npm-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cp test-infra/npm-shrinkwrap.canonical.json npm-shrinkwrap.json 3 | npm install 4 | rm npm-shrinkwrap.json 5 | --------------------------------------------------------------------------------