Orphan branch starting v3.1

Before this version jasny/bootstrap was a fork of twbs/bootstrap
This commit is contained in:
Arnold Daniels
2016-01-03 19:29:36 -04:00
commit 4ceef3e52b
116 changed files with 13898 additions and 0 deletions

11
.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

8
.gitattributes vendored Normal file
View File

@@ -0,0 +1,8 @@
# Enforce Unix newlines
*.css text eol=lf
*.html text eol=lf
*.js text eol=lf
*.json text eol=lf
*.less text eol=lf
*.md text eol=lf
*.yml text eol=lf

41
.gitignore vendored Normal file
View File

@@ -0,0 +1,41 @@
# Ignore docs files
_gh_pages
_site
.ruby-version
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.zip
*.vi
*~
# OS or Editor folders
.DS_Store
._*
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
.idea
# Komodo
*.komodoproject
.komodotools
# grunt-html-validation
validation-status.json
validation-report.json
# Folders to ignore
node_modules

28
.travis.yml Normal file
View File

@@ -0,0 +1,28 @@
language: node_js
node_js:
- "0.10"
before_install:
- time sudo pip install --use-mirrors -r test-infra/requirements.txt
- rvm use 1.9.3 --fuzzy
- if [ "$TWBS_TEST" = validate-html ]; then echo "ruby=$(basename $(rvm gemdir)) jekyll=$JEKYLL_VERSION" > pseudo_Gemfile.lock; fi
install:
- time npm install -g grunt-cli
- time ./test-infra/s3_cache.py download 'npm packages' test-infra/npm-shrinkwrap.canonical.json ./node_modules || time ./test-infra/uncached-npm-install.sh
- if [ "$TWBS_TEST" = validate-html ]; then time ./test-infra/s3_cache.py download rubygems pseudo_Gemfile.lock $(rvm gemdir) || gem install -N jekyll -v $JEKYLL_VERSION; fi
after_script:
- if [ "$TWBS_TEST" = core ]; then time ./test-infra/s3_cache.py upload 'npm packages' test-infra/npm-shrinkwrap.canonical.json ./node_modules; fi
- if [ "$TWBS_TEST" = validate-html ]; then time ./test-infra/s3_cache.py upload rubygems pseudo_Gemfile.lock $(rvm gemdir); fi
env:
global:
- JEKYLL_VERSION: 1.4.1
- SAUCE_USERNAME: bootstrap
- secure: "pJkBwnuae9dKU5tEcCqccfS1QQw7/meEcfz63fM7ba7QJNjoA6BaXj08L5Z3Vb5vBmVPwBawxo5Hp0jC0r/Z/O0hGnAmz/Cz09L+cy7dSAZ9x4hvZePSja/UAusaB5ogMoO8l2b773MzgQeSmrLbExr9BWLeqEfjC2hFgdgHLaQ="
- secure: "gqjqISbxBJK6byFbsmr1AyP1qoWH+rap06A2gI7v72+Tn2PU2nYkIMUkCvhZw6K889jv+LhQ/ybcBxDOXHpNCExCnSgB4dcnmYp+9oeNZb37jSP0rQ+Ib4OTLjzc3/FawE/fUq5kukZTC7porzc/k0qJNLAZRx3YLALmK1GIdUY="
- secure: "Gghh/e3Gsbj1+4RR9Lh2aR/xJl35HWiHqlPIeSUqE9D7uDCVTAwNce/dGL3Ew7uJPfJ6Pgr70wD3zgu3stw0Zmzayax0hiDtGwcQCxVIER08wqGANK9C2Q7PYJkNTNtiTo6ehKWbdV4Z+/U+TEYyQfpQTDbAFYk/vVpsdjp0Lmc="
- secure: "RTbRdx4G/2OTLfrZtP1VbRljxEmd6A1F3GqXboeQTldsnAlwpsES65es5CE3ub/rmixLApOY9ot7OPmNixFgC2Y8xOsV7lNCC62QVpmqQEDyGFFQKb3yO6/dmwQxdsCqGfzf9Np6Wh5V22QFvr50ZLKLd7Uhd9oXMDIk/z1MJ3o="
matrix:
- TWBS_TEST=core
- TWBS_TEST=validate-html
- TWBS_TEST=sauce-js-unit
matrix:
fast_finish: true

61
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,61 @@
# Contributing to Bootstrap
Looking to contribute something to Bootstrap? **Here's how you can help.**
## Reporting issues
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.
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.
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.
3. **Include a live example.** Make use of jsFiddle or jsBin to share your isolated test cases.
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.
## Pull requests
- CSS changes must be done in `.less` files first, never just the compiled `.css` files
- If modifying the `.less` files, always recompile and commit the compiled files `bootstrap.css` and `bootstrap.min.css`
- Try not to pollute your pull request with unintended changes--keep them simple and small
- Try to share which browsers your code has been tested in before submitting a pull request
- Pull requests should always be against the `master` branch, never against `gh-pages`.
## Coding standards
### HTML
- Two spaces for indentation, never tabs
- Double quotes only, never single quotes
- Always use proper indentation
- Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags)
- 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://`.
### CSS
- Adhere to the [RECESS CSS property order](http://markdotto.com/2011/11/29/css-property-order/)
- Multiple-line approach (one property and value per line)
- Always a space after a property's colon (e.g., `display: block;` and not `display:block;`)
- End all lines with a semi-colon
- For multiple, comma-separated selectors, place each selector on its own line
- 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).
### JS
- No semicolons
- Comma first
- 2 spaces (no tabs)
- strict mode
- "Attractive"
## License
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).
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.

390
Gruntfile.js Normal file
View File

@@ -0,0 +1,390 @@
/*!
* Bootstrap's Gruntfile
* http://getbootstrap.com
* Copyright 2013-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
module.exports = function (grunt) {
'use strict';
// Force use of Unix newlines
grunt.util.linefeed = '\n';
RegExp.quote = function (string) {
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
};
var fs = require('fs');
var path = require('path');
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
var generateRawFilesJs = require('./grunt/bs-raw-files-generator.js');
var updateShrinkwrap = require('./grunt/shrinkwrap.js');
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/*!\n' +
' * Jasny Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
' * Copyright 2012-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
' */\n',
jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Jasny Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',
// Task configuration.
clean: {
dist: ['dist', 'docs/dist'],
jekyll: ['_gh_pages'],
assets: ['assets/css/*.min.css', 'assets/js/*.min.js'],
jade: ['jade/*.jade']
},
jshint: {
options: {
jshintrc: 'js/.jshintrc'
},
grunt: {
options: {
jshintrc: 'grunt/.jshintrc'
},
src: ['Gruntfile.js', 'grunt/*.js']
},
src: {
src: 'js/*.js'
},
test: {
src: 'js/tests/unit/*.js'
},
assets: {
src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js']
}
},
jscs: {
options: {
config: 'js/.jscs.json',
},
grunt: {
src: ['Gruntfile.js', 'grunt/*.js']
},
src: {
src: 'js/*.js'
},
test: {
src: 'js/tests/unit/*.js'
},
assets: {
src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js']
}
},
csslint: {
options: {
csslintrc: 'less/.csslintrc'
},
src: [
'dist/css/<%= pkg.name %>.css',
'docs/assets/css/docs.css',
'docs/examples/**/*.css'
]
},
concat: {
options: {
banner: '<%= banner %>\n<%= jqueryCheck %>',
stripBanners: false
},
bootstrap: {
src: [
'js/offcanvas.js',
'js/rowlink.js',
'js/inputmask.js',
'js/fileinput.js'
],
dest: 'dist/js/<%= pkg.name %>.js'
}
},
uglify: {
options: {
report: 'min'
},
bootstrap: {
options: {
banner: '<%= banner %>'
},
src: '<%= concat.bootstrap.dest %>',
dest: 'dist/js/<%= pkg.name %>.min.js'
},
customize: {
options: {
preserveComments: 'some'
},
src: [
'docs/assets/js/vendor/less.min.js',
'docs/assets/js/vendor/jszip.min.js',
'docs/assets/js/vendor/uglify.min.js',
'docs/assets/js/vendor/blob.js',
'docs/assets/js/vendor/filesaver.js',
'docs/assets/js/raw-files.min.js',
'docs/assets/js/customizer.js'
],
dest: 'docs/assets/js/customize.min.js'
},
docsJs: {
options: {
preserveComments: 'some'
},
src: [
'docs/assets/js/vendor/holder.js',
'docs/assets/js/application.js'
],
dest: 'docs/assets/js/docs.min.js'
}
},
less: {
compileCore: {
options: {
strictMath: true,
sourceMap: true,
outputSourceFiles: true,
sourceMapURL: '<%= pkg.name %>.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
},
files: {
'dist/css/<%= pkg.name %>.css': 'less/build/<%= pkg.name %>.less'
}
},
minify: {
options: {
cleancss: true,
report: 'min'
},
files: {
'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css'
}
}
},
cssmin: {
compress: {
options: {
keepSpecialComments: '*',
noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css
report: 'min',
selectorsMergeMode: 'ie8'
},
src: [
'docs/assets/css/docs.css',
'docs/assets/css/pygments-manni.css'
],
dest: 'docs/assets/css/docs.min.css'
}
},
usebanner: {
dist: {
options: {
position: 'top',
banner: '<%= banner %>'
},
files: {
src: [
'dist/css/<%= pkg.name %>.css',
'dist/css/<%= pkg.name %>.min.css'
]
}
}
},
csscomb: {
options: {
config: 'less/.csscomb.json'
},
dist: {
files: {
'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css'
}
},
examples: {
expand: true,
cwd: 'docs/examples/',
src: ['**/*.css'],
dest: 'docs/examples/'
}
},
copy: {
docs: {
expand: true,
cwd: './dist',
src: [
'{css,js}/*.min.*',
'css/*.map'
],
dest: 'docs/dist'
}
},
qunit: {
options: {
inject: 'js/tests/unit/phantom.js'
},
files: 'js/tests/index.html'
},
connect: {
server: {
options: {
port: 3000,
base: '.'
}
}
},
jekyll: {
docs: {}
},
jade: {
compile: {
options: {
pretty: true,
data: function () {
var filePath = path.join(__dirname, 'less/build/variables.less');
var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'});
var parser = new BsLessdocParser(fileContent);
return {sections: parser.parseFile()};
}
},
files: {
'docs/_includes/customizer-variables.html': 'docs/jade/customizer-variables.jade',
'docs/_includes/nav-customize.html': 'docs/jade/customizer-nav.jade'
}
}
},
validation: {
options: {
charset: 'utf-8',
doctype: 'HTML5',
failHard: true,
reset: true,
relaxerror: [
'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
'Element img is missing required attribute src.'
]
},
files: {
src: '_gh_pages/**/*.html'
}
},
watch: {
src: {
files: '<%= jshint.src.src %>',
tasks: ['jshint:src', 'qunit']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/*.less',
tasks: 'less'
}
},
sed: {
versionNumber: {
pattern: (function () {
var old = grunt.option('oldver');
return old ? RegExp.quote(old) : old;
})(),
replacement: grunt.option('newver'),
recursive: true
}
},
'saucelabs-qunit': {
all: {
options: {
build: process.env.TRAVIS_JOB_ID,
concurrency: 10,
urls: ['http://127.0.0.1:3000/js/tests/index.html'],
browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml')
}
}
},
exec: {
npmUpdate: {
command: 'npm update --silent'
},
npmShrinkWrap: {
command: 'npm shrinkwrap --dev'
}
}
});
// These plugins provide necessary tasks.
require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
// Docs HTML validation task
grunt.registerTask('validate-html', ['jekyll', 'validation']);
// Test task.
var testSubtasks = [];
// Skip core tests if running a different subset of the test suite
if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') {
testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
}
// Skip HTML validation if running a different subset of the test suite
if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') {
testSubtasks.push('validate-html');
}
// Only run Sauce Labs tests if there's a Sauce access key
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
// Skip Sauce if running a different subset of the test suite
(!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) {
testSubtasks.push('connect');
testSubtasks.push('saucelabs-qunit');
}
grunt.registerTask('test', testSubtasks);
// JS distribution task.
grunt.registerTask('dist-js', ['concat', 'uglify']);
// CSS distribution task.
grunt.registerTask('dist-css', ['less', 'cssmin', 'csscomb', 'usebanner']);
// Docs distribution task.
grunt.registerTask('dist-docs', 'copy:docs');
// Full distribution task.
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'dist-js', 'dist-docs']);
// Default task.
grunt.registerTask('default', ['dist', 'build-customizer']);
// Version numbering task.
// grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
// This can be overzealous, so its changes should always be manually reviewed!
grunt.registerTask('change-version-number', 'sed');
// task for building customizer
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
grunt.registerTask('build-customizer-html', 'jade');
grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
var banner = grunt.template.process('<%= banner %>');
generateRawFilesJs(banner);
});
// Task for updating the npm packages used by the Travis build.
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
};

176
LICENSE Normal file
View File

@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

176
README.md Normal file
View File

@@ -0,0 +1,176 @@
# [Jasny Bootstrap](http://jasny.github.io/bootstrap/) [![Build Status](https://secure.travis-ci.org/jasny/bootstrap.png)](http://travis-ci.org/jasny/bootstrap)[![devDependency Status](https://david-dm.org/jasny/bootstrap/dev-status.png)](https://david-dm.org/jasny/bootstrap#info=devDependencies)
Jasny Bootstrap is a fork of the famous [Twitter Bootstrap](http://getbootstrap.com/) with added components.
* [Button labels](http://jasny.github.io/bootstrap/css/#buttons-labels)
* [Off canvas navmenu](http://jasny.github.io/bootstrap/components/#navmenu)
* [Fixed alerts](http://jasny.github.io/bootstrap/components/#alerts-fixed)
* [Row link](http://jasny.github.io/bootstrap/javascript/#rowlink)
* [Input mask](http://jasny.github.io/bootstrap/javascript/#inputmask)
* [File input widget](http://jasny.github.io/bootstrap/javascript/#fileinput)
To get started, check out <http://jasny.github.io/bootstrap>!
## Quick start
Three quick start options are available:
* [Download the latest release](https://github.com/jasny/bootstrap/releases/tag/v3.0.0-p7).
* Clone the repo: `git clone git://github.com/jasny/bootstrap.git`.
* Install with [Bower](http://bower.io): `bower install bootstrap=jasny/bootstrap`. To install Jasny Bootstrap next to Twitter Bootstrap use `bower install jasny-bootstrap=jasny/bootstrap`.
Read the [Getting Started page](http://jasny.github.io/bootstrap/getting-started/) for information on the framework contents, templates and examples, and more.
### What's included
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:
```
bootstrap/
├── css/
│ ├── bootstrap.css
│ ├── bootstrap.min.css
│ ├── bootstrap-theme.css
│ └── bootstrap-theme.min.css
├── js/
│ ├── bootstrap.js
│ └── bootstrap.min.js
└── fonts/
├── glyphicons-halflings-regular.eot
├── glyphicons-halflings-regular.svg
├── glyphicons-halflings-regular.ttf
└── glyphicons-halflings-regular.woff
```
We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). Fonts from Glyphicons are included, as is the optional Bootstrap theme.
Alternatively you can extend Twitter Bootstrap by downloading <code>jasny-bootstrap.*</code> files from the extension package, in conjunction with the original Twitter Bootstrap files or a custom build of Bootstrap. The structure of (the compiled) Jasny Bootstrap extension package is:
```
extend/
├── css/
│ ├── jasny-bootstrap.css
│ ├── jasny-bootstrap.min.css
└── js/
├── jasny-bootstrap.js
└── jasny-bootstrap.min.js
```
## Bugs and feature requests
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/).
You may use [this JS Bin](http://jsbin.com/iKumuWo/1/edit) as a template for your bug reports.
## Documentation
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 <http://jasny.github.io/bootstrap>. The docs may also be run locally.
### Running documentation locally
1. If necessary, [install Jekyll](http://jekyllrb.com/docs/installation) (requires v1.x).
2. From the root `/bootstrap` directory, run `jekyll serve` in the command line.
- **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.
3. Open <http://localhost:9001> in your browser, and voilà.
Learn more about using Jekyll by reading its [documentation](http://jekyllrb.com/docs/home/).
### Documentation for previous releases
Documentation for v2.3.2 has been made available for the time being at <http://jasny.github.io/bootstrap/2.3.2/> while folks transition to Bootstrap 3.
[Previous releases](https://github.com/jasny/bootstrap/releases) and their documentation are also available for download.
## Compiling CSS and JavaScript
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.
### Install Grunt
From the command line:
1. Install `grunt-cli` globally with `npm install -g grunt-cli`.
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.
When completed, you'll be able to run the various Grunt commands provided from the command line.
**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.
### Available Grunt commands
#### Build - `grunt`
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/).**
#### Only compile CSS and JavaScript - `grunt dist`
`grunt dist` creates the `/dist` directory with compiled files. **Uses [recess](http://twitter.github.io/recess/) and [UglifyJS](http://lisperator.net/uglifyjs/).**
#### Tests - `grunt test`
Runs [JSHint](http://jshint.com) and [QUnit](http://qunitjs.com/) tests headlessly in [PhantomJS](http://phantomjs.org/) (used for CI).
#### Watch - `grunt watch`
This is a convenience method for watching just Less files and automatically building them whenever you save.
### Troubleshooting dependencies
Should you encounter problems with installing dependencies or running Grunt commands, uninstall all previous dependency versions (global and local). Then, rerun `npm install`.
## Contributing
Please read through our [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.
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).
Editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at <http://editorconfig.org>.
With v3.1, we're moving from the Apache 2 to the MIT license for the Bootstrap code (not the docs). Please see the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md) for more information.
## Community
Keep track of development and community news.
* Follow [@ArnoldDaniels on Twitter](http://twitter.com/ArnoldDaniels).
* Have a question that's not a feature request or bug report? [Ask on stackoverflow.](http://stackoverflow.com/)
## Versioning
Jasny Bootstrap follows the version of Twitter Bootstrap added with a custom patch number.
`<major>.<minor>.<patch>-p<jasny patch>`
Backwards compatibility is only broken if Twitter Bootstrap also does so, in which case the major is incremented.
## Authors
**Mark Otto**
+ <http://twitter.com/mdo>
+ <http://github.com/mdo>
**Jacob Thornton**
+ <http://twitter.com/fat>
+ <http://github.com/fat>
**Arnold Daniels**
+ [http://twitter.com/ArnoldDaniels](http://twitter.com/ArnoldDaniels)
+ [http://github.com/jasny](http://github.com/jasny)
+ [http://jasny.net](http://jasny.net)
## Copyright and license
Copyright 2013 Twitter, Inc under [the Apache 2.0 license](LICENSE).
Copyright 2013 Jasny BV under [the Apache 2.0 license](LICENSE).

31
_config.yml Normal file
View File

@@ -0,0 +1,31 @@
# Dependencies
markdown: rdiscount
pygments: true
# Permalinks
permalink: pretty
# Server
source: ./docs
destination: ./_gh_pages
host: 0.0.0.0
port: 9001
baseurl: /
url: http://localhost:9001
encoding: UTF-8
exclude:
- "jade"
- "vendor"
# Custom vars
current_version: 3.1.0
repo: https://github.com/jasny/bootstrap
download:
source: https://github.com/jasny/bootstrap/archive/v3.1.0.zip
dist: https://github.com/jasny/bootstrap/releases/download/v3.1.0/bootstrap-3.1.0-dist.zip
cdn:
css: //cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.0/css/jasny-bootstrap.min.css
js: //cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.0/js/jasny-bootstrap.min.js

21
bower.json Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "jasny-bootstrap",
"version": "3.1.0",
"main": [
"./dist/css/jasny-bootstrap.css",
"./dist/js/jasny-bootstrap.js"
],
"ignore": [
"**/.*",
"_config.yml",
"CNAME",
"composer.json",
"CONTRIBUTING.md",
"docs",
"js/tests"
],
"dependencies": {
"jquery": ">= 1.9.0",
"bootstrap": ">= 3.0.0"
}
}

19
composer.json Normal file
View File

@@ -0,0 +1,19 @@
{
"name": "jasny/bootstrap"
, "description": "The missing bootstrap components"
, "keywords": ["bootstrap", "css"]
, "homepage": "http://jasny.github.io/bootstrap"
, "authors": [
{
"name": "Arnold Daniels",
"email": "arnold@jasny.net"
}
]
, "support": {
"issues": "https://github.com/jasny/bootstrap/issues"
}
, "license": "Apache-2.0"
, "require": {
"twitter/bootstrap" : ">=3.0.0"
}
}

599
dist/css/jasny-bootstrap.css vendored Normal file
View File

@@ -0,0 +1,599 @@
/*!
* Jasny Bootstrap v3.1.0 (http://jasny.github.io/bootstrap)
* Copyright 2012-2014 Arnold Daniels
* Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
*/
@media (min-width: 1px) {
.container-smooth {
max-width: 1170px;
}
}
.btn-labeled {
padding-top: 0;
padding-bottom: 0;
}
.btn-label {
position: relative;
left: -12px;
display: inline-block;
padding: 6px 12px;
background: transparent;
background: rgba(0, 0, 0, .15);
border-radius: 3px 0 0 3px;
}
.btn-label.btn-label-right {
right: -12px;
left: auto;
border-radius: 0 3px 3px 0;
}
.btn-lg .btn-label {
left: -16px;
padding: 10px 16px;
border-radius: 5px 0 0 5px;
}
.btn-lg .btn-label.btn-label-right {
right: -16px;
left: auto;
border-radius: 0 5px 5px 0;
}
.btn-sm .btn-label {
left: -10px;
padding: 5px 10px;
border-radius: 2px 0 0 2px;
}
.btn-sm .btn-label.btn-label-right {
right: -10px;
left: auto;
border-radius: 0 2px 2px 0;
}
.btn-xs .btn-label {
left: -5px;
padding: 1px 5px;
border-radius: 2px 0 0 2px;
}
.btn-xs .btn-label.btn-label-right {
right: -5px;
left: auto;
border-radius: 0 2px 2px 0;
}
.nav-tabs-bottom {
border-top: 1px solid #ddd;
border-bottom: 0;
}
.nav-tabs-bottom > li {
margin-top: -1px;
margin-bottom: 0;
}
.nav-tabs-bottom > li > a {
border-radius: 0 0 4px 4px;
}
.nav-tabs-bottom > li > a:hover,
.nav-tabs-bottom > li > a:focus,
.nav-tabs-bottom > li.active > a,
.nav-tabs-bottom > li.active > a:hover,
.nav-tabs-bottom > li.active > a:focus {
border: 1px solid #ddd;
border-top-color: transparent;
}
.nav-tabs-left {
border-right: 1px solid #ddd;
border-bottom: 0;
}
.nav-tabs-left > li {
float: none;
margin-right: -1px;
margin-bottom: 0;
}
.nav-tabs-left > li > a {
margin-right: 0;
margin-bottom: 2px;
border-radius: 4px 0 0 4px;
}
.nav-tabs-left > li > a:hover,
.nav-tabs-left > li > a:focus,
.nav-tabs-left > li.active > a,
.nav-tabs-left > li.active > a:hover,
.nav-tabs-left > li.active > a:focus {
border: 1px solid #ddd;
border-right-color: transparent;
}
.row > .nav-tabs-left {
position: relative;
z-index: 1;
padding-right: 0;
padding-left: 15px;
margin-right: -1px;
}
.row > .nav-tabs-left + .tab-content {
border-left: 1px solid #ddd;
}
.nav-tabs-right {
border-bottom: 0;
border-left: 1px solid #ddd;
}
.nav-tabs-right > li {
float: none;
margin-bottom: 0;
margin-left: -1px;
}
.nav-tabs-right > li > a {
margin-bottom: 2px;
margin-left: 0;
border-radius: 0 4px 4px 0;
}
.nav-tabs-right > li > a:hover,
.nav-tabs-right > li > a:focus,
.nav-tabs-right > li.active > a,
.nav-tabs-right > li.active > a:hover,
.nav-tabs-right > li.active > a:focus {
border: 1px solid #ddd;
border-left-color: transparent;
}
.row > .nav-tabs-right {
padding-right: 15px;
padding-left: 0;
}
.navmenu,
.navbar-offcanvas {
width: 300px;
height: 100%;
border-style: solid;
border-width: 1px;
border-radius: 4px;
}
.navmenu-fixed-left,
.navmenu-fixed-right,
.navbar-offcanvas {
position: fixed;
top: 0;
z-index: 1030;
border-radius: 0;
}
.navmenu-fixed-left,
.navbar-offcanvas {
left: 0;
border-width: 0 1px 0 0;
}
.navmenu-fixed-right {
right: 0;
border-width: 0 0 0 1px;
}
.navmenu-nav {
margin-bottom: 10px;
}
.navmenu-nav.dropdown-menu {
position: static;
float: none;
padding-top: 0;
margin: 0;
border: none;
border-radius: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.navbar-offcanvas .navbar-nav {
margin: 0;
}
@media (min-width: 768px) {
.navbar-offcanvas {
width: auto;
border-top: 0;
box-shadow: none;
}
.navbar-offcanvas.offcanvas {
position: static;
display: block !important;
height: auto !important;
padding-bottom: 0;
overflow: visible !important;
}
.navbar-offcanvas .navbar-nav.navbar-left:first-child {
margin-left: -15px;
}
.navbar-offcanvas .navbar-nav.navbar-right:last-child {
margin-right: -15px;
}
.navbar-offcanvas .navmenu-brand {
display: none;
}
}
.navmenu-brand {
display: block;
padding: 10px 15px;
margin: 10px 0;
font-size: 18px;
line-height: 20px;
}
.navmenu-brand:hover,
.navmenu-brand:focus {
text-decoration: none;
}
.navmenu-default,
.navbar-default .navbar-offcanvas {
background-color: #f8f8f8;
border-color: #e7e7e7;
}
.navmenu-default .navmenu-brand,
.navbar-default .navbar-offcanvas .navmenu-brand {
color: #777;
}
.navmenu-default .navmenu-brand:hover,
.navbar-default .navbar-offcanvas .navmenu-brand:hover,
.navmenu-default .navmenu-brand:focus,
.navbar-default .navbar-offcanvas .navmenu-brand:focus {
color: #5e5e5e;
background-color: transparent;
}
.navmenu-default .navmenu-text,
.navbar-default .navbar-offcanvas .navmenu-text {
color: #777;
}
.navmenu-default .navmenu-nav > .dropdown > a:hover .caret,
.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a:hover .caret,
.navmenu-default .navmenu-nav > .dropdown > a:focus .caret,
.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a:focus .caret {
border-top-color: #333;
border-bottom-color: #333;
}
.navmenu-default .navmenu-nav > .open > a,
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a,
.navmenu-default .navmenu-nav > .open > a:hover,
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:hover,
.navmenu-default .navmenu-nav > .open > a:focus,
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:focus {
color: #555;
background-color: #e7e7e7;
}
.navmenu-default .navmenu-nav > .open > a .caret,
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a .caret,
.navmenu-default .navmenu-nav > .open > a:hover .caret,
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:hover .caret,
.navmenu-default .navmenu-nav > .open > a:focus .caret,
.navbar-default .navbar-offcanvas .navmenu-nav > .open > a:focus .caret {
border-top-color: #555;
border-bottom-color: #555;
}
.navmenu-default .navmenu-nav > .dropdown > a .caret,
.navbar-default .navbar-offcanvas .navmenu-nav > .dropdown > a .caret {
border-top-color: #777;
border-bottom-color: #777;
}
.navmenu-default .navmenu-nav.dropdown-menu,
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu {
background-color: #e7e7e7;
}
.navmenu-default .navmenu-nav.dropdown-menu > .divider,
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .divider {
background-color: #f8f8f8;
}
.navmenu-default .navmenu-nav.dropdown-menu > .active > a,
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a,
.navmenu-default .navmenu-nav.dropdown-menu > .active > a:hover,
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:hover,
.navmenu-default .navmenu-nav.dropdown-menu > .active > a:focus,
.navbar-default .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:focus {
background-color: #d7d7d7;
}
.navmenu-default .navmenu-nav > li > a,
.navbar-default .navbar-offcanvas .navmenu-nav > li > a {
color: #777;
}
.navmenu-default .navmenu-nav > li > a:hover,
.navbar-default .navbar-offcanvas .navmenu-nav > li > a:hover,
.navmenu-default .navmenu-nav > li > a:focus,
.navbar-default .navbar-offcanvas .navmenu-nav > li > a:focus {
color: #333;
background-color: transparent;
}
.navmenu-default .navmenu-nav > .active > a,
.navbar-default .navbar-offcanvas .navmenu-nav > .active > a,
.navmenu-default .navmenu-nav > .active > a:hover,
.navbar-default .navbar-offcanvas .navmenu-nav > .active > a:hover,
.navmenu-default .navmenu-nav > .active > a:focus,
.navbar-default .navbar-offcanvas .navmenu-nav > .active > a:focus {
color: #555;
background-color: #e7e7e7;
}
.navmenu-default .navmenu-nav > .disabled > a,
.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a,
.navmenu-default .navmenu-nav > .disabled > a:hover,
.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a:hover,
.navmenu-default .navmenu-nav > .disabled > a:focus,
.navbar-default .navbar-offcanvas .navmenu-nav > .disabled > a:focus {
color: #ccc;
background-color: transparent;
}
.navmenu-inverse,
.navbar-inverse .navbar-offcanvas {
background-color: #222;
border-color: #080808;
}
.navmenu-inverse .navmenu-brand,
.navbar-inverse .navbar-offcanvas .navmenu-brand {
color: #999;
}
.navmenu-inverse .navmenu-brand:hover,
.navbar-inverse .navbar-offcanvas .navmenu-brand:hover,
.navmenu-inverse .navmenu-brand:focus,
.navbar-inverse .navbar-offcanvas .navmenu-brand:focus {
color: #fff;
background-color: transparent;
}
.navmenu-inverse .navmenu-text,
.navbar-inverse .navbar-offcanvas .navmenu-text {
color: #999;
}
.navmenu-inverse .navmenu-nav > .dropdown > a:hover .caret,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a:hover .caret,
.navmenu-inverse .navmenu-nav > .dropdown > a:focus .caret,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a:focus .caret {
border-top-color: #fff;
border-bottom-color: #fff;
}
.navmenu-inverse .navmenu-nav > .open > a,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a,
.navmenu-inverse .navmenu-nav > .open > a:hover,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:hover,
.navmenu-inverse .navmenu-nav > .open > a:focus,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:focus {
color: #fff;
background-color: #080808;
}
.navmenu-inverse .navmenu-nav > .open > a .caret,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a .caret,
.navmenu-inverse .navmenu-nav > .open > a:hover .caret,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:hover .caret,
.navmenu-inverse .navmenu-nav > .open > a:focus .caret,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .open > a:focus .caret {
border-top-color: #fff;
border-bottom-color: #fff;
}
.navmenu-inverse .navmenu-nav > .dropdown > a .caret,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .dropdown > a .caret {
border-top-color: #999;
border-bottom-color: #999;
}
.navmenu-inverse .navmenu-nav.dropdown-menu,
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu {
background-color: #080808;
}
.navmenu-inverse .navmenu-nav.dropdown-menu > .divider,
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .divider {
background-color: #222;
}
.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a,
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a,
.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a:hover,
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:hover,
.navmenu-inverse .navmenu-nav.dropdown-menu > .active > a:focus,
.navbar-inverse .navbar-offcanvas .navmenu-nav.dropdown-menu > .active > a:focus {
background-color: #000;
}
.navmenu-inverse .navmenu-nav > li > a,
.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a {
color: #999;
}
.navmenu-inverse .navmenu-nav > li > a:hover,
.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a:hover,
.navmenu-inverse .navmenu-nav > li > a:focus,
.navbar-inverse .navbar-offcanvas .navmenu-nav > li > a:focus {
color: #fff;
background-color: transparent;
}
.navmenu-inverse .navmenu-nav > .active > a,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a,
.navmenu-inverse .navmenu-nav > .active > a:hover,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a:hover,
.navmenu-inverse .navmenu-nav > .active > a:focus,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .active > a:focus {
color: #fff;
background-color: #080808;
}
.navmenu-inverse .navmenu-nav > .disabled > a,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a,
.navmenu-inverse .navmenu-nav > .disabled > a:hover,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a:hover,
.navmenu-inverse .navmenu-nav > .disabled > a:focus,
.navbar-inverse .navbar-offcanvas .navmenu-nav > .disabled > a:focus {
color: #444;
background-color: transparent;
}
.alert-fixed-top,
.alert-fixed-bottom {
position: fixed;
left: 0;
z-index: 1035;
width: 100%;
margin: 0;
border-radius: 0;
}
@media (min-width: 992px) {
.alert-fixed-top,
.alert-fixed-bottom {
left: 50%;
width: 992px;
margin-left: -496px;
}
}
.alert-fixed-top {
top: 0;
border-width: 0 0 1px 0;
}
@media (min-width: 992px) {
.alert-fixed-top {
border-width: 0 1px 1px 1px;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
}
.alert-fixed-bottom {
bottom: 0;
border-width: 1px 0 0 0;
}
@media (min-width: 992px) {
.alert-fixed-bottom {
border-width: 1px 1px 0 1px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
}
.offcanvas {
display: none;
}
.offcanvas.in {
display: block;
}
@media (max-width: 767px) {
.offcanvas-xs {
display: none;
}
.offcanvas-xs.in {
display: block;
}
}
@media (max-width: 991px) {
.offcanvas-sm {
display: none;
}
.offcanvas-sm.in {
display: block;
}
}
@media (max-width: 1199px) {
.offcanvas-md {
display: none;
}
.offcanvas-md.in {
display: block;
}
}
.offcanvas-lg {
display: none;
}
.offcanvas-lg.in {
display: block;
}
.canvas-sliding {
-webkit-transition: top .35s, left .35s, bottom .35s, right .35s;
transition: top .35s, left .35s, bottom .35s, right .35s;
}
.offcanvas-clone {
position: absolute !important;
top: auto !important;
right: 0 !important;
bottom: 0 !important;
left: auto !important;
width: 0 !important;
height: 0 !important;
padding: 0 !important;
margin: 0 !important;
overflow: hidden !important;
border: none !important;
opacity: 0 !important;
}
.table.rowlink td:not(.rowlink-skip),
.table .rowlink td:not(.rowlink-skip) {
cursor: pointer;
}
.table.rowlink td:not(.rowlink-skip) a,
.table .rowlink td:not(.rowlink-skip) a {
font: inherit;
color: inherit;
text-decoration: inherit;
}
.table-hover.rowlink tr:hover td,
.table-hover .rowlink tr:hover td {
background-color: #cfcfcf;
}
.btn-file {
position: relative;
overflow: hidden;
vertical-align: middle;
}
.btn-file > input {
position: absolute;
top: 0;
right: 0;
height: 100%;
margin: 0;
font-size: 23px;
cursor: pointer;
filter: alpha(opacity=0);
opacity: 0;
transform: translate(-300px, 0) scale(4);
direction: ltr;
}
.fileinput {
display: inline-block;
margin-bottom: 9px;
}
.fileinput .form-control {
display: inline-block;
padding-top: 7px;
padding-bottom: 5px;
margin-bottom: 0;
vertical-align: middle;
cursor: text;
}
.fileinput .thumbnail {
display: inline-block;
margin-bottom: 5px;
overflow: hidden;
text-align: center;
vertical-align: middle;
}
.fileinput .thumbnail > img {
max-height: 100%;
}
.fileinput .btn {
vertical-align: middle;
}
.fileinput-exists .fileinput-new,
.fileinput-new .fileinput-exists {
display: none;
}
.fileinput-inline .fileinput-controls {
display: inline;
}
.fileinput-filename {
display: inline-block;
overflow: hidden;
vertical-align: middle;
}
.form-control .fileinput-filename {
vertical-align: bottom;
}
.fileinput-new .input-group .btn-file {
border-radius: 0 4px 4px 0;
}
.fileinput-new .input-group .btn-file.btn-xs,
.fileinput-new .input-group .btn-file.btn-sm {
border-radius: 0 3px 3px 0;
}
.fileinput-new .input-group .btn-file.btn-lg {
border-radius: 0 6px 6px 0;
}
.form-group.has-warning .fileinput .fileinput-preview {
color: #8a6d3b;
}
.form-group.has-warning .fileinput .thumbnail {
border-color: #faebcc;
}
.form-group.has-error .fileinput .fileinput-preview {
color: #a94442;
}
.form-group.has-error .fileinput .thumbnail {
border-color: #ebccd1;
}
.form-group.has-success .fileinput .fileinput-preview {
color: #3c763d;
}
.form-group.has-success .fileinput .thumbnail {
border-color: #d6e9c6;
}
.input-group-addon:not(:first-child) {
border-left: 0;
}
/*# sourceMappingURL=jasny-bootstrap.css.map */

1
dist/css/jasny-bootstrap.css.map vendored Normal file

File diff suppressed because one or more lines are too long

7
dist/css/jasny-bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

941
dist/js/jasny-bootstrap.js vendored Normal file
View File

@@ -0,0 +1,941 @@
/*!
* Jasny Bootstrap v3.1.0 (http://jasny.github.io/bootstrap)
* Copyright 2012-2014 Arnold Daniels
* Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)
*/
if (typeof jQuery === 'undefined') { throw new Error('Jasny Bootstrap\'s JavaScript requires jQuery') }
/* ========================================================================
* Bootstrap: offcanvas.js v3.0.3-p7
* http://jasny.github.io/bootstrap/javascript.html#offcanvas
*
* Based on Boostrap collapse.js by Twitter, Inc.
* ========================================================================
* Copyright 2013 Jasny, BV.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// OFFCANVAS PUBLIC CLASS DEFINITION
// =================================
var OffCanvas = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, OffCanvas.DEFAULTS, options)
this.state = null
if (this.options.recalc) {
this.calcClone()
$(window).on('resize', $.proxy(this.recalc, this))
}
if (this.options.autohide)
$(document).on('click', $.proxy(this.autohide, this))
if (this.options.toggle) this.toggle()
}
OffCanvas.DEFAULTS = {
toggle: true,
placement: 'left',
autohide: true,
recalc: true
}
OffCanvas.prototype.offset = function () {
switch (this.options.placement) {
case 'left':
case 'right': return this.$element.outerWidth()
case 'top':
case 'bottom': return this.$element.outerHeight()
}
}
OffCanvas.prototype.calcPlacement = function () {
var horizontal = $(window).width() / this.$element.width(),
vertical = $(window).height() / this.$element.height()
if (!this.$element.hasClass('in')) {
this.$element.css('visiblity', 'hidden !important').addClass('in')
}
var element = this.$element
function ab(a, b) {
if (element.css(b) === 'auto') return a
if (element.css(a) === 'auto') return b
var size_a = parseInt(element.css(a), 10),
size_b = parseInt(element.css(b), 10)
return size_a > size_b ? b : a
}
this.options.placement = horizontal > vertical ? ab('left', 'right') : ab('top', 'bottom')
if (this.$element.css('visibility') === 'hidden !important') {
this.$element.removeClass('in').css('visiblity', '')
}
}
OffCanvas.prototype.opposite = function (placement) {
switch (placement) {
case 'top': return 'bottom'
case 'left': return 'right'
case 'bottom': return 'top'
case 'right': return 'left'
}
}
OffCanvas.prototype.getCanvasElements = function() {
// Return a set containing the canvas plus all fixed elements
var canvas = this.options.canvas ? $(this.options.canvas) : this.$element
var fixed_elements = canvas.find('*').filter(function() {
return $(this).css('position') === 'fixed'
}).not(this.options.exclude)
return canvas.add(fixed_elements)
}
OffCanvas.prototype.slide = function (elements, offset, callback) {
// Use jQuery animation if CSS transitions aren't supported
if (!$.support.transition) {
var anim = {}
anim[this.options.placement] = "+=" + offset
return elements.animate(anim, 350, callback)
}
var placement = this.options.placement,
opposite = this.opposite(placement)
elements.each(function() {
if ($(this).css(placement) !== 'auto')
$(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
if ($(this).css(opposite) !== 'auto')
$(this).css(opposite, (parseInt($(this).css(opposite), 10) || 0) - offset)
})
this.$element
.one($.support.transition.end, callback)
.emulateTransitionEnd(350)
}
OffCanvas.prototype.disableScrolling = function() {
var bodyWidth = $('body').width()
var prop = 'padding-' + this.opposite(this.options.placement)
if ($('body').data('offcanvas-style') === undefined) $('body').data('offcanvas-style', $('body').attr('style'))
$('body').css('overflow', 'hidden')
if ($('body').width() > bodyWidth) {
var padding = parseInt($('body').css(prop), 10) + $('body').width() - bodyWidth
setTimeout(function() {
$('body').css(prop, padding)
}, 1)
}
}
OffCanvas.prototype.show = function () {
if (this.state) return
var startEvent = $.Event('show.bs.offcanvas')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
if (this.options.placement === 'auto') this.calcPlacement()
this.state = 'sliding'
var elements = this.getCanvasElements()
var offset = this.offset(),
placement = this.options.placement,
opposite = this.opposite(placement)
elements.addClass('canvas-sliding').each(function() {
$(this).data('offcanvas-style', $(this).attr('style') || '')
if ($(this).css('position') === 'static') $(this).css('position', 'relative')
if (($(this).css(placement) === 'auto' || $(this).css(placement) === '0px') &&
($(this).css(opposite) === 'auto' || $(this).css(opposite) === '0px')) {
$(this).css(placement, 0)
}
})
if (elements.index(this.$element) !== -1) this.$element.css(placement, -1 * offset)
this.disableScrolling()
var complete = function () {
this.state = 'slid'
elements.removeClass('canvas-sliding').addClass('canvas-slid')
this.$element.trigger('shown.bs.offcanvas')
}
setTimeout($.proxy(function() {
this.$element.addClass('in')
this.slide(elements, offset, $.proxy(complete, this))
}, this), 1)
}
OffCanvas.prototype.hide = function (fast) {
if (this.state !== 'slid') return
var startEvent = $.Event('hide.bs.offcanvas')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
this.state = 'sliding'
var elements = $('.canvas-slid')
var offset = -1 * this.offset()
var complete = function () {
this.state = null
this.$element.removeClass('in')
elements.removeClass('canvas-sliding')
elements.add('body').each(function() {
$(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
})
this.$element.trigger('hidden.bs.offcanvas')
}
elements.removeClass('canvas-slid').addClass('canvas-sliding')
setTimeout($.proxy(function() {
this.slide(elements, offset, $.proxy(complete, this))
}, this), 1)
}
OffCanvas.prototype.toggle = function () {
if (this.state === 'sliding') return
this[this.state === 'slid' ? 'hide' : 'show']()
}
OffCanvas.prototype.calcClone = function() {
this.$calcClone = this.$element.clone()
.html('')
.addClass('offcanvas-clone').removeClass('in')
.appendTo($('body'))
}
OffCanvas.prototype.recalc = function () {
if (this.state() !== 'slid' || this.$calcClone.css('display') === 'none') return
var offset = -1 * this.offset()
var placement = this.options.placement
this.getCanvasElements().each(function() {
$(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
}).removeClass('canvas-slid')
$('body').css('overflow', '')
this.$element.css(placement, '').removeClass('in canvas-slid')
}
OffCanvas.prototype.autohide = function (e) {
if ($(e.target).closest(this.$element).length === 0) this.hide()
}
// OFFCANVAS PLUGIN DEFINITION
// ==========================
var old = $.fn.offcanvas
$.fn.offcanvas = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.offcanvas')
var options = $.extend({}, OffCanvas.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.offcanvas', (data = new OffCanvas(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.offcanvas.Constructor = OffCanvas
// OFFCANVAS NO CONFLICT
// ====================
$.fn.offcanvas.noConflict = function () {
$.fn.offcanvas = old
return this
}
// OFFCANVAS DATA-API
// =================
$(document).on('click.bs.offcanvas.data-api', '[data-toggle=offcanvas]', function (e) {
var $this = $(this), href
var target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
var $canvas = $(target)
var data = $canvas.data('bs.offcanvas')
var option = data ? 'toggle' : $this.data()
e.stopPropagation()
if (data) data.toggle()
else $canvas.offcanvas(option)
})
}(window.jQuery);
/* ============================================================
* Bootstrap: rowlink.js v3.0.0-p7
* http://jasny.github.io/bootstrap/javascript.html#rowlink
* ============================================================
* Copyright 2012 Jasny BV, Netherlands.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
+function ($) { "use strict";
var Rowlink = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Rowlink.DEFAULTS, options)
this.$element.on('click.bs.rowlink', 'td:not(.rowlink-skip)', $.proxy(this.click, this))
}
Rowlink.DEFAULTS = {
target: "a"
}
Rowlink.prototype.click = function(e) {
var target = $(e.currentTarget).closest('tr').find(this.options.target)[0]
if ($(e.target)[0] === target) return
e.preventDefault();
if (target.click) {
target.click()
} else if (document.createEvent) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
target.dispatchEvent(evt);
}
}
// ROWLINK PLUGIN DEFINITION
// ===========================
var old = $.fn.rowlink
$.fn.rowlink = function (options) {
return this.each(function () {
var $this = $(this)
var data = $this.data('rowlink')
if (!data) $this.data('rowlink', (data = new Rowlink(this, options)))
})
}
$.fn.rowlink.Constructor = Rowlink
// ROWLINK NO CONFLICT
// ====================
$.fn.rowlink.noConflict = function () {
$.fn.rowlink = old
return this
}
// ROWLINK DATA-API
// ==================
$(document).on('click.bs.rowlink.data-api', '[data-link="row"]', function (e) {
var $this = $(this)
if ($this.data('rowlink')) return
$this.rowlink($this.data())
$(e.target).trigger('click.bs.rowlink')
})
}(window.jQuery);
/* ===========================================================
* Bootstrap: inputmask.js v3.0.0-p7
* http://jasny.github.io/bootstrap/javascript.html#inputmask
* Based on Masked Input plugin by Josh Bush (digitalbush.com)
* ===========================================================
* Copyright 2012 Jasny BV, Netherlands.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
+function ($) { "use strict";
var isIphone = (window.orientation !== undefined)
var isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1
var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
// INPUTMASK PUBLIC CLASS DEFINITION
// =================================
var Inputmask = function (element, options) {
if (isAndroid) return // No support because caret positioning doesn't work on Android
this.$element = $(element)
this.options = $.extend({}, Inputmask.DEFAULS, options)
this.mask = String(this.options.mask)
this.init()
this.listen()
this.checkVal() //Perform initial check for existing values
}
Inputmask.DEFAULS = {
mask: "",
placeholder: "_",
definitions: {
'9': "[0-9]",
'a': "[A-Za-z]",
'?': "[A-Za-z0-9]",
'*': "."
}
}
Inputmask.prototype.init = function() {
var defs = this.options.definitions
var len = this.mask.length
this.tests = []
this.partialPosition = this.mask.length
this.firstNonMaskPos = null
$.each(this.mask.split(""), $.proxy(function(i, c) {
if (c == '?') {
len--
this.partialPosition = i
} else if (defs[c]) {
this.tests.push(new RegExp(defs[c]))
if (this.firstNonMaskPos === null)
this.firstNonMaskPos = this.tests.length - 1
} else {
this.tests.push(null)
}
}, this))
this.buffer = $.map(this.mask.split(""), $.proxy(function(c, i) {
if (c != '?') return defs[c] ? this.options.placeholder : c
}, this))
this.focusText = this.$element.val()
this.$element.data("rawMaskFn", $.proxy(function() {
return $.map(this.buffer, function(c, i) {
return this.tests[i] && c != this.options.placeholder ? c : null
}).join('')
}, this))
}
Inputmask.prototype.listen = function() {
if (this.$element.attr("readonly")) return
var pasteEventName = (isIE ? 'paste' : 'input') + ".mask"
this.$element
.on("unmask.bs.inputmask", $.proxy(this.unmask, this))
.on("focus.bs.inputmask", $.proxy(this.focusEvent, this))
.on("blur.bs.inputmask", $.proxy(this.blurEvent, this))
.on("keydown.bs.inputmask", $.proxy(this.keydownEvent, this))
.on("keypress.bs.inputmask", $.proxy(this.keypressEvent, this))
.on(pasteEventName, $.proxy(this.pasteEvent, this))
}
//Helper Function for Caret positioning
Inputmask.prototype.caret = function(begin, end) {
if (this.$element.length === 0) return
if (typeof begin == 'number') {
end = (typeof end == 'number') ? end : begin
return this.$element.each(function() {
if (this.setSelectionRange) {
this.setSelectionRange(begin, end)
} else if (this.createTextRange) {
var range = this.createTextRange()
range.collapse(true)
range.moveEnd('character', end)
range.moveStart('character', begin)
range.select()
}
})
} else {
if (this.$element[0].setSelectionRange) {
begin = this.$element[0].selectionStart
end = this.$element[0].selectionEnd
} else if (document.selection && document.selection.createRange) {
var range = document.selection.createRange()
begin = 0 - range.duplicate().moveStart('character', -100000)
end = begin + range.text.length
}
return {
begin: begin,
end: end
}
}
}
Inputmask.prototype.seekNext = function(pos) {
var len = this.mask.length
while (++pos <= len && !this.tests[pos]);
return pos
}
Inputmask.prototype.seekPrev = function(pos) {
while (--pos >= 0 && !this.tests[pos]);
return pos
}
Inputmask.prototype.shiftL = function(begin,end) {
var len = this.mask.length
if (begin < 0) return
for (var i = begin, j = this.seekNext(end); i < len; i++) {
if (this.tests[i]) {
if (j < len && this.tests[i].test(this.buffer[j])) {
this.buffer[i] = this.buffer[j]
this.buffer[j] = this.options.placeholder
} else
break
j = this.seekNext(j)
}
}
this.writeBuffer()
this.caret(Math.max(this.firstNonMaskPos, begin))
}
Inputmask.prototype.shiftR = function(pos) {
var len = this.mask.length
for (var i = pos, c = this.options.placeholder; i < len; i++) {
if (this.tests[i]) {
var j = this.seekNext(i)
var t = this.buffer[i]
this.buffer[i] = c
if (j < len && this.tests[j].test(t))
c = t
else
break
}
}
},
Inputmask.prototype.unmask = function() {
this.$element
.unbind(".mask")
.removeData("inputmask")
}
Inputmask.prototype.focusEvent = function() {
this.focusText = this.$element.val()
var len = this.mask.length
var pos = this.checkVal()
this.writeBuffer()
var that = this
var moveCaret = function() {
if (pos == len)
that.caret(0, pos)
else
that.caret(pos)
}
moveCaret()
setTimeout(moveCaret, 50)
}
Inputmask.prototype.blurEvent = function() {
this.checkVal()
if (this.$element.val() !== this.focusText)
this.$element.trigger('change')
}
Inputmask.prototype.keydownEvent = function(e) {
var k = e.which
//backspace, delete, and escape get special treatment
if (k == 8 || k == 46 || (isIphone && k == 127)) {
var pos = this.caret(),
begin = pos.begin,
end = pos.end
if (end - begin === 0) {
begin = k != 46 ? this.seekPrev(begin) : (end = this.seekNext(begin - 1))
end = k == 46 ? this.seekNext(end) : end
}
this.clearBuffer(begin, end)
this.shiftL(begin, end - 1)
return false
} else if (k == 27) {//escape
this.$element.val(this.focusText)
this.caret(0, this.checkVal())
return false
}
}
Inputmask.prototype.keypressEvent = function(e) {
var len = this.mask.length
var k = e.which,
pos = this.caret()
if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
return true
} else if (k) {
if (pos.end - pos.begin !== 0) {
this.clearBuffer(pos.begin, pos.end)
this.shiftL(pos.begin, pos.end - 1)
}
var p = this.seekNext(pos.begin - 1)
if (p < len) {
var c = String.fromCharCode(k)
if (this.tests[p].test(c)) {
this.shiftR(p)
this.buffer[p] = c
this.writeBuffer()
var next = this.seekNext(p)
this.caret(next)
}
}
return false
}
}
Inputmask.prototype.pasteEvent = function() {
var that = this
setTimeout(function() {
that.caret(that.checkVal(true))
}, 0)
}
Inputmask.prototype.clearBuffer = function(start, end) {
var len = this.mask.length
for (var i = start; i < end && i < len; i++) {
if (this.tests[i])
this.buffer[i] = this.options.placeholder
}
}
Inputmask.prototype.writeBuffer = function() {
return this.$element.val(this.buffer.join('')).val()
}
Inputmask.prototype.checkVal = function(allow) {
var len = this.mask.length
//try to place characters where they belong
var test = this.$element.val()
var lastMatch = -1
for (var i = 0, pos = 0; i < len; i++) {
if (this.tests[i]) {
this.buffer[i] = this.options.placeholder
while (pos++ < test.length) {
var c = test.charAt(pos - 1)
if (this.tests[i].test(c)) {
this.buffer[i] = c
lastMatch = i
break
}
}
if (pos > test.length)
break
} else if (this.buffer[i] == test.charAt(pos) && i != this.partialPosition) {
pos++
lastMatch = i
}
}
if (!allow && lastMatch + 1 < this.partialPosition) {
this.$element.val("")
this.clearBuffer(0, len)
} else if (allow || lastMatch + 1 >= this.partialPosition) {
this.writeBuffer()
if (!allow) this.$element.val(this.$element.val().substring(0, lastMatch + 1))
}
return (this.partialPosition ? i : this.firstNonMaskPos)
}
// INPUTMASK PLUGIN DEFINITION
// ===========================
var old = $.fn.inputmask
$.fn.inputmask = function (options) {
return this.each(function () {
var $this = $(this)
var data = $this.data('inputmask')
if (!data) $this.data('inputmask', (data = new Inputmask(this, options)))
})
}
$.fn.inputmask.Constructor = Inputmask
// INPUTMASK NO CONFLICT
// ====================
$.fn.inputmask.noConflict = function () {
$.fn.inputmask = old
return this
}
// INPUTMASK DATA-API
// ==================
$(document).on('focus.bs.inputmask.data-api', '[data-mask]', function (e) {
var $this = $(this)
if ($this.data('inputmask')) return
$this.inputmask($this.data())
})
}(window.jQuery);
/* ===========================================================
* Bootstrap: fileinput.js v3.1.0
* http://jasny.github.com/bootstrap/javascript/#fileinput
* ===========================================================
* Copyright 2012-2014 Jasny BV, Netherlands.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
+function ($) { "use strict";
var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
// FILEUPLOAD PUBLIC CLASS DEFINITION
// =================================
var Fileinput = function (element, options) {
this.$element = $(element)
this.$input = this.$element.find(':file')
if (this.$input.length === 0) return
this.name = this.$input.attr('name') || options.name
this.$hidden = this.$element.find('input[type=hidden][name="' + this.name + '"]')
if (this.$hidden.length === 0) {
this.$hidden = $('<input type="hidden" />')
this.$element.prepend(this.$hidden)
}
this.$preview = this.$element.find('.fileinput-preview')
var height = this.$preview.css('height')
if (this.$preview.css('display') != 'inline' && height != '0px' && height != 'none') this.$preview.css('line-height', height)
this.original = {
exists: this.$element.hasClass('fileinput-exists'),
preview: this.$preview.html(),
hiddenVal: this.$hidden.val()
}
this.listen()
}
Fileinput.prototype.listen = function() {
this.$input.on('change.bs.fileinput', $.proxy(this.change, this))
$(this.$input[0].form).on('reset.bs.fileinput', $.proxy(this.reset, this))
this.$element.find('[data-trigger="fileinput"]').on('click.bs.fileinput', $.proxy(this.trigger, this))
this.$element.find('[data-dismiss="fileinput"]').on('click.bs.fileinput', $.proxy(this.clear, this))
},
Fileinput.prototype.change = function(e) {
if (e.target.files === undefined) e.target.files = e.target && e.target.value ? [ {name: e.target.value.replace(/^.+\\/, '')} ] : []
if (e.target.files.length === 0) return
this.$hidden.val('')
this.$hidden.attr('name', '')
this.$input.attr('name', this.name)
var file = e.target.files[0]
if (this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
var reader = new FileReader()
var preview = this.$preview
var element = this.$element
reader.onload = function(re) {
var $img = $('<img>') // .attr('src', re.target.result)
$img[0].src = re.target.result
e.target.files[0].result = re.target.result
element.find('.fileinput-filename').text(file.name)
// if parent has max-height, using `(max-)height: 100%` on child doesn't take padding and border into account
if (preview.css('max-height') != 'none') $img.css('max-height', parseInt(preview.css('max-height'), 10) - parseInt(preview.css('padding-top'), 10) - parseInt(preview.css('padding-bottom'), 10) - parseInt(preview.css('border-top'), 10) - parseInt(preview.css('border-bottom'), 10))
preview.html($img)
element.addClass('fileinput-exists').removeClass('fileinput-new')
element.trigger('change.bs.fileinput', e.target.files)
}
reader.readAsDataURL(file)
} else {
this.$element.find('.fileinput-filename').text(file.name)
this.$preview.text(file.name)
this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
this.$element.trigger('change.bs.fileinput')
}
},
Fileinput.prototype.clear = function(e) {
if (e) e.preventDefault()
this.$hidden.val('')
this.$hidden.attr('name', this.name)
this.$input.attr('name', '')
//ie8+ doesn't support changing the value of input with type=file so clone instead
if (isIE) {
var inputClone = this.$input.clone(true);
this.$input.after(inputClone);
this.$input.remove();
this.$input = inputClone;
} else {
this.$input.val('')
}
this.$preview.html('')
this.$element.find('.fileinput-filename').text('')
this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
if (e !== false) {
this.$input.trigger('change')
this.$element.trigger('clear.bs.fileinput')
}
},
Fileinput.prototype.reset = function() {
this.clear(false)
this.$hidden.val(this.original.hiddenVal)
this.$preview.html(this.original.preview)
this.$element.find('.fileinput-filename').text('')
if (this.original.exists) this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
else this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
this.$element.trigger('reset.bs.fileinput')
},
Fileinput.prototype.trigger = function(e) {
this.$input.trigger('click')
e.preventDefault()
}
// FILEUPLOAD PLUGIN DEFINITION
// ===========================
var old = $.fn.fileinput
$.fn.fileinput = function (options) {
return this.each(function () {
var $this = $(this),
data = $this.data('fileinput')
if (!data) $this.data('fileinput', (data = new Fileinput(this, options)))
if (typeof options == 'string') data[options]()
})
}
$.fn.fileinput.Constructor = Fileinput
// FILEINPUT NO CONFLICT
// ====================
$.fn.fileinput.noConflict = function () {
$.fn.fileinput = old
return this
}
// FILEUPLOAD DATA-API
// ==================
$(document).on('click.fileinput.data-api', '[data-provides="fileinput"]', function (e) {
var $this = $(this)
if ($this.data('fileinput')) return
$this.fileinput($this.data())
var $target = $(e.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');
if ($target.length > 0) {
e.preventDefault()
$target.trigger('click.bs.fileinput')
}
})
}(window.jQuery);

6
dist/js/jasny-bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

319
docs/LICENSE Normal file
View File

@@ -0,0 +1,319 @@
Creative Commons Legal Code
Attribution 3.0 Unported
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
CONDITIONS.
1. Definitions
a. "Adaptation" means a work based upon the Work, or upon the Work and
other pre-existing works, such as a translation, adaptation,
derivative work, arrangement of music or other alterations of a
literary or artistic work, or phonogram or performance and includes
cinematographic adaptations or any other form in which the Work may be
recast, transformed, or adapted including in any form recognizably
derived from the original, except that a work that constitutes a
Collection will not be considered an Adaptation for the purpose of
this License. For the avoidance of doubt, where the Work is a musical
work, performance or phonogram, the synchronization of the Work in
timed-relation with a moving image ("synching") will be considered an
Adaptation for the purpose of this License.
b. "Collection" means a collection of literary or artistic works, such as
encyclopedias and anthologies, or performances, phonograms or
broadcasts, or other works or subject matter other than works listed
in Section 1(f) below, which, by reason of the selection and
arrangement of their contents, constitute intellectual creations, in
which the Work is included in its entirety in unmodified form along
with one or more other contributions, each constituting separate and
independent works in themselves, which together are assembled into a
collective whole. A work that constitutes a Collection will not be
considered an Adaptation (as defined above) for the purposes of this
License.
c. "Distribute" means to make available to the public the original and
copies of the Work or Adaptation, as appropriate, through sale or
other transfer of ownership.
d. "Licensor" means the individual, individuals, entity or entities that
offer(s) the Work under the terms of this License.
e. "Original Author" means, in the case of a literary or artistic work,
the individual, individuals, entity or entities who created the Work
or if no individual or entity can be identified, the publisher; and in
addition (i) in the case of a performance the actors, singers,
musicians, dancers, and other persons who act, sing, deliver, declaim,
play in, interpret or otherwise perform literary or artistic works or
expressions of folklore; (ii) in the case of a phonogram the producer
being the person or legal entity who first fixes the sounds of a
performance or other sounds; and, (iii) in the case of broadcasts, the
organization that transmits the broadcast.
f. "Work" means the literary and/or artistic work offered under the terms
of this License including without limitation any production in the
literary, scientific and artistic domain, whatever may be the mode or
form of its expression including digital form, such as a book,
pamphlet and other writing; a lecture, address, sermon or other work
of the same nature; a dramatic or dramatico-musical work; a
choreographic work or entertainment in dumb show; a musical
composition with or without words; a cinematographic work to which are
assimilated works expressed by a process analogous to cinematography;
a work of drawing, painting, architecture, sculpture, engraving or
lithography; a photographic work to which are assimilated works
expressed by a process analogous to photography; a work of applied
art; an illustration, map, plan, sketch or three-dimensional work
relative to geography, topography, architecture or science; a
performance; a broadcast; a phonogram; a compilation of data to the
extent it is protected as a copyrightable work; or a work performed by
a variety or circus performer to the extent it is not otherwise
considered a literary or artistic work.
g. "You" means an individual or entity exercising rights under this
License who has not previously violated the terms of this License with
respect to the Work, or who has received express permission from the
Licensor to exercise rights under this License despite a previous
violation.
h. "Publicly Perform" means to perform public recitations of the Work and
to communicate to the public those public recitations, by any means or
process, including by wire or wireless means or public digital
performances; to make available to the public Works in such a way that
members of the public may access these Works from a place and at a
place individually chosen by them; to perform the Work to the public
by any means or process and the communication to the public of the
performances of the Work, including by public digital performance; to
broadcast and rebroadcast the Work by any means including signs,
sounds or images.
i. "Reproduce" means to make copies of the Work by any means including
without limitation by sound or visual recordings and the right of
fixation and reproducing fixations of the Work, including storage of a
protected performance or phonogram in digital form or other electronic
medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
limit, or restrict any uses free from copyright or rights arising from
limitations or exceptions that are provided for in connection with the
copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License,
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
perpetual (for the duration of the applicable copyright) license to
exercise the rights in the Work as stated below:
a. to Reproduce the Work, to incorporate the Work into one or more
Collections, and to Reproduce the Work as incorporated in the
Collections;
b. to create and Reproduce Adaptations provided that any such Adaptation,
including any translation in any medium, takes reasonable steps to
clearly label, demarcate or otherwise identify that changes were made
to the original Work. For example, a translation could be marked "The
original work was translated from English to Spanish," or a
modification could indicate "The original work has been modified.";
c. to Distribute and Publicly Perform the Work including as incorporated
in Collections; and,
d. to Distribute and Publicly Perform Adaptations.
e. For the avoidance of doubt:
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme cannot be waived, the Licensor
reserves the exclusive right to collect such royalties for any
exercise by You of the rights granted under this License;
ii. Waivable Compulsory License Schemes. In those jurisdictions in
which the right to collect royalties through any statutory or
compulsory licensing scheme can be waived, the Licensor waives the
exclusive right to collect such royalties for any exercise by You
of the rights granted under this License; and,
iii. Voluntary License Schemes. The Licensor waives the right to
collect royalties, whether individually or, in the event that the
Licensor is a member of a collecting society that administers
voluntary licensing schemes, via that society, from any exercise
by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now
known or hereafter devised. The above rights include the right to make
such modifications as are technically necessary to exercise the rights in
other media and formats. Subject to Section 8(f), all rights not expressly
granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made
subject to and limited by the following restrictions:
a. You may Distribute or Publicly Perform the Work only under the terms
of this License. You must include a copy of, or the Uniform Resource
Identifier (URI) for, this License with every copy of the Work You
Distribute or Publicly Perform. You may not offer or impose any terms
on the Work that restrict the terms of this License or the ability of
the recipient of the Work to exercise the rights granted to that
recipient under the terms of the License. You may not sublicense the
Work. You must keep intact all notices that refer to this License and
to the disclaimer of warranties with every copy of the Work You
Distribute or Publicly Perform. When You Distribute or Publicly
Perform the Work, You may not impose any effective technological
measures on the Work that restrict the ability of a recipient of the
Work from You to exercise the rights granted to that recipient under
the terms of the License. This Section 4(a) applies to the Work as
incorporated in a Collection, but this does not require the Collection
apart from the Work itself to be made subject to the terms of this
License. If You create a Collection, upon notice from any Licensor You
must, to the extent practicable, remove from the Collection any credit
as required by Section 4(b), as requested. If You create an
Adaptation, upon notice from any Licensor You must, to the extent
practicable, remove from the Adaptation any credit as required by
Section 4(b), as requested.
b. If You Distribute, or Publicly Perform the Work or any Adaptations or
Collections, You must, unless a request has been made pursuant to
Section 4(a), keep intact all copyright notices for the Work and
provide, reasonable to the medium or means You are utilizing: (i) the
name of the Original Author (or pseudonym, if applicable) if supplied,
and/or if the Original Author and/or Licensor designate another party
or parties (e.g., a sponsor institute, publishing entity, journal) for
attribution ("Attribution Parties") in Licensor's copyright notice,
terms of service or by other reasonable means, the name of such party
or parties; (ii) the title of the Work if supplied; (iii) to the
extent reasonably practicable, the URI, if any, that Licensor
specifies to be associated with the Work, unless such URI does not
refer to the copyright notice or licensing information for the Work;
and (iv) , consistent with Section 3(b), in the case of an Adaptation,
a credit identifying the use of the Work in the Adaptation (e.g.,
"French translation of the Work by Original Author," or "Screenplay
based on original Work by Original Author"). The credit required by
this Section 4 (b) may be implemented in any reasonable manner;
provided, however, that in the case of a Adaptation or Collection, at
a minimum such credit will appear, if a credit for all contributing
authors of the Adaptation or Collection appears, then as part of these
credits and in a manner at least as prominent as the credits for the
other contributing authors. For the avoidance of doubt, You may only
use the credit required by this Section for the purpose of attribution
in the manner set out above and, by exercising Your rights under this
License, You may not implicitly or explicitly assert or imply any
connection with, sponsorship or endorsement by the Original Author,
Licensor and/or Attribution Parties, as appropriate, of You or Your
use of the Work, without the separate, express prior written
permission of the Original Author, Licensor and/or Attribution
Parties.
c. Except as otherwise agreed in writing by the Licensor or as may be
otherwise permitted by applicable law, if You Reproduce, Distribute or
Publicly Perform the Work either by itself or as part of any
Adaptations or Collections, You must not distort, mutilate, modify or
take other derogatory action in relation to the Work which would be
prejudicial to the Original Author's honor or reputation. Licensor
agrees that in those jurisdictions (e.g. Japan), in which any exercise
of the right granted in Section 3(b) of this License (the right to
make Adaptations) would be deemed to be a distortion, mutilation,
modification or other derogatory action prejudicial to the Original
Author's honor and reputation, the Licensor will waive or not assert,
as appropriate, this Section, to the fullest extent permitted by the
applicable national law, to enable You to reasonably exercise Your
right under Section 3(b) of this License (right to make Adaptations)
but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate
automatically upon any breach by You of the terms of this License.
Individuals or entities who have received Adaptations or Collections
from You under this License, however, will not have their licenses
terminated provided such individuals or entities remain in full
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is
perpetual (for the duration of the applicable copyright in the Work).
Notwithstanding the above, Licensor reserves the right to release the
Work under different license terms or to stop distributing the Work at
any time; provided, however that any such election will not serve to
withdraw this License (or any other license that has been, or is
required to be, granted under the terms of this License), and this
License will continue in full force and effect unless terminated as
stated above.
8. Miscellaneous
a. Each time You Distribute or Publicly Perform the Work or a Collection,
the Licensor offers to the recipient a license to the Work on the same
terms and conditions as the license granted to You under this License.
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
offers to the recipient a license to the original Work on the same
terms and conditions as the license granted to You under this License.
c. If any provision of this License is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this License, and without further action
by the parties to this agreement, such provision shall be reformed to
the minimum extent necessary to make such provision valid and
enforceable.
d. No term or provision of this License shall be deemed waived and no
breach consented to unless such waiver or consent shall be in writing
and signed by the party to be charged with such waiver or consent.
e. This License constitutes the entire agreement between the parties with
respect to the Work licensed here. There are no understandings,
agreements or representations with respect to the Work not specified
here. Licensor shall not be bound by any additional provisions that
may appear in any communication from You. This License may not be
modified without the mutual written agreement of the Licensor and You.
f. The rights granted under, and the subject matter referenced, in this
License were drafted utilizing the terminology of the Berne Convention
for the Protection of Literary and Artistic Works (as amended on
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
and the Universal Copyright Convention (as revised on July 24, 1971).
These rights and subject matter take effect in the relevant
jurisdiction in which the License terms are sought to be enforced
according to the corresponding provisions of the implementation of
those treaty provisions in the applicable national law. If the
standard suite of rights granted under applicable copyright law
includes additional rights not granted under this License, such
additional rights are deemed to be included in the License; this
License is not intended to restrict the license of any rights under
applicable law.
Creative Commons Notice
Creative Commons is not a party to this License, and makes no warranty
whatsoever in connection with the Work. Creative Commons will not be
liable to You or any party on any legal theory for any damages
whatsoever, including without limitation any general, special,
incidental or consequential damages arising in connection to this
license. Notwithstanding the foregoing two (2) sentences, if Creative
Commons has expressly identified itself as the Licensor hereunder, it
shall have all rights and obligations of Licensor.
Except for the limited purpose of indicating to the public that the
Work is licensed under the CCPL, Creative Commons does not authorize
the use by either party of the trademark "Creative Commons" or any
related trademark or logo of Creative Commons without the prior
written consent of Creative Commons. Any permitted use will be in
compliance with Creative Commons' then-current trademark usage
guidelines, as may be published on its website or otherwise made
available upon request from time to time. For the avoidance of doubt,
this trademark restriction does not form part of this License.
Creative Commons may be contacted at http://creativecommons.org/.

10
docs/_includes/ads.html Normal file
View File

@@ -0,0 +1,10 @@
<div id="aboutme-container">
<a href="mailto:arnold@jasny.net" class="aboutme">
<img class="img-circle" src="http://0.gravatar.com/avatar/0bba82e8b2a9d2cf9645cb07ea54766f?s=100&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D100&amp;r=G" alt="Arnold Daniels">
<div class="aboutme-text">
<span class="aboutme-title">Looking for a developer?</span>
I'm available for freelance work, I want to hear about your projects.
<span class="aboutme-name">- Arnold Daniels</span>
</div>
</a>
</div>

View File

@@ -0,0 +1,335 @@
<!-- NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-variables.jade template.-->
<h2 id="components">Components</h2>
<p>Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).</p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@padding-base-vertical">@padding-base-vertical</label>
<input id="input-@padding-base-vertical" type="text" value="6px" data-var="@padding-base-vertical" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-base-horizontal">@padding-base-horizontal</label>
<input id="input-@padding-base-horizontal" type="text" value="12px" data-var="@padding-base-horizontal" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-large-vertical">@padding-large-vertical</label>
<input id="input-@padding-large-vertical" type="text" value="10px" data-var="@padding-large-vertical" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-large-horizontal">@padding-large-horizontal</label>
<input id="input-@padding-large-horizontal" type="text" value="16px" data-var="@padding-large-horizontal" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-small-vertical">@padding-small-vertical</label>
<input id="input-@padding-small-vertical" type="text" value="5px" data-var="@padding-small-vertical" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-small-horizontal">@padding-small-horizontal</label>
<input id="input-@padding-small-horizontal" type="text" value="10px" data-var="@padding-small-horizontal" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-xs-vertical">@padding-xs-vertical</label>
<input id="input-@padding-xs-vertical" type="text" value="1px" data-var="@padding-xs-vertical" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@padding-xs-horizontal">@padding-xs-horizontal</label>
<input id="input-@padding-xs-horizontal" type="text" value="5px" data-var="@padding-xs-horizontal" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@line-height-large">@line-height-large</label>
<input id="input-@line-height-large" type="text" value="1.33" data-var="@line-height-large" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@line-height-small">@line-height-small</label>
<input id="input-@line-height-small" type="text" value="1.5" data-var="@line-height-small" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@border-radius-base">@border-radius-base</label>
<input id="input-@border-radius-base" type="text" value="4px" data-var="@border-radius-base" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@border-radius-large">@border-radius-large</label>
<input id="input-@border-radius-large" type="text" value="6px" data-var="@border-radius-large" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@border-radius-small">@border-radius-small</label>
<input id="input-@border-radius-small" type="text" value="3px" data-var="@border-radius-small" class="form-control"/>
</div>
</div>
<h2 id="tables">Tables</h2>
<p>Customizes the <code>.table</code> component with basic values, each used across all table variations.</p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@table-bg-hover">@table-bg-hover</label>
<input id="input-@table-bg-hover" type="text" value="#f5f5f5" data-var="@table-bg-hover" class="form-control"/>
<p class="help-block">Background color used for <code>.table-hover</code>.</p>
</div>
</div>
<h2 id="media-queries-breakpoints">Media queries breakpoints</h2>
<p>Define the breakpoints at which your layout will change, adapting to different screen sizes.</p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@screen-xs">@screen-xs</label>
<input id="input-@screen-xs" type="text" value="480px" data-var="@screen-xs" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@screen-sm">@screen-sm</label>
<input id="input-@screen-sm" type="text" value="768px" data-var="@screen-sm" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@screen-md">@screen-md</label>
<input id="input-@screen-md" type="text" value="992px" data-var="@screen-md" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@screen-lg">@screen-lg</label>
<input id="input-@screen-lg" type="text" value="1200px" data-var="@screen-lg" class="form-control"/>
</div>
</div>
<h2 id="grid-system">Grid system</h2>
<p>Define your custom responsive grid.</p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@grid-gutter-width">@grid-gutter-width</label>
<input id="input-@grid-gutter-width" type="text" value="30px" data-var="@grid-gutter-width" class="form-control"/>
<p class="help-block">Padding between columns. Gets divided in half for the left and right.</p>
</div>
<div class="bs-customizer-input">
<label for="input-@grid-float-breakpoint">@grid-float-breakpoint</label>
<input id="input-@grid-float-breakpoint" type="text" value="768px" data-var="@grid-float-breakpoint" class="form-control"/>
<p class="help-block">Point at which the navbar becomes uncollapsed.</p>
</div>
<div class="bs-customizer-input">
<label for="input-@container-smooth">@container-smooth</label>
<input id="input-@container-smooth" type="text" value="@container-lg" data-var="@container-smooth" class="form-control"/>
<p class="help-block">Maximum with of a smooth container.</p>
</div>
</div>
<h2 id="navbar">Navbar</h2>
<p></p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@navbar-height">@navbar-height</label>
<input id="input-@navbar-height" type="text" value="50px" data-var="@navbar-height" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navbar-padding-horizontal">@navbar-padding-horizontal</label>
<input id="input-@navbar-padding-horizontal" type="text" value="floor((@grid-gutter-width / 2))" data-var="@navbar-padding-horizontal" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navbar-padding-vertical">@navbar-padding-vertical</label>
<input id="input-@navbar-padding-vertical" type="text" value="((@navbar-height - @line-height-computed) / 2)" data-var="@navbar-padding-vertical" class="form-control"/>
</div>
</div>
<h2 id="navmenu">Navmenu</h2>
<p></p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@navmenu-width">@navmenu-width</label>
<input id="input-@navmenu-width" type="text" value="300px" data-var="@navmenu-width" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-margin-vertical">@navmenu-margin-vertical</label>
<input id="input-@navmenu-margin-vertical" type="text" value="(0.5 * @line-height-computed)" data-var="@navmenu-margin-vertical" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-color">@navmenu-default-color</label>
<input id="input-@navmenu-default-color" type="text" value="#777" data-var="@navmenu-default-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-bg">@navmenu-default-bg</label>
<input id="input-@navmenu-default-bg" type="text" value="#f8f8f8" data-var="@navmenu-default-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-border">@navmenu-default-border</label>
<input id="input-@navmenu-default-border" type="text" value="darken(@navmenu-default-bg, 6.5%)" data-var="@navmenu-default-border" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-color">@navmenu-default-link-color</label>
<input id="input-@navmenu-default-link-color" type="text" value="#777" data-var="@navmenu-default-link-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-hover-color">@navmenu-default-link-hover-color</label>
<input id="input-@navmenu-default-link-hover-color" type="text" value="#333" data-var="@navmenu-default-link-hover-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-hover-bg">@navmenu-default-link-hover-bg</label>
<input id="input-@navmenu-default-link-hover-bg" type="text" value="transparent" data-var="@navmenu-default-link-hover-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-active-color">@navmenu-default-link-active-color</label>
<input id="input-@navmenu-default-link-active-color" type="text" value="#555" data-var="@navmenu-default-link-active-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-active-bg">@navmenu-default-link-active-bg</label>
<input id="input-@navmenu-default-link-active-bg" type="text" value="darken(@navmenu-default-bg, 6.5%)" data-var="@navmenu-default-link-active-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-disabled-color">@navmenu-default-link-disabled-color</label>
<input id="input-@navmenu-default-link-disabled-color" type="text" value="#ccc" data-var="@navmenu-default-link-disabled-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-link-disabled-bg">@navmenu-default-link-disabled-bg</label>
<input id="input-@navmenu-default-link-disabled-bg" type="text" value="transparent" data-var="@navmenu-default-link-disabled-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-brand-color">@navmenu-default-brand-color</label>
<input id="input-@navmenu-default-brand-color" type="text" value="@navmenu-default-link-color" data-var="@navmenu-default-brand-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-brand-hover-color">@navmenu-default-brand-hover-color</label>
<input id="input-@navmenu-default-brand-hover-color" type="text" value="darken(@navmenu-default-link-color, 10%)" data-var="@navmenu-default-brand-hover-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-default-brand-hover-bg">@navmenu-default-brand-hover-bg</label>
<input id="input-@navmenu-default-brand-hover-bg" type="text" value="transparent" data-var="@navmenu-default-brand-hover-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-color">@navmenu-inverse-color</label>
<input id="input-@navmenu-inverse-color" type="text" value="@gray-light" data-var="@navmenu-inverse-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-bg">@navmenu-inverse-bg</label>
<input id="input-@navmenu-inverse-bg" type="text" value="#222" data-var="@navmenu-inverse-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-border">@navmenu-inverse-border</label>
<input id="input-@navmenu-inverse-border" type="text" value="darken(@navmenu-inverse-bg, 10%)" data-var="@navmenu-inverse-border" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-color">@navmenu-inverse-link-color</label>
<input id="input-@navmenu-inverse-link-color" type="text" value="@gray-light" data-var="@navmenu-inverse-link-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-hover-color">@navmenu-inverse-link-hover-color</label>
<input id="input-@navmenu-inverse-link-hover-color" type="text" value="#fff" data-var="@navmenu-inverse-link-hover-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-hover-bg">@navmenu-inverse-link-hover-bg</label>
<input id="input-@navmenu-inverse-link-hover-bg" type="text" value="transparent" data-var="@navmenu-inverse-link-hover-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-active-color">@navmenu-inverse-link-active-color</label>
<input id="input-@navmenu-inverse-link-active-color" type="text" value="@navmenu-inverse-link-hover-color" data-var="@navmenu-inverse-link-active-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-active-bg">@navmenu-inverse-link-active-bg</label>
<input id="input-@navmenu-inverse-link-active-bg" type="text" value="darken(@navmenu-inverse-bg, 10%)" data-var="@navmenu-inverse-link-active-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-disabled-color">@navmenu-inverse-link-disabled-color</label>
<input id="input-@navmenu-inverse-link-disabled-color" type="text" value="#444" data-var="@navmenu-inverse-link-disabled-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-link-disabled-bg">@navmenu-inverse-link-disabled-bg</label>
<input id="input-@navmenu-inverse-link-disabled-bg" type="text" value="transparent" data-var="@navmenu-inverse-link-disabled-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-brand-color">@navmenu-inverse-brand-color</label>
<input id="input-@navmenu-inverse-brand-color" type="text" value="@navmenu-inverse-link-color" data-var="@navmenu-inverse-brand-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-brand-hover-color">@navmenu-inverse-brand-hover-color</label>
<input id="input-@navmenu-inverse-brand-hover-color" type="text" value="#fff" data-var="@navmenu-inverse-brand-hover-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-brand-hover-bg">@navmenu-inverse-brand-hover-bg</label>
<input id="input-@navmenu-inverse-brand-hover-bg" type="text" value="transparent" data-var="@navmenu-inverse-brand-hover-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-search-bg">@navmenu-inverse-search-bg</label>
<input id="input-@navmenu-inverse-search-bg" type="text" value="lighten(@navmenu-inverse-bg, 25%)" data-var="@navmenu-inverse-search-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-search-bg-focus">@navmenu-inverse-search-bg-focus</label>
<input id="input-@navmenu-inverse-search-bg-focus" type="text" value="#fff" data-var="@navmenu-inverse-search-bg-focus" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-search-border">@navmenu-inverse-search-border</label>
<input id="input-@navmenu-inverse-search-border" type="text" value="@navmenu-inverse-bg" data-var="@navmenu-inverse-search-border" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@navmenu-inverse-search-placeholder-color">@navmenu-inverse-search-placeholder-color</label>
<input id="input-@navmenu-inverse-search-placeholder-color" type="text" value="#ccc" data-var="@navmenu-inverse-search-placeholder-color" class="form-control"/>
</div>
</div>
<h2 id="navs">Navs</h2>
<p></p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@nav-link-padding">@nav-link-padding</label>
<input id="input-@nav-link-padding" type="text" value="10px 15px" data-var="@nav-link-padding" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@nav-tabs-active-link-hover-border-color">@nav-tabs-active-link-hover-border-color</label>
<input id="input-@nav-tabs-active-link-hover-border-color" type="text" value="#ddd" data-var="@nav-tabs-active-link-hover-border-color" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@nav-tabs-border-color">@nav-tabs-border-color</label>
<input id="input-@nav-tabs-border-color" type="text" value="#ddd" data-var="@nav-tabs-border-color" class="form-control"/>
</div>
</div>
<h2 id="form-states-and-alerts">Form states and alerts</h2>
<p>Define colors for form feedback states and, by default, alerts.</p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@state-success-text">@state-success-text</label>
<input id="input-@state-success-text" type="text" value="#3c763d" data-var="@state-success-text" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-success-bg">@state-success-bg</label>
<input id="input-@state-success-bg" type="text" value="#dff0d8" data-var="@state-success-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-success-border">@state-success-border</label>
<input id="input-@state-success-border" type="text" value="darken(spin(@state-success-bg, -10), 5%)" data-var="@state-success-border" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-info-text">@state-info-text</label>
<input id="input-@state-info-text" type="text" value="#31708f" data-var="@state-info-text" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-info-bg">@state-info-bg</label>
<input id="input-@state-info-bg" type="text" value="#d9edf7" data-var="@state-info-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-info-border">@state-info-border</label>
<input id="input-@state-info-border" type="text" value="darken(spin(@state-info-bg, -10), 7%)" data-var="@state-info-border" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-warning-text">@state-warning-text</label>
<input id="input-@state-warning-text" type="text" value="#8a6d3b" data-var="@state-warning-text" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-warning-bg">@state-warning-bg</label>
<input id="input-@state-warning-bg" type="text" value="#fcf8e3" data-var="@state-warning-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-warning-border">@state-warning-border</label>
<input id="input-@state-warning-border" type="text" value="darken(spin(@state-warning-bg, -10), 5%)" data-var="@state-warning-border" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-danger-text">@state-danger-text</label>
<input id="input-@state-danger-text" type="text" value="#a94442" data-var="@state-danger-text" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-danger-bg">@state-danger-bg</label>
<input id="input-@state-danger-bg" type="text" value="#f2dede" data-var="@state-danger-bg" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@state-danger-border">@state-danger-border</label>
<input id="input-@state-danger-border" type="text" value="darken(spin(@state-danger-bg, -10), 5%)" data-var="@state-danger-border" class="form-control"/>
</div>
</div>
<h2 id="alerts">Alerts</h2>
<p>Define alert colors, border radius, and padding.</p>
<div class="row">
<div class="bs-customizer-input">
<label for="input-@alert-border-radius">@alert-border-radius</label>
<input id="input-@alert-border-radius" type="text" value="@border-radius-base" data-var="@alert-border-radius" class="form-control"/>
</div>
<div class="bs-customizer-input">
<label for="input-@alert-fixed-width">@alert-fixed-width</label>
<input id="input-@alert-fixed-width" type="text" value="@screen-md" data-var="@alert-fixed-width" class="form-control"/>
</div>
</div>
<!-- NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-variables.jade template.-->

View File

@@ -0,0 +1,14 @@
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="{{ page.base_url }}dist/js/jasny-bootstrap.min.js"></script>
<script src="http://platform.twitter.com/widgets.js"></script>
<script src="{{ page.base_url }}assets/js/docs.min.js"></script>
{% if page.slug == "customize" %}
<script src="../assets/js/customize.min.js"></script>
{% endif %}

View File

@@ -0,0 +1,43 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<title>
{% if page.title == "Jasny Bootstrap" %}
{{ page.title }}
{% else %}
{{ page.title }} &middot; Jasny Bootstrap
{% endif %}
</title>
<!-- Bootstrap core CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="{{ page.base_url }}dist/css/jasny-bootstrap.min.css" rel="stylesheet">
<!-- Documentation extras -->
<link href="{{ page.base_url }}assets/css/docs.css" rel="stylesheet">
<link href="{{ page.base_url }}assets/css/pygments-manni.css" rel="stylesheet">
<!--[if lt IE 9]><script src="{{ page.base_url }}assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<!-- Favicons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{{ page.base_url }}assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="shortcut icon" href="{{ page.base_url }}assets/ico/favicon.png">
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-32388850-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>

View File

@@ -0,0 +1,15 @@
<li>
<a href="#navmenu">Navmenu</a>
<ul class="nav">
<li><a href="#navmenu-default">Default navmenu</a></li>
<li><a href="#navmenu-fixed">Fixed to left or right</a></li>
<li><a href="#navmenu-offcanvas">Off canvas</a></li>
<li><a href="#navmenu-inverted">Inverted navmenu</a></li>
</ul>
</li>
<li>
<a href="#alerts">Alerts</a>
<ul class="nav">
<li><a href="#alerts-fixed">Fixed to top / bottom</a></li>
</ul>
</li>

View File

@@ -0,0 +1,12 @@
<li>
<a href="#overview">Overview</a>
<ul class="nav">
<li><a href="#overview-container">Containers</a></li>
</ul>
</li>
<li>
<a href="#buttons">Buttons</a>
<ul class="nav">
<li><a href="#buttons-labels">Labels</a></li>
</ul>
</li>

View File

@@ -0,0 +1,19 @@
<!-- NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template.-->
<li><a href="#less">Less components</a></li>
<li><a href="#plugins">jQuery plugins</a></li>
<li><a href="#less-variables">Less variables</a>
<ul class="nav">
<li><a href="#components">Components</a></li>
<li><a href="#tables">Tables</a></li>
<li><a href="#media-queries-breakpoints">Media queries breakpoints</a></li>
<li><a href="#grid-system">Grid system</a></li>
<li><a href="#navbar">Navbar</a></li>
<li><a href="#navmenu">Navmenu</a></li>
<li><a href="#navs">Navs</a></li>
<li><a href="#form-states-and-alerts">Form states and alerts</a></li>
<li><a href="#alerts">Alerts</a></li>
</ul>
</li>
<li><a href="#download">Download</a></li>
<!-- NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template.-->

View File

@@ -0,0 +1,26 @@
<li>
<a href="#jasny-bootstrap">Jasny Bootstrap</a>
</li>
<li>
<a href="#download">Download Jasny Bootstrap</a>
<ul class="nav">
<li><a href="#download-compiled">Compiled CSS, JS, and fonts</a></li>
<li><a href="#download-additional">Additional downloads</a></li>
<li><a href="#download-cdn">Bootstrap CDN</a></li>
</ul>
</li>
<li>
<a href="#whats-included">What's included</a>
</li>
<li>
<a href="#examples">Examples</a>
</li>
<li>
<a href="#migration">Migrating from 2.x to 3.0</a>
<ul class="nav">
<li><a href="#migration-classes">Major class changes</a></li>
<li><a href="#migration-new">What's new</a></li>
<li><a href="#migration-dropped">What's removed</a></li>
<li><a href="#migration-notes">Additional notes</a></li>
</ul>
</li>

View File

@@ -0,0 +1,38 @@
<li>
<a href="#js-overview">Overview</a>
<ul class="nav">
<li><a href="#js-individual-compiled">Individual or compiled</a></li>
<li><a href="#js-data-attrs">Data attributes</a></li>
<li><a href="#js-programmatic-api">Programmatic API</a></li>
<li><a href="#js-noconflict">No conflict</a></li>
<li><a href="#js-events">Events</a></li>
</ul>
</li>
<li>
<a href="#offcanvas">Off canvas</a>
<ul class="nav">
<li><a href="#offcanvas-examples">Examples</a></li>
<li><a href="#offcanvas-usage">Usage</a></li>
</ul>
</li>
<li>
<a href="#rowlink">Row link</a>
<ul class="nav">
<li><a href="#rowlink-examples">Examples</a></li>
<li><a href="#rowlink-usage">Usage</a></li>
</ul>
</li>
<li>
<a href="#inputmask">Input mask</a>
<ul class="nav">
<li><a href="#inputmask-examples">Examples</a></li>
<li><a href="#inputmask-usage">Usage</a></li>
</ul>
</li>
<li>
<a href="#fileinput">File input</a>
<ul class="nav">
<li><a href="#fileinput-examples">Examples</a></li>
<li><a href="#fileinput-usage">Usage</a></li>
</ul>
</li>

View File

@@ -0,0 +1,37 @@
<header class="navbar navbar-inverse navbar-fixed-top bs-docs-nav" role="banner">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="{{ page.base_url }}" class="navbar-brand">Jasny Bootstrap</a>
</div>
<nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
<ul class="nav navbar-nav">
<li{% if page.slug == "getting-started" %} class="active"{% endif %}>
<a href="{{ page.base_url }}getting-started">Getting started</a>
</li>
<li{% if page.slug == "css" %} class="active"{% endif %}>
<a href="{{ page.base_url }}css">CSS</a>
</li>
<li{% if page.slug == "components" %} class="active"{% endif %}>
<a href="{{ page.base_url }}components">Components</a>
</li>
<li{% if page.slug == "js" %} class="active"{% endif %}>
<a href="{{ page.base_url }}javascript">JavaScript</a>
</li>
<li{% if page.slug == "customize" %} class="active"{% endif %}>
<a href="{{ page.base_url }}customize">Customize</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="http://www.jasny.net"><span class="hidden-sm">More by</span> Jasny</a>
</li>
</ul>
</nav>
</div>
</header>

View File

@@ -0,0 +1,16 @@
<div class="bs-social">
<ul class="bs-social-buttons">
<li>
<iframe class="github-btn" src="http://ghbtns.com/github-btn.html?user=jasny&amp;repo=bootstrap&amp;type=watch&amp;count=true" width="100" height="20" title="Star on GitHub"></iframe>
</li>
<li>
<iframe class="github-btn" src="http://ghbtns.com/github-btn.html?user=jasny&amp;repo=bootstrap&amp;type=fork&amp;count=true" width="102" height="20" title="Fork on GitHub"></iframe>
</li>
<li class="follow-btn">
<a href="https://twitter.com/ArnoldDaniels" class="twitter-follow-button" data-link-color="#0069D6" data-show-count="true">Follow @ArnoldDaniels</a>
</li>
<li class="tweet-btn">
<a href="https://twitter.com/share" class="twitter-share-button" data-url="http://jasny.github.io/bootstrap" data-count="horizontal" data-via="ArnoldDaniels">Tweet</a>
</li>
</ul>
</div>

View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta, title, CSS, favicons, etc. -->
{% include header.html %}
</head>
<body class="{% if page.slug == "customize" %}bs-twbs-show{% endif %}">
<script type="text/javascript">
if (localStorage && localStorage.hide_twbs === 'no') document.body.setAttribute('class', 'bs-twbs-show')
</script>
<a class="sr-only" href="#content">Skip to main content</a>
<!-- Docs master nav -->
{% include nav-main.html %}
<!-- Docs page layout -->
<div class="bs-header" id="content">
<div class="container">
<h1>{{ page.title }}</h1>
<p>{{ page.lead }}</p>
{% include ads.html %}
</div>
</div>
<div class="container bs-docs-container">
<div class="row">
<div class="col-md-3">
<div class="bs-sidebar hidden-print" role="complementary">
<ul class="nav bs-sidenav">
{% if page.slug == "getting-started" %}
{% include nav-getting-started.html %}
{% elsif page.slug == "css" %}
{% include nav-css.html %}
{% elsif page.slug == "components" %}
{% include nav-components.html %}
{% elsif page.slug == "js" %}
{% include nav-javascript.html %}
{% elsif page.slug == "customize" %}
{% include nav-customize.html %}
{% elsif page.slug == "about" %}
{% include nav-about.html %}
{% endif %}
</ul>
</div>
</div>
<div class="col-md-9" role="main">
{{ content }}
</div>
</div>
</div>
<!-- Footer
================================================== -->
<footer class="bs-footer" role="contentinfo">
<div class="container">
{% include social-buttons.html %}
<p>Jasny Bootstrap is a fork of <a href="http://getbootstrap.com/" target="_blank">Twitter Bootstrap</a>. This fork is developed and maintained by <a href="http://twitter.com/ArnoldDaniels" target="_blank">Arnold Daniels</a>.</p>
<p>Code licensed under <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License v2.0</a>, documentation under <a href="http://creativecommons.org/licenses/by/3.0/">CC BY 3.0</a>.</p>
<ul class="footer-links">
<li>Currently v{{ site.current_version }}</li>
<li class="muted">&middot;</li>
<li><a href="{{ page.base_url }}2.3.1/">Bootstrap 2.3.1 docs</a></li>
<li class="muted">&middot;</li>
<li><a href="http://www.jasny.net">Jasny.net</a></li>
<li class="muted">&middot;</li>
<li><a href="{{ site.repo }}/issues?state=open">Issues</a></li>
<li class="muted">&middot;</li>
<li><a href="{{ site.repo }}/releases">Releases</a></li>
</ul>
</div>
</footer>
<!-- JS and analytics only. -->
{% include footer.html %}
</body>
</html>

41
docs/_layouts/home.html Normal file
View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta, title, CSS, favicons, etc. -->
{% include header.html %}
</head>
<body class="bs-docs-home">
<a class="sr-only" href="#content">Skip to main content</a>
<!-- Docs master nav -->
{% include nav-main.html %}
<!-- Page content of course! -->
{{ content }}
<footer class="container" role="contentinfo">
{% include ads.html %}
{% include social-buttons.html %}
<ul class="bs-masthead-links">
<li class="current-version">
Currently v{{ site.current_version }}
</li>
<li>
<a href="{{ page.base_url }}2.3.1/">Bootstrap 2.3.1 docs</a>
</li>
<li>
<a href="{{ site.repo }}" onclick="_gaq.push(['_trackEvent', 'Jumbotron actions', 'Jumbotron links', 'GitHub project']);">GitHub project</a>
</li>
<li>
<a href="{{ page.base_url }}getting-started/#examples" onclick="_gaq.push(['_trackEvent', 'Jumbotron actions', 'Jumbotron links', 'Examples']);">Examples</a>
</li>
</ul>
</footer>
<!-- JS and analytics only. -->
{% include footer.html %}
</body>
</html>

1249
docs/assets/css/docs.css Normal file

File diff suppressed because it is too large Load Diff

6
docs/assets/css/docs.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,66 @@
.hll { background-color: #ffffcc }
/*{ background: #f0f3f3; }*/
.c { color: #999; } /* Comment */
.err { color: #AA0000; background-color: #FFAAAA } /* Error */
.k { color: #006699; } /* Keyword */
.o { color: #555555 } /* Operator */
.cm { color: #0099FF; font-style: italic } /* Comment.Multiline */
.cp { color: #009999 } /* Comment.Preproc */
.c1 { color: #999; } /* Comment.Single */
.cs { color: #999; } /* Comment.Special */
.gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #003300; } /* Generic.Heading */
.gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */
.go { color: #AAAAAA } /* Generic.Output */
.gp { color: #000099; } /* Generic.Prompt */
.gs { } /* Generic.Strong */
.gu { color: #003300; } /* Generic.Subheading */
.gt { color: #99CC66 } /* Generic.Traceback */
.kc { color: #006699; } /* Keyword.Constant */
.kd { color: #006699; } /* Keyword.Declaration */
.kn { color: #006699; } /* Keyword.Namespace */
.kp { color: #006699 } /* Keyword.Pseudo */
.kr { color: #006699; } /* Keyword.Reserved */
.kt { color: #007788; } /* Keyword.Type */
.m { color: #FF6600 } /* Literal.Number */
.s { color: #d44950 } /* Literal.String */
.na { color: #4f9fcf } /* Name.Attribute */
.nb { color: #336666 } /* Name.Builtin */
.nc { color: #00AA88; } /* Name.Class */
.no { color: #336600 } /* Name.Constant */
.nd { color: #9999FF } /* Name.Decorator */
.ni { color: #999999; } /* Name.Entity */
.ne { color: #CC0000; } /* Name.Exception */
.nf { color: #CC00FF } /* Name.Function */
.nl { color: #9999FF } /* Name.Label */
.nn { color: #00CCFF; } /* Name.Namespace */
.nt { color: #2f6f9f; } /* Name.Tag */
.nv { color: #003333 } /* Name.Variable */
.ow { color: #000000; } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #FF6600 } /* Literal.Number.Float */
.mh { color: #FF6600 } /* Literal.Number.Hex */
.mi { color: #FF6600 } /* Literal.Number.Integer */
.mo { color: #FF6600 } /* Literal.Number.Oct */
.sb { color: #CC3300 } /* Literal.String.Backtick */
.sc { color: #CC3300 } /* Literal.String.Char */
.sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */
.s2 { color: #CC3300 } /* Literal.String.Double */
.se { color: #CC3300; } /* Literal.String.Escape */
.sh { color: #CC3300 } /* Literal.String.Heredoc */
.si { color: #AA0000 } /* Literal.String.Interpol */
.sx { color: #CC3300 } /* Literal.String.Other */
.sr { color: #33AAAA } /* Literal.String.Regex */
.s1 { color: #CC3300 } /* Literal.String.Single */
.ss { color: #FFCC33 } /* Literal.String.Symbol */
.bp { color: #336666 } /* Name.Builtin.Pseudo */
.vc { color: #003333 } /* Name.Variable.Class */
.vg { color: #003333 } /* Name.Variable.Global */
.vi { color: #003333 } /* Name.Variable.Instance */
.il { color: #FF6600 } /* Literal.Number.Integer.Long */
.css .o,
.css .o + .nt,
.css .nt + .nt { color: #999; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
docs/assets/ico/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

View File

@@ -0,0 +1,76 @@
// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
// IT'S ALL JUST JUNK FOR OUR DOCS!
// ++++++++++++++++++++++++++++++++++++++++++
/*!
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/.
*/
!function ($) {
$(function() {
// IE10 viewport hack for Surface/desktop Windows 8 bug
//
// See Getting Started docs for more information
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement("style");
msViewportStyle.appendChild(
document.createTextNode(
"@-ms-viewport{width:auto!important}"
)
);
document.getElementsByTagName("head")[0].
appendChild(msViewportStyle);
}
var $window = $(window)
var $body = $(document.body)
var navHeight = $('.navbar').outerHeight(true) + 10
// scrollspy
$body.scrollspy({
target: '.bs-sidebar',
offset: navHeight
})
$window.on('load', function () {
$body.scrollspy('refresh')
})
$('.bs-docs-container [href=#]').click(function (e) {
e.preventDefault()
})
// back to top
setTimeout(function () {
var $sideBar = $('.bs-sidebar')
$sideBar.affix({
offset: {
top: function () {
var offsetTop = $sideBar.offset().top
var sideBarMargin = parseInt($sideBar.children(0).css('margin-top'), 10)
var navOuterHeight = $('.bs-docs-nav').height()
return (this.top = offsetTop - navOuterHeight - sideBarMargin)
},
bottom: function () {
return (this.bottom = $('.bs-footer').outerHeight(true))
}
}
})
}, 100)
setTimeout(function () {
$('.bs-top').affix()
}, 100)
})
}(jQuery)

55
docs/assets/js/customize.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,336 @@
/*!
* Bootstrap Customizer (http://getbootstrap.com/customize/)
* Copyright 2011-2014 Twitter, Inc.
*
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/.
*/
window.onload = function () { // wait for load in a dumb way because B-0
var cw = '/*!\n' +
' * Jasny Bootstrap v3.1.0 (http://jasny.github.com/bootstrap)\n' +
' * Copyright 2011-2014 Arnold Daniels.\n' +
' * Licensed under Apache-2.0 (https://github.com/jasny/bootstrap/blob/master/LICENSE)\n' +
' */\n\n'
function showError(msg, err) {
$('<div id="bsCustomizerAlert" class="bs-customizer-alert">' +
'<div class="container">' +
'<a href="#bsCustomizerAlert" data-dismiss="alert" class="close pull-right">&times;</a>' +
'<p class="bs-customizer-alert-text"><span class="glyphicon glyphicon-warning-sign"></span>' + msg + '</p>' +
(err.extract ? '<pre class="bs-customizer-alert-extract">' + err.extract.join('\n') + '</pre>' : '') +
'</div>' +
'</div>').appendTo('body').alert()
throw err
}
function showCallout(msg, showUpTop) {
var callout = $('<div class="bs-callout bs-callout-danger">' +
'<h4>Attention!</h4>' +
'<p>' + msg + '</p>' +
'</div>')
if (showUpTop) {
callout.appendTo('.bs-docs-container')
} else {
callout.insertAfter('.bs-customize-download')
}
}
function getQueryParam(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, '\\$&') // escape RegEx meta chars
var match = location.search.match(new RegExp('[?&]' + key + '=([^&]+)(&|$)'))
return match && decodeURIComponent(match[1].replace(/\+/g, ' '))
}
function createGist(configJson) {
var data = {
'description': 'Bootstrap Customizer Config',
'public': true,
'files': {
'config.json': {
'content': configJson
}
}
}
$.ajax({
url: 'https://api.github.com/gists',
type: 'POST',
dataType: 'json',
data: JSON.stringify(data)
})
.success(function (result) {
var origin = window.location.protocol + '//' + window.location.host
history.replaceState(false, document.title, origin + window.location.pathname + '?id=' + result.id)
})
.error(function (err) {
showError('<strong>Ruh roh!</strong> Could not save gist file, configuration not saved.', err)
})
}
function getCustomizerData() {
var vars = {}
$('#less-variables-section input')
.each(function () {
$(this).val() && (vars[$(this).prev().text()] = $(this).val())
})
var data = {
vars: vars,
css: $('#less-section input:checked') .map(function () { return this.value }).toArray(),
js: $('#plugin-section input:checked').map(function () { return this.value }).toArray()
}
if ($.isEmptyObject(data.vars) && !data.css.length && !data.js.length) return
return data
}
function parseUrl() {
var id = getQueryParam('id')
if (!id) return
$.ajax({
url: 'https://api.github.com/gists/' + id,
type: 'GET',
dataType: 'json'
})
.success(function (result) {
var data = JSON.parse(result.files['config.json'].content)
if (data.js) {
$('#plugin-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.js))
})
}
if (data.css) {
$('#less-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.css))
})
}
if (data.vars) {
for (var i in data.vars) {
$('input[data-var="' + i + '"]').val(data.vars[i])
}
}
})
.error(function (err) {
showError('Error fetching bootstrap config file', err)
})
}
function generateZip(css, js, fonts, config, complete) {
if (!css && !js) return showError('<strong>Ruh roh!</strong> No Bootstrap files selected.', new Error('no Bootstrap'))
var zip = new JSZip()
if (css) {
var cssFolder = zip.folder('css')
for (var fileName in css) {
cssFolder.file(fileName, css[fileName])
}
}
if (js) {
var jsFolder = zip.folder('js')
for (var jsFileName in js) {
jsFolder.file(jsFileName, js[jsFileName])
}
}
if (fonts) {
var fontsFolder = zip.folder('fonts')
for (var fontsFileName in fonts) {
fontsFolder.file(fontsFileName, fonts[fontsFileName], {base64: true})
}
}
if (config) {
zip.file('config.json', config)
}
var content = zip.generate({ type: 'blob' })
complete(content)
}
function generateCustomCSS(vars) {
var result = ''
for (var key in vars) {
result += key + ': ' + vars[key] + ';\n'
}
return result + '\n\n'
}
function generateFonts() {
return false;
}
// Returns an Array of @import'd filenames in the order
// in which they appear in the file.
function includedLessFilenames(lessFilename) {
var IMPORT_REGEX = /^@import \"(.*?)\";$/
var lessLines = __less[lessFilename].split('\n')
for (var i = 0, imports = []; i < lessLines.length; i++) {
var match = IMPORT_REGEX.exec(lessLines[i])
if (match) imports.push(match[1])
}
return imports
}
function generateLESS(lessFilename, lessFileIncludes, vars) {
var lessSource = __less[lessFilename]
$.each(includedLessFilenames(lessFilename), function(index, filename) {
var fileInclude = lessFileIncludes[filename]
// Files not explicitly unchecked are compiled into the final stylesheet.
// Core stylesheets like 'normalize.less' are not included in the form
// since disabling them would wreck everything, and so their 'fileInclude'
// will be 'undefined'.
if (fileInclude || (fileInclude == null)) lessSource += __less[filename]
// Custom variables are added after Bootstrap variables so the custom
// ones take precedence.
if (('build/default-variables.less' === filename) && vars) lessSource += generateCustomCSS(vars)
})
lessSource = lessSource.replace(/@import[^\n]*/gi, '') //strip any imports
return lessSource
}
function compileLESS(lessSource, baseFilename, intoResult) {
var parser = new less.Parser({
paths: ['build/default-variables.less', 'mixins.less'],
optimization: 0,
filename: baseFilename + '.css'
}).parse(lessSource, function (err, tree) {
if (err) {
return showError('<strong>Ruh roh!</strong> Could not parse less files.', err)
}
intoResult[baseFilename + '.css'] = cw + tree.toCSS()
intoResult[baseFilename + '.min.css'] = cw + tree.toCSS({ compress: true })
})
}
function generateCSS() {
var oneChecked = false
var lessFileIncludes = {}
$('#less-section input').each(function() {
var $this = $(this)
var checked = $this.is(':checked')
lessFileIncludes[$this.val()] = checked
oneChecked = oneChecked || checked
})
if (!oneChecked) return false
var result = {}
var vars = {}
$('#less-variables-section input')
.each(function () {
$(this).val() && (vars[$(this).prev().text()] = $(this).val())
})
var bsLessSource = generateLESS('jasny-bootstrap.less', lessFileIncludes, vars)
try {
compileLESS(bsLessSource, 'jasny-bootstrap', result)
} catch (err) {
return showError('<strong>Ruh roh!</strong> Could not parse less files.', err)
}
return result
}
function generateJavascript() {
var $checked = $('#plugin-section input:checked')
if (!$checked.length) return false
var js = $checked
.map(function () { return __js[this.value] })
.toArray()
.join('\n')
return {
'jasny-bootstrap.js': js,
'jasny-bootstrap.min.js': cw + uglify(js)
}
}
var inputsComponent = $('#less-section input')
var inputsPlugin = $('#plugin-section input')
var inputsVariables = $('#less-variables-section input')
$('#less-section .toggle').on('click', function (e) {
e.preventDefault()
inputsComponent.prop('checked', !inputsComponent.is(':checked'))
})
$('#plugin-section .toggle').on('click', function (e) {
e.preventDefault()
inputsPlugin.prop('checked', !inputsPlugin.is(':checked'))
})
$('[data-dependencies]').on('click', function () {
if (!$(this).is(':checked')) return
var dependencies = this.getAttribute('data-dependencies')
if (!dependencies) return
dependencies = dependencies.split(',')
for (var i = 0; i < dependencies.length; i++) {
var dependency = $('[value="' + dependencies[i] + '"]')
dependency && dependency.prop('checked', true)
}
})
$('[data-dependents]').on('click', function () {
if ($(this).is(':checked')) return
var dependents = this.getAttribute('data-dependents')
if (!dependents) return
dependents = dependents.split(',')
for (var i = 0; i < dependents.length; i++) {
var dependent = $('[value="' + dependents[i] + '"]')
dependent && dependent.prop('checked', false)
}
})
var $compileBtn = $('#btn-compile')
var $downloadBtn = $('#btn-download')
$compileBtn.on('click', function (e) {
var configData = getCustomizerData()
var configJson = JSON.stringify(configData, null, 2)
e.preventDefault()
$compileBtn.attr('disabled', 'disabled')
generateZip(generateCSS(), generateJavascript(), generateFonts(), configJson, function (blob) {
$compileBtn.removeAttr('disabled')
saveAs(blob, 'jasny-bootstrap.zip')
createGist(configJson)
})
})
// browser support alerts
if (!window.URL && navigator.userAgent.toLowerCase().indexOf('safari') != -1) {
showCallout('Looks like you\'re using safari, which sadly doesn\'t have the best support' +
'for HTML5 blobs. Because of this your file will be downloaded with the name <code>"untitled"</code>.' +
'However, if you check your downloads folder, just rename this <code>"untitled"</code> file' +
'to <code>"jasny-bootstrap.zip"</code> and you should be good to go!')
} else if (!window.URL && !window.webkitURL) {
$('.bs-docs-section, .bs-docs-sidebar').css('display', 'none')
showCallout('Looks like your current browser doesn\'t support the Bootstrap Customizer. Please take a second' +
'to <a href="https://www.google.com/intl/en/chrome/browser/">upgrade to a more modern browser</a>.', true)
}
parseUrl()
}

16
docs/assets/js/docs.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
// IT'S JUST JUNK FOR OUR DOCS!
// ++++++++++++++++++++++++++++++++++++++++++
/*!
* Copyright 2011-2014 Twitter, Inc.
*
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/.
*/
// Intended to prevent false-positive bug reports about responsive styling supposedly not working in IE8.
if (window.location.protocol == 'file:')
alert("ERROR: Bootstrap's responsive CSS is disabled!\nSee getbootstrap.com/getting-started/#respond-file-proto for details.")

7
docs/assets/js/raw-files.min.js vendored Normal file

File diff suppressed because one or more lines are too long

166
docs/assets/js/vendor/blob.js vendored Normal file
View File

@@ -0,0 +1,166 @@
/* Blob.js
* A Blob implementation.
* 2013-12-27
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/eboyjr
* License: X11/MIT
* See LICENSE.md
*/
/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
if (!(typeof Blob === "function" || typeof Blob === "object") || typeof URL === "undefined")
if ((typeof Blob === "function" || typeof Blob === "object") && typeof webkitURL !== "undefined") self.URL = webkitURL;
else var Blob = (function (view) {
"use strict";
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
var
get_class = function(object) {
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
}
, FakeBlobBuilder = function BlobBuilder() {
this.data = [];
}
, FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
}
, FBB_proto = FakeBlobBuilder.prototype
, FB_proto = FakeBlob.prototype
, FileReaderSync = view.FileReaderSync
, FileException = function(type) {
this.code = this[this.name = type];
}
, file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" ")
, file_ex_code = file_ex_codes.length
, real_URL = view.URL || view.webkitURL || view
, real_create_object_URL = real_URL.createObjectURL
, real_revoke_object_URL = real_URL.revokeObjectURL
, URL = real_URL
, btoa = view.btoa
, atob = view.atob
, ArrayBuffer = view.ArrayBuffer
, Uint8Array = view.Uint8Array
;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function(blob) {
var
type = blob.type
, data_URI_header
;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
} if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data/*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
var
str = ""
, buf = new Uint8Array(data)
, i = 0
, buf_len = buf.length
;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync;
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length)
, type
, this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
return FakeBlobBuilder;
}(view));
return function Blob(blobParts, options) {
var type = options ? (options.type || "") : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));

242
docs/assets/js/vendor/filesaver.js vendored Normal file
View File

@@ -0,0 +1,242 @@
/* FileSaver.js
* A saveAs() FileSaver implementation.
* 2014-01-24
*
* By Eli Grey, http://eligrey.com
* License: X11/MIT
* See LICENSE.md
*/
/*global self */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
plusplus: true */
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
var saveAs = saveAs
// IE 10+ (native saveAs)
|| (navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
// Everyone else
|| (function(view) {
"use strict";
// IE <10 is explicitly unsupported
if (/MSIE [1-9]\./.test(navigator.userAgent)) {
return;
}
var
doc = view.document
// only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, URL = view.URL || view.webkitURL || view
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = !view.externalHost && "download" in save_link
, click = function(node) {
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
node.dispatchEvent(event);
}
, webkit_req_fs = view.webkitRequestFileSystem
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
, throw_outside = function (ex) {
(view.setImmediate || view.setTimeout)(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
, fs_min_size = 0
, deletion_queue = []
, process_deletion_queue = function() {
var i = deletion_queue.length;
while (i--) {
var file = deletion_queue[i];
if (typeof file === "string") { // file is an object URL
URL.revokeObjectURL(file);
} else { // file is a File
file.remove();
}
}
deletion_queue.length = 0; // clear queue
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
}
, FileSaver = function(blob, name) {
// First try a.download, then web filesystem, then object URLs
var
filesaver = this
, type = blob.type
, blob_changed = false
, object_url
, target_view
, get_object_url = function() {
var object_url = get_URL().createObjectURL(blob);
deletion_queue.push(object_url);
return object_url;
}
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
, fs_error = function() {
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_object_url(blob);
}
if (target_view) {
target_view.location.href = object_url;
} else {
window.open(object_url, "_blank");
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
}
, abortable = function(func) {
return function() {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
}
, create_if_not_found = {create: true, exclusive: false}
, slice
;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_object_url(blob);
// FF for Android has a nasty garbage collection mechanism
// that turns all objects that are not pure javascript into 'deadObject'
// this means `doc` and `save_link` are unusable and need to be recreated
// `view` is usable though:
doc = view.document;
save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
save_link.href = object_url;
save_link.download = name;
var event = doc.createEvent("MouseEvents");
event.initMouseEvent(
"click", true, false, view, 0, 0, 0, 0, 0
, false, false, false, false, 0, null
);
save_link.dispatchEvent(event);
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
}
if (!req_fs) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
var save = function() {
dir.getFile(name, create_if_not_found, abortable(function(file) {
file.createWriter(abortable(function(writer) {
writer.onwriteend = function(event) {
target_view.location.href = file.toURL();
deletion_queue.push(file);
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
};
writer.onerror = function() {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
}
};
"writestart progress write abort".split(" ").forEach(function(event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
filesaver.abort = function() {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {create: false}, abortable(function(file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function(ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
}
, FS_proto = FileSaver.prototype
, saveAs = function(blob, name) {
return new FileSaver(blob, name);
}
;
FS_proto.abort = function() {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2;
FS_proto.error =
FS_proto.onwritestart =
FS_proto.onprogress =
FS_proto.onwrite =
FS_proto.onabort =
FS_proto.onerror =
FS_proto.onwriteend =
null;
view.addEventListener("unload", process_deletion_queue, false);
return saveAs;
}(
typeof self !== "undefined" && self
|| typeof window !== "undefined" && window
|| this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window
if (typeof module !== "undefined") module.exports = saveAs;

648
docs/assets/js/vendor/holder.js vendored Normal file
View File

@@ -0,0 +1,648 @@
/*!
Holder - 2.3.1 - client side image placeholders
(c) 2012-2014 Ivan Malopinsky / http://imsky.co
Provided under the MIT License.
Commercial use requires attribution.
*/
var Holder = Holder || {};
(function (app, win) {
var system_config = {
use_svg: false,
use_canvas: false,
use_fallback: false
};
var instance_config = {};
var preempted = false;
canvas = document.createElement('canvas');
var dpr = 1, bsr = 1;
var resizable_images = [];
if (!canvas.getContext) {
system_config.use_fallback = true;
} else {
if (canvas.toDataURL("image/png")
.indexOf("data:image/png") < 0) {
//Android doesn't support data URI
system_config.use_fallback = true;
} else {
var ctx = canvas.getContext("2d");
}
}
if(!!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect){
system_config.use_svg = true;
system_config.use_canvas = false;
}
if(!system_config.use_fallback){
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
}
var ratio = dpr / bsr;
var settings = {
domain: "holder.js",
images: "img",
bgnodes: ".holderjs",
themes: {
"gray": {
background: "#eee",
foreground: "#aaa",
size: 12
},
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
},
"sky": {
background: "#0D8FDB",
foreground: "#fff",
size: 12
},
"vine": {
background: "#39DBAC",
foreground: "#1E292C",
size: 12
},
"lava": {
background: "#F8591A",
foreground: "#1C2846",
size: 12
}
},
stylesheet: ""
};
app.flags = {
dimensions: {
regex: /^(\d+)x(\d+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: +exec[1],
height: +exec[2]
}
}
},
fluid: {
regex: /^([0-9%]+)x([0-9%]+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) {
var exec = this.regex.exec(val);
return {
size: settings.themes.gray.size,
foreground: "#" + exec[2],
background: "#" + exec[1]
}
}
},
text: {
regex: /text\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
font: {
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
},
textmode: {
regex: /textmode\:(.*)/,
output: function(val){
return this.regex.exec(val)[1];
}
}
}
function text_size(width, height, template) {
height = parseInt(height, 10);
width = parseInt(width, 10);
var bigSide = Math.max(height, width)
var smallSide = Math.min(height, width)
var scale = 1 / 12;
var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);
return {
height: Math.round(Math.max(template.size, newHeight))
}
}
var svg_el = (function(){
//Prevent IE <9 from initializing SVG renderer
if(!window.XMLSerializer) return;
var serializer = new XMLSerializer();
var svg_ns = "http://www.w3.org/2000/svg"
var svg = document.createElementNS(svg_ns, "svg");
//IE throws an exception if this is set and Chrome requires it to be set
if(svg.webkitMatchesSelector){
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
}
var bg_el = document.createElementNS(svg_ns, "rect")
var text_el = document.createElementNS(svg_ns, "text")
var textnode_el = document.createTextNode(null)
text_el.setAttribute("text-anchor", "middle")
text_el.appendChild(textnode_el)
svg.appendChild(bg_el)
svg.appendChild(text_el)
return function(props){
svg.setAttribute("width",props.width);
svg.setAttribute("height", props.height);
bg_el.setAttribute("width", props.width);
bg_el.setAttribute("height", props.height);
bg_el.setAttribute("fill", props.template.background);
text_el.setAttribute("x", props.width/2)
text_el.setAttribute("y", props.height/2)
textnode_el.nodeValue=props.text
text_el.setAttribute("style", css_properties({
"fill": props.template.foreground,
"font-weight": "bold",
"font-size": props.text_height+"px",
"font-family":props.font,
"dominant-baseline":"central"
}))
return serializer.serializeToString(svg)
}
})()
function css_properties(props){
var ret = [];
for(p in props){
if(props.hasOwnProperty(p)){
ret.push(p+":"+props[p])
}
}
return ret.join(";")
}
function draw_canvas(args) {
var ctx = args.ctx,
dimensions = args.dimensions,
template = args.template,
ratio = args.ratio,
holder = args.holder,
literal = holder.textmode == "literal",
exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width * ratio,
height = dimensions.height * ratio;
var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
canvas.width = width;
canvas.height = height;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = template.background;
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = template.foreground;
ctx.font = "bold " + text_height + "px " + font;
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) {
var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
}
var text_width = ctx.measureText(text).width;
if (text_width / width >= 0.75) {
text_height = Math.floor(text_height * 0.75 * (width / text_width));
}
//Resetting font size if necessary
ctx.font = "bold " + (text_height * ratio) + "px " + font;
ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png");
}
function draw_svg(args){
var dimensions = args.dimensions,
template = args.template,
holder = args.holder,
literal = holder.textmode == "literal",
exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width,
height = dimensions.height;
var font = template.font ? template.font : "Arial,Helvetica,sans-serif";
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) {
var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
}
var string = svg_el({
text: text,
width:width,
height:height,
text_height:text_height,
font:font,
template:template
})
return "data:image/svg+xml;base64,"+btoa(string);
}
function draw(args) {
if(instance_config.use_canvas && !instance_config.use_svg){
return draw_canvas(args);
}
else{
return draw_svg(args);
}
}
function render(mode, el, holder, src) {
var dimensions = holder.dimensions,
theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, {
text: text
}) : theme);
theme = (holder.font ? extend(theme, {
font: holder.font
}) : theme);
el.setAttribute("data-src", src);
holder.theme = theme;
el.holder_data = holder;
if (mode == "image") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (instance_config.use_fallback || !holder.auto) {
el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px";
}
if (instance_config.use_fallback) {
el.style.backgroundColor = theme.background;
} else {
el.setAttribute("src", draw({ctx: ctx, dimensions: dimensions, template: theme, ratio:ratio, holder: holder}));
if(holder.textmode && holder.textmode == "exact"){
resizable_images.push(el);
resizable_update(el);
}
}
} else if (mode == "background") {
if (!instance_config.use_fallback) {
el.style.backgroundImage = "url(" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + ")";
el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
}
} else if (mode == "fluid") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (dimensions.height.slice(-1) == "%") {
el.style.height = dimensions.height
} else if(holder.auto == null || !holder.auto){
el.style.height = dimensions.height + "px"
}
if (dimensions.width.slice(-1) == "%") {
el.style.width = dimensions.width
} else if(holder.auto == null || !holder.auto){
el.style.width = dimensions.width + "px"
}
if (el.style.display == "inline" || el.style.display === "" || el.style.display == "none") {
el.style.display = "block";
}
set_initial_dimensions(el)
if (instance_config.use_fallback) {
el.style.backgroundColor = theme.background;
} else {
resizable_images.push(el);
resizable_update(el);
}
}
}
function dimension_check(el, callback) {
var dimensions = {
height: el.clientHeight,
width: el.clientWidth
};
if (!dimensions.height && !dimensions.width) {
el.setAttribute("data-holder-invisible", true)
callback.call(this, el)
}
else{
el.removeAttribute("data-holder-invisible")
return dimensions;
}
}
function set_initial_dimensions(el){
if(el.holder_data){
var dimensions = dimension_check(el, app.invisible_error_fn( set_initial_dimensions))
if(dimensions){
var holder = el.holder_data;
holder.initial_dimensions = dimensions;
holder.fluid_data = {
fluid_height: holder.dimensions.height.slice(-1) == "%",
fluid_width: holder.dimensions.width.slice(-1) == "%",
mode: null
}
if(holder.fluid_data.fluid_width && !holder.fluid_data.fluid_height){
holder.fluid_data.mode = "width"
holder.fluid_data.ratio = holder.initial_dimensions.width / parseFloat(holder.dimensions.height)
}
else if(!holder.fluid_data.fluid_width && holder.fluid_data.fluid_height){
holder.fluid_data.mode = "height";
holder.fluid_data.ratio = parseFloat(holder.dimensions.width) / holder.initial_dimensions.height
}
}
}
}
function resizable_update(element) {
var images;
if (element.nodeType == null) {
images = resizable_images;
} else {
images = [element]
}
for (var i in images) {
if (!images.hasOwnProperty(i)) {
continue;
}
var el = images[i]
if (el.holder_data) {
var holder = el.holder_data;
var dimensions = dimension_check(el, app.invisible_error_fn( resizable_update))
if(dimensions){
if(holder.fluid){
if(holder.auto){
switch(holder.fluid_data.mode){
case "width":
dimensions.height = dimensions.width / holder.fluid_data.ratio;
break;
case "height":
dimensions.width = dimensions.height * holder.fluid_data.ratio;
break;
}
}
el.setAttribute("src", draw({
ctx: ctx,
dimensions: dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
if(holder.textmode && holder.textmode == "exact"){
holder.exact_dimensions = dimensions;
el.setAttribute("src", draw({
ctx: ctx,
dimensions: holder.dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
}
}
}
}
function parse_flags(flags, options) {
var ret = {
theme: extend(settings.themes.gray, {})
};
var render = false;
for (var fl = flags.length, j = 0; j < fl; j++) {
var flag = flags[j];
if (app.flags.dimensions.match(flag)) {
render = true;
ret.dimensions = app.flags.dimensions.output(flag);
} else if (app.flags.fluid.match(flag)) {
render = true;
ret.dimensions = app.flags.fluid.output(flag);
ret.fluid = true;
} else if (app.flags.textmode.match(flag)) {
ret.textmode = app.flags.textmode.output(flag)
} else if (app.flags.colors.match(flag)) {
ret.theme = app.flags.colors.output(flag);
} else if (options.themes[flag]) {
//If a theme is specified, it will override custom colors
if(options.themes.hasOwnProperty(flag)){
ret.theme = extend(options.themes[flag], {});
}
} else if (app.flags.font.match(flag)) {
ret.font = app.flags.font.output(flag);
} else if (app.flags.auto.match(flag)) {
ret.auto = true;
} else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(flag);
}
}
return render ? ret : false;
}
for (var flag in app.flags) {
if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) {
return val.match(this.regex)
}
}
app.invisible_error_fn = function(fn){
return function(el){
if(el.hasAttribute("data-holder-invisible")){
throw new Error("Holder: invisible placeholder")
}
}
}
app.add_theme = function (name, theme) {
name != null && theme != null && (settings.themes[name] = theme);
return app;
};
app.add_image = function (src, el) {
var node = selector(el);
if (node.length) {
for (var i = 0, l = node.length; i < l; i++) {
var img = document.createElement("img")
img.setAttribute("data-src", src);
node[i].appendChild(img);
}
}
return app;
};
app.run = function (o) {
instance_config = extend({}, system_config)
preempted = true;
var options = extend(settings, o),
images = [],
imageNodes = [],
bgnodes = [];
if(options.use_canvas != null && options.use_canvas){
instance_config.use_canvas = true;
instance_config.use_svg = false;
}
if (typeof (options.images) == "string") {
imageNodes = selector(options.images);
} else if (window.NodeList && options.images instanceof window.NodeList) {
imageNodes = options.images;
} else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images];
} else if(window.HTMLCollection && options.images instanceof window.HTMLCollection){
imageNodes = options.images
}
if (typeof (options.bgnodes) == "string") {
bgnodes = selector(options.bgnodes);
} else if (window.NodeList && options.elements instanceof window.NodeList) {
bgnodes = options.bgnodes;
} else if (window.Node && options.bgnodes instanceof window.Node) {
bgnodes = [options.bgnodes];
}
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style");
if (!holdercss) {
holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss);
}
if (!options.nocss) {
if (holdercss.styleSheet) {
holdercss.styleSheet.cssText += options.stylesheet;
} else {
holdercss.appendChild(document.createTextNode(options.stylesheet));
}
}
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
for (var l = bgnodes.length, i = 0; i < l; i++) {
var src = window.getComputedStyle(bgnodes[i], null)
.getPropertyValue("background-image");
var flags = src.match(cssregex);
var bgsrc = bgnodes[i].getAttribute("data-background-src");
if (flags) {
var holder = parse_flags(flags[1].split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
} else if (bgsrc != null) {
var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
}
}
for (l = images.length, i = 0; i < l; i++) {
var attr_data_src, attr_src;
attr_src = attr_data_src = src = null;
try {
attr_src = images[i].getAttribute("src");
attr_datasrc = images[i].getAttribute("data-src");
} catch (e) {}
if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {
src = attr_src;
} else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {
src = attr_datasrc;
}
if (src) {
var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1).split("/"), options);
if (holder) {
if (holder.fluid) {
render("fluid", images[i], holder, src)
} else {
render("image", images[i], holder, src);
}
}
}
}
return app;
};
contentLoaded(win, function () {
if (window.addEventListener) {
window.addEventListener("resize", resizable_update, false);
window.addEventListener("orientationchange", resizable_update, false);
} else {
window.attachEvent("onresize", resizable_update)
}
preempted || app.run({});
});
if (typeof define === "function" && define.amd) {
define([], function () {
return app;
});
}
//github.com/davidchambers/Base64.js
(function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
//getElementsByClassName polyfill
document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s})
//getComputedStyle polyfill
window.getComputedStyle||(window.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var n=/(\-([a-z]){1})/g;return t=="float"&&(t="styleFloat"),n.test(t)&&(t=t.replace(n,function(){return arguments[2].toUpperCase()})),e.currentStyle[t]?e.currentStyle[t]:null},this})
//http://javascript.nwbox.com/ContentLoaded by Diego Perini with modifications
function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h=u,c=!0,i=n.document,a=i.documentElement,e=i.addEventListener?"addEventListener":"attachEvent",v=i.addEventListener?"removeEventListener":"detachEvent",f=i.addEventListener?"":"on",r=function(e){(e.type!=s||i.readyState==l)&&((e.type=="load"?n:i)[v](f+e.type,r,u),!h&&(h=!0)&&t.call(n,null))},o=function(){try{a.doScroll("left")}catch(n){setTimeout(o,50);return}r("poll")};if(i.readyState==l)t.call(n,"lazy");else{if(i.createEventObject&&a.doScroll){try{c=!n.frameElement}catch(y){}c&&o()}i[e](f+"DOMContentLoaded",r,u),i[e](f+s,r,u),n[e](f+"load",r,u)}}
//https://gist.github.com/991057 by Jed Schmidt with modifications
function selector(a,b){var a=a.match(/^(\W)?(.*)/),b=b||document,c=b["getElement"+(a[1]?"#"==a[1]?"ById":"sByClassName":"sByTagName")],d=c.call(b,a[2]),e=[];return null!==d&&(e=d.length||0===d.length?d:[d]),e}
//shallow object property extend
function extend(a,b){
var c={};
for(var i in a){
if(a.hasOwnProperty(i)){
c[i]=a[i];
}
}
for(var i in b){
if(b.hasOwnProperty(i)){
c[i]=b[i];
}
}
return c
}
//hasOwnProperty polyfill
if (!Object.prototype.hasOwnProperty)
/*jshint -W001, -W103 */
Object.prototype.hasOwnProperty = function(prop) {
var proto = this.__proto__ || this.constructor.prototype;
return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);
}
/*jshint +W001, +W103 */
})(Holder, window);

14
docs/assets/js/vendor/jszip.min.js vendored Normal file

File diff suppressed because one or more lines are too long

16
docs/assets/js/vendor/less.min.js vendored Normal file

File diff suppressed because one or more lines are too long

14
docs/assets/js/vendor/uglify.min.js vendored Normal file

File diff suppressed because one or more lines are too long

185
docs/components.html Normal file
View File

@@ -0,0 +1,185 @@
---
layout: default
title: Components
slug: components
lead: "Reusable components to built the user interface."
base_url: "../"
---
<!-- Navmenu
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="navmenu">Navmenu</h1>
</div>
<p>Navmenu is a vertical navigation component. By default it shares it look and feel with the navmenu component.</p>
<div class="bs-callout bs-callout-info">
<h4>Custom width</h4>
<p>The navmenu is 300px wide by default. You can change this by customizing the <code>@navmenu-width</code> variable or by setting the width of <code>.navmenu</code> in your CSS.</p>
</div>
<h2 id="navmenu-default">Default navmenu</h2>
<div class="bs-example">
<nav class="navmenu navmenu-default" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu navmenu-nav" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</nav>
</div>
{% highlight html %}
<nav class="navmenu navmenu-default" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu navmenu-nav" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</nav>
{% endhighlight %}
<div class="bs-callout bs-callout-warning">
<h4>Make navmenus accessible</h4>
<p>Be sure to add a <code>role="navigation"</code> to every navmenu to help with accessibility.</p>
</div>
<h2 id="navmenu-fixed">Fixed to left or right</h2>
<p>Add either <code>.navmenu-fixed-left</code> or <code>.navmenu-fixed-right</code>.</p>
<div class="bs-example bs-navmenu-fixed-example">
<nav class="navmenu navmenu-default navmenu-fixed-left" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</nav>
</div><!-- /example -->
{% highlight html %}
<nav class="navmenu navmenu-default navmenu-fixed-left offcanvas-sm" role="navigation">
...
</nav>
{% endhighlight %}
<div class="bs-callout bs-callout-danger">
<h4>Body padding required</h4>
<p>The fixed navmenu will overlay your other content, unless you add <code>padding</code> to the left or right of the <code>&lt;body&gt;</code>. Try out your own values or use our snippet below. Tip: By default, the navmenu is 300px wide.</p>
{% highlight css %}
@media (min-width: 992px) {
body {
padding-left: 300px;
}
}
{% endhighlight %}
<p>Make sure to include this <strong>after</strong> the Jasny Bootstrap CSS.</p>
</div>
<h2 id="navmenu-offcanvas">Off canvas</h2>
<p>With the <a href="../javascript/#offcanvas">offcanvas plugin</a>, you can hide the navmenu off canvas. This is especially useful for screens with a small viewport.</p>
<div class="bs-example bs-navmenu-offcanvas-example">
<div id="myNavmenuCanvas">
<nav id="myNavmenu" class="navmenu navmenu-default navmenu-fixed-left offcanvas" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</nav>
<div class="navbar navbar-default navbar-fixed-top">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target="#myNavmenu" data-canvas="#myNavmenuCanvas" data-placement="left">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis in aliquet nisl. Praesent sed leo congue, fringilla eros eu, tempus metus. Nam mollis odio ipsum, non vehicula ipsum accumsan sodales. Morbi varius vitae elit euismod cursus. Donec a dapibus justo, in facilisis nisi. Suspendisse ut turpis dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque dui risus, tincidunt at odio ut, ultrices dignissim ipsum. Cras ultrices erat nec leo luctus varius. Nulla sollicitudin tincidunt nulla, ut porta mauris volutpat vitae. Suspendisse ornare dolor sit amet massa venenatis pulvinar.</p>
</div>
</div><!-- /example -->
{% highlight html %}
<nav id="myNavmenu" class="navmenu navmenu-default navmenu-fixed-left offcanvas" role="navigation">
...
</nav>
<div class="navbar navbar-default navbar-fixed-top">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target="#myNavmenu" data-canvas="body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
{% endhighlight %}
<div class="bs-callout bs-callout-info">
<h4>Examples</h4>
<p>There is a full example for an <a href="../examples/navmenu-push/">off canvas push menu</a> as well as examples for an off canvas navmenu with an <a href="../examples/navmenu/">slide in</a> and <a href="../examples/navmenu-reveal/">reveal</a> effect.</p>
</div>
<h2 id="navmenu-inverted">Inverted navmenu</h2>
<p>Modify the look of the navmenu by adding <code>.navmenu-inverse</code>.</p>
<div class="bs-example">
<nav class="navmenu navmenu-inverse" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</nav>
</div><!-- /example -->
{% highlight html %}
<nav class="navmenu navmenu-inverse" role="navigation">
...
</nav>
{% endhighlight %}
</div>
<!-- Alerts
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="alerts">Alerts</h1>
</div>
<h2 id="alerts-fixed">Fixed to top / bottom</h2>
<p>Add <code>.alert-fixed-top</code> top stick the alert on top of your page. Use <code>.alert-fixed-bottom</code> for the bottom.</p>
<div class="bs-example">
<div class="alert alert-success alert-fixed-top">
<strong>Success!</strong> Your action has been completed succefully.
</div>
</div>
{% highlight html %}
<div class="alert alert-success alert-fixed-top">
<strong>Success!</strong> Your action has been completed succefully.
</div>
{% endhighlight %}
</div>

52
docs/css.html Normal file
View File

@@ -0,0 +1,52 @@
---
layout: default
title: CSS
slug: css
lead: "Global CSS settings, fundamental HTML elements styled and enhanced with extensible classes, and an advanced grid system."
base_url: "../"
---
<!-- Global Bootstrap settings
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="overview">Overview</h1>
</div>
<h3 id="overview-container">Containers</h3>
<p>Added <code>.container-smooth</code> a container to use the same <code>max-width</code> for all viewport sizes. This means that the container size won't jump at media query breakpoints.</p>
</div>
<!-- Buttons
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="buttons">Buttons</h1>
</div>
<div>
<h2 id="buttons-labels">Labels</h2>
<p>Give a button some extra style by adding a label. Add <code>.btn-labeled</code> to any button with a label.</p>
<div class="bs-example">
<button type="button" class="btn btn-labeled btn-default"><span class="btn-label"><i class="glyphicon glyphicon-arrow-left"></i></span>Left</button>
<button type="button" class="btn btn-labeled btn-default">Right<span class="btn-label btn-label-right"><i class="glyphicon glyphicon-arrow-right"></i></span></button>
<button type="button" class="btn btn-labeled btn-success"><span class="btn-label"><i class="glyphicon glyphicon-ok"></i></span>Success</button>
<button type="button" class="btn btn-labeled btn-danger"><span class="btn-label"><i class="glyphicon glyphicon-remove"></i></span>Danger</button>
</div>
{% highlight html %}
<!-- Standard button with label -->
<button type="button" class="btn btn-labeled btn-default"><span class="btn-label"><i class="glyphicon glyphicon-arrow-left"></i></span>Left</button>
<!-- Standard button with label on the right side -->
<button type="button" class="btn btn-labeled btn-default">Right<span class="btn-label btn-label-right"><i class="glyphicon glyphicon-arrow-right"></i></span></button>
<!-- Success button with label -->
<button type="button" class="btn btn-labeled btn-success"><span class="btn-label"><i class="glyphicon glyphicon-ok"></i></span>Success</button>
<!-- Danger button with label -->
<button type="button" class="btn btn-labeled btn-danger"><span class="btn-label"><i class="glyphicon glyphicon-remove"></i></span>Danger</button>
{% endhighlight %}
</div>
</div>

164
docs/customize.html Normal file
View File

@@ -0,0 +1,164 @@
---
layout: default
title: Customize and download
slug: customize
lead: Customize Bootstrap's components, Less variables, and jQuery plugins to get your very own version.
base_url: "../"
---
<!-- Customizer form -->
<form class="bs-customizer" role="form">
<div class="bs-docs-section" id="less-section">
<div class="page-header">
<button class="btn btn-default toggle" type="button">Toggle all</button>
<h1 id="less">Less files</h1>
</div>
<p class="lead">Choose which Less files to compile into your custom build of Jasny Bootstrap. Not sure which files to use? Read through the <a href="../css/">CSS</a> and <a href="../components/">Components</a> pages in the docs.</p>
<div class="row">
<div class="col-xs-6 col-sm-4">
<h3>Common CSS</h3>
<div class="checkbox">
<label>
<input type="checkbox" checked value="grid-container-smooth.less">
Grid system
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="button-labels.less">
Button labels
</label>
</div>
</div><!-- .col-xs-6 .col-sm-4 -->
<div class="col-xs-6 col-sm-4">
<h3>Components</h3>
<div class="checkbox">
<label>
<input type="checkbox" checked value="navmenu.less">
Navmenu
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="alerts-fixed.less">
Alerts
</label>
</div>
</div><!-- .col-xs-6 .col-sm-4 -->
<div class="col-xs-6 col-sm-4">
<h3>JavaScript components</h3>
<div class="checkbox">
<label>
<input type="checkbox" checked value="offcanvas.less">
Off canvas
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="rowlink.less">
Rowlink
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="inputmask.less">
Input mask
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="fileinput.less">
File input
</label>
</div>
</div><!-- .col-xs-6 .col-sm-4 -->
</div><!-- /.row -->
<div class="bs-callout bs-callout-danger">
<h4>Twitter Bootstrap required</h4>
<p>Jasny Bootstrap requires <a href="http://getbootstrap.com/" target="_blank">Twitter Bootstrap</a> to be included.</p>
</div>
</div>
<div class="bs-docs-section" id="plugin-section">
<div class="page-header">
<button class="btn btn-default toggle" type="button">Toggle all</button>
<h1 id="plugins">jQuery plugins</h1>
</div>
<p class="lead">Choose which jQuery plugins should be included in your custom JavaScript files. Unsure what to include? Read the <a href="../javascript/">JavaScript</a> page in the docs.</p>
<div class="row">
<div class="col-lg-6">
<h4>Linked to components</h4>
<div class="checkbox">
<label>
<input type="checkbox" checked value="rowlink.js">
Rowlink
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="inputmask.js">
Input mask
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" checked value="fileinput.js">
File input
</label>
</div>
</div>
<div class="col-lg-6">
<h4>Magic</h4>
<div class="checkbox">
<label>
<input type="checkbox" checked value="offcanvas.js">
Off canvas
</label>
</div>
</div>
</div>
<div class="bs-callout bs-callout-info">
<h4>Produces two files</h4>
<p>All checked plugins will be compiled into a readable <code>jasny-bootstrap.js</code> and a minified <code>jasny-bootstrap.min.js</code>. We recommend you use the minified version in production.</p>
</div>
<div class="bs-callout bs-callout-danger">
<h4>jQuery required</h4>
<p>All plugins require the latest version of <a href="http://jquery.com/" target="_blank">jQuery</a> to be included.</p>
</div>
</div>
<div class="bs-docs-section" id="less-variables-section">
<div class="page-header">
<button class="btn btn-default toggle" type="reset">Reset to defaults</button>
<h1 id="less-variables">Less variables</h1>
</div>
<p class="lead">Customize Less variables to define colors, sizes and more inside your custom CSS stylesheets.</p>
{% include customizer-variables.html %}
</div>
<div class="bs-docs-section">
<div class="page-header">
<h1 id="download">Download</h1>
</div>
<p class="lead">Hooray! Your custom version of Jasny Bootstrap is now ready to be compiled. Just click the button below to finish the process.</p>
<div class="bs-customize-download">
<button type="submit" id="btn-compile" class="btn btn-block btn-lg btn-outline" onclick="_gaq.push(['_trackEvent', 'Customize', 'Download', 'Customize and Download']);">Compile and Download</button>
</div>
</div><!-- /download -->
</form>

1
docs/dist/css/jasny-bootstrap.css.map vendored Normal file

File diff suppressed because one or more lines are too long

7
docs/dist/css/jasny-bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

6
docs/dist/js/jasny-bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../docs-assets/ico/favicon.png">
<title>Navbar Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="../../dist/css/jasny-bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="navbar-offcanvas.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<!-- Static navbar -->
<div class="navbar navbar-fixed-top navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target=".navbar-offcanvas" data-canvas="body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-offcanvas offcanvas">
<a class="navmenu-brand" href="#">Project name</a>
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Offcanvas Navbar example</h1>
<p>This example demonstrates using the offcanvas plugin with the navbar.</p>
</div>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../../dist/js/jasny-bootstrap.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,10 @@
body {
padding-top: 80px;
padding-bottom: 20px;
}
@media (min-width: 992px) {
.navbar {
padding-right: 15px;
}
}

View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.png">
<title>Off Canvas Push Menu Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="../../dist/css/jasny-bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="navmenu-push.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navmenu navmenu-default navmenu-fixed-left offcanvas">
<a class="navmenu-brand" href="#">Project name</a>
<ul class="nav navmenu-nav">
<li><a href="../navmenu/">Slide in</a></li>
<li class="active"><a href="./">Push</a></li>
<li><a href="../navmenu-reveal/">Reveal</a></li>
</ul>
<ul class="nav navmenu-nav">
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu navmenu-nav">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div>
<div class="navbar navbar-default navbar-fixed-top">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target=".navmenu" data-canvas="body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="container">
<div class="page-header">
<h1>Off Canvas Push Menu Template</h1>
</div>
<p class="lead">This example demonstrates the use of the offcanvas plugin with a push effect.</p>
<p>You get the push effect by setting the <code>canvas</code> option to 'body'.</p>
<p>Also take a look at the example for a navmenu with <a href="../navmenu">slide in effect</a> and <a href="../navmenu-reveal">reveal effect</a>.</p>
</div><!-- /.container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../../dist/js/jasny-bootstrap.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,29 @@
html, body {
height: 100%;
}
body {
padding: 50px 0 0 0;
}
.navbar-toggle {
float: left;
margin-left: 15px;
}
@media (min-width: 0) {
.navbar-toggle {
display: block; /* force showing the toggle */
}
}
@media (min-width: 992px) {
body {
padding: 0;
}
.navbar {
right: auto;
background: none;
border: none;
}
}

View File

@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.png">
<title>Off Canvas Reveal Menu Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="../../dist/css/jasny-bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="navmenu-reveal.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navmenu navmenu-default navmenu-fixed-left">
<a class="navmenu-brand" href="#">Project name</a>
<ul class="nav navmenu-nav">
<li><a href="../navmenu/">Slide in</a></li>
<li><a href="../navmenu-push/">Push</a></li>
<li class="active"><a href="./">Reveal</a></li>
</ul>
<ul class="nav navmenu-nav">
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu navmenu-nav">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div>
<div class="canvas">
<div class="navbar navbar-default navbar-fixed-top">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-recalc="false" data-target=".navmenu" data-canvas=".canvas">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="container">
<div class="page-header">
<h1>Off Canvas Reveal Menu Template</h1>
</div>
<p class="lead">This example demonstrates the use of the offcanvas plugin with a reveal effect.</p>
<p>On the contrary of the push effect, the menu doesn't move with the canvas.</p>
<p>You get the reveal effect by wrapping the content in a div and setting the <code>canvas</code> option to target that div.</p>
<p>Note that in this example, the navmenu doesn't have the <code>.offcanvas</code> class, but is placed under the canvas by setting the <code>z-index</code>.</p>
<p>Also take a look at the examples for a navmenu with <a href="../navmenu">slide in effect</a> and <a href="../navmenu-push">push effect</a>.</p>
</div><!-- /.container -->
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../../dist/js/jasny-bootstrap.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,41 @@
html, body {
height: 100%;
}
.navbar-toggle {
float: left;
margin-left: 15px;
}
.navmenu {
z-index: 1;
}
.canvas {
position: relative;
left: 0;
z-index: 2;
min-height: 100%;
padding: 50px 0 0 0;
background: #fff;
}
@media (min-width: 0) {
.navbar-toggle {
display: block; /* force showing the toggle */
}
}
@media (min-width: 992px) {
body {
padding: 0;
}
.navbar {
right: auto;
background: none;
border: none;
}
.canvas {
padding: 0;
}
}

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.png">
<title>Navmenu Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="../../dist/css/jasny-bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="navmenu.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navmenu navmenu-default navmenu-fixed-left offcanvas-sm">
<a class="navmenu-brand visible-md visible-lg" href="#">Project name</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="./">Slide in</a></li>
<li><a href="../navmenu-push/">Push</a></li>
<li><a href="../navmenu-reveal/">Reveal</a></li>
</ul>
<ul class="nav navmenu-nav">
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu navmenu-nav">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div>
<div class="navbar navbar-default navbar-fixed-top hidden-md hidden-lg">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target=".navmenu">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="container">
<div class="page-header">
<h1>Navmenu Template</h1>
</div>
<p class="lead">This example shows the navmenu element. If the viewport is <b>less than 992px</b> the menu will be placed the off canvas and will be shown with a slide in effect.</p>
<p>Also take a look at the examples for a navmenu with <a href="../navmenu-push">push effect</a> and <a href="../navmenu-reveal">reveal effect</a>.</p>
</div><!-- /.container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../../dist/js/jasny-bootstrap.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,46 @@
html, body {
height: 100%;
}
body {
padding: 50px 0 0 0;
}
.navmenu {
padding-top: 50px;
}
.navbar {
display: block;
text-align: center;
}
.navbar-brand {
display: inline-block;
float: none;
}
.navbar-toggle {
position: absolute;
float: left;
margin-left: 15px;
}
.container {
max-width: 100%;
}
@media (min-width: 1px) {
.navbar-toggle {
display: block !important;
}
}
@media (min-width: 992px) {
body {
padding: 0 0 0 300px;
}
.navmenu {
padding-top: 0;
}
.navbar {
display: none !important; /* IE8 fix */
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../docs-assets/ico/favicon.png">
<title>Starter Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<link href="../../dist/css/jasny-bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="starter-template.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<div class="starter-template">
<h1>Bootstrap starter template</h1>
<p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
</div>
</div><!-- /.container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../../dist/js/jasny-bootstrap.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
body
{
padding-top: 50px;
}
.starter-template
{
padding: 40px 15px;
text-align: center;
}

313
docs/getting-started.html Normal file
View File

@@ -0,0 +1,313 @@
---
layout: default
title: Getting started
slug: getting-started
lead: "An overview of Jasny Bootstrap, how to download and use, basic templates and examples, and more."
base_url: "../"
---
<!-- Getting started
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="jasny-bootstrap">Jasny Bootstrap</h1>
</div>
<p class="lead">Jasny Bootstrap is an extension to <a href="http://getbootstrap.com">Twitter Bootstrap</a>, adding a number of features and components.</p>
<p>The aim of Jasny Bootstrap is to provide all the required features for building highly interactive web applications for desktop and mobile.</p>
<div class="bs-callout bs-callout-warning">
<h4>Delivered as extension only</h4>
<p>As of version 3.1.0 Jasny Bootstrap is no longer bundeled with Twitter Bootstrap. You should load Twitter Bootstrap's CSS before this extension.</p>
</div>
</div>
<!-- Getting started
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="download">Download</h1>
</div>
<p class="lead">Jasny Bootstrap has a few easy ways to quickly get started, each one appealing to a different skill level and use case. Read through to see what suits your particular needs.</p>
<h3 id="download-compiled">Compiled CSS and JS</h3>
<p>The fastest way to get Jasny Bootstrap is to download the compiled and minified versions of our CSS and JavaScript. No documentation or original source files are included.</p>
<p><a class="btn btn-lg btn-primary" href="{{ site.download.dist }}" onclick="_gaq.push(['_trackEvent', 'Getting started', 'Download', 'Download compiled']);">Download Jasny Bootstrap</a></p>
<h3 id="download-additional">Additional downloads</h3>
<div class="bs-docs-dl-options">
<h4>
<a href="{{ site.download.source }}" onclick="_gaq.push(['_trackEvent', 'Getting started', 'Download', 'Download source']);">Download source code</a>
</h4>
<p>Get the latest Jasny Bootstrap LESS and JavaScript source code by downloading it directly from GitHub.</p>
<h4>
<a href="{{ site.repo }}" onclick="_gaq.push(['_trackEvent', 'Getting started', 'Download', 'GitHub project']);">Clone or fork via GitHub</a>
</h4>
<p>Visit us on GitHub to clone or fork the Jasny Bootstrap project.</p>
<h4>
Install with <a href="http://bower.io">Bower</a>
</h4>
<p>Install and manage the original files for all CSS and JavaScript, along with a local copy of the docs, using <a href="http://bower.io">Bower</a>.</p>
{% highlight bash %}$ bower install jasny-bootstrap{% endhighlight %}
</div>
<h3 id="download-cdn">Jasny Bootstrap @ cdnjs</h3>
<p><a href="http://cdnjs.com" target="_blank">CDNJS</a> is a community driven CDN hosted by CloudFlare, supporting over a hundred projects. To use this CDN, swap your local instances for the CDN links listed below.</p>
{% highlight html %}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="{{ site.cdn.css }}">
<!-- Latest compiled and minified JavaScript -->
<script src="{{ site.cdn.js }}"></script>
{% endhighlight %}
<div class="bs-callout bs-callout-warning" id="callout-less-compilation">
<h4>Compiling Jasny Bootstrap's LESS files</h4>
<p>If you work with Jasny Bootstrap's uncompiled source code, you need to compile the LESS files to produce usable CSS files. For compiling LESS files into CSS, we only officially support <a href="http://twitter.github.io/recess/">Recess</a>, which is Twitter's CSS hinter based on <a href="http://lesscss.org">less.js</a>.</p>
</div>
</div>
<!-- File structure
================================================== -->
<div class="bs-docs-section bs-jasny">
<div class="page-header">
<h1 id="whats-included">What's included</h1>
</div>
<p class="lead">Within the download you'll find the following directories and files, logically grouping common resources and providing both compiled and minified variations.</p>
<p>Once downloaded, unzip the compressed folder to see the structure of (the compiled) Jasny Bootstrap. You'll see something like this:</p>
<!-- NOTE: This info is intentionally duplicated in the README.
Copy any changes made here over to the README too. -->
{% highlight bash %}
jasny-bootstrap/
├── css/
│ ├── jasny-bootstrap.css
│ ├── jasny-bootstrap.min.css
└── js/
├── jasny-bootstrap.js
└── jasny-bootstrap.min.js
{% endhighlight %}
<p>This is the most basic form of Jasny Bootstrap. We provide compiled CSS and JS (<code>jasny-bootstrap.*</code>), as well as compiled and minified CSS and JS (<code>jasny-bootstrap.min.*</code>).</p>
<p>The <code>jasny-bootstrap.*</code> files should be loaded in conjunction with the original Twitter Bootstrap files.</p>
<div class="bs-callout bs-callout-danger" id="jquery-required">
<h4>jQuery required</h4>
<p>Please note that <strong>all JavaScript plugins require jQuery</strong> to be included, as shown in the <a href="#template">starter template</a>. <a href="{{ site.repo }}/blob/v{{ site.current_version }}/bower.json">Consult our <code>bower.json</code></a> to see which versions of jQuery are supported.</p>
</div>
</div>
<!-- Template
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="template">Basic template</h1>
</div>
<p class="lead">Start with this basic HTML template, or modify <a href="../getting-started#examples">these examples</a>. We hope you'll customize our templates and examples, adapting them to suit your needs.</p>
<p>Copy the HTML below to begin working with a minimal Bootstrap document.</p>
{% highlight html %}
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap 101 Template</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="css/jasny-bootstrap.min.css" rel="stylesheet" media="screen">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>Hello, world!</h1>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
<script src="js/jasny-bootstrap.min.js"></script>
</body>
</html>
{% endhighlight %}
</div>
<!-- Template
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="examples">Examples</h1>
</div>
<p class="lead">Create diverse and advanced user interfaces using Jasny's Bootstrap components. See also <a href="#customizing">Customizing Bootstrap</a> for tips on maintaining your own Bootstrap variants.</p>
<div class="row bs-examples">
<div class="col-xs-6 col-md-4">
<a class="thumbnail" href="../examples/starter-template/">
<img src="../examples/screenshots/starter-template.jpg" alt="">
</a>
<h4>Starter template</h4>
<p>Nothing but the basics: compiled CSS and JavaScript along with a container.</p>
</div>
<div class="col-xs-6 col-md-4">
<a class="thumbnail" href="../examples/navmenu/">
<img src="../examples/screenshots/navmenu.jpg" alt="">
</a>
<h4>Navmenu</h4>
<p>A basic template showing the navmenu element and demonstrates usage of the offcanvas plugin.</p>
</div>
<div class="clearfix visible-xs visible-sm"></div>
<div class="col-xs-6 col-md-4">
<a class="thumbnail" href="../examples/navmenu-push/">
<img src="../examples/screenshots/navmenu-push.jpg" alt="">
</a>
<h4>Off Canvas Push Menu</h4>
<p>A template demonstrating a push effect for the off canvas navmenu.</p>
</div>
<div class="clearfix visible-md visible-lg"></div>
<div class="col-xs-6 col-md-4">
<a class="thumbnail" href="../examples/navmenu-reveal/">
<img src="../examples/screenshots/navmenu-reveal.jpg" alt="">
</a>
<h4>Off Canvas Reveal Menu</h4>
<p>A template demonstrating a reveal effect by placing the navmenu under the content.</p>
</div>
<div class="col-xs-6 col-md-4">
<a class="thumbnail" href="../examples/navbar-offcanvas/">
<img src="../examples/screenshots/navbar-offcanvas.jpg" alt="">
</a>
<h4>Off canvas navbar</h4>
<p>A template using offcanvas for mobile view of the navbar.</p>
</div>
</div>
</div>
<!-- Migration
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="migration">Migrating from 2.x to 3.0</h1>
</div>
<p class="lead">Folks looking to upgrade to v3 should use this section as a general upgrade guide. We've outlined some of the major changes and provided tables that highlight key changes.</p>
<h2 id="migration-classes">Major class changes</h2>
<p>This table shows the style changes between v2.x and v3.0.</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Bootstrap 2.x</th>
<th>Bootstrap 3.0</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>.container-semifluid</code></td>
<td><code>.container-smooth</code></td>
</tr>
<tr>
<td><code>.fileupload</code> <code>.fileupload-*</code></td>
<td><code>.fileinput</code> <code>.fileinput-*</code></td>
</tr>
</tbody>
</table>
</div><!-- /.table-responsive -->
<h2 id="migration-new">What's new</h2>
<p>We've added new elements and changed some existing ones. Here are the new or updated styles.</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Element</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Navmenu</td>
<td><code>.navmenu .navmenu-default</code> <code>.navmenu .navmenu-inverse</code> <code>.navmenu-fixed-left</code> <code>.navmenu-fixed-right</code> <code>.navmenu-brand</code> <code>.navmenu-nav</code></td>
</tr>
<tr>
<td>Fixed alerts</td>
<td><code>.alert-fixed-top</code> <code>.alert-fixed-bottom</code></td>
</tr>
<tr>
<td>Off canvas</td>
<td><code>.offcanvas</code> <code>.offcanvas-*</code></td>
</tr>
</tbody>
</table>
</div><!-- /.table-responsive -->
<h2 id="migration-dropped">What's removed</h2>
<p>The following elements have been dropped or changed in v3.0.</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Element</th>
<th>Removed from 2.x</th>
<th>3.0 Equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td>Header actions</td>
<td><code>.header-actions</code></td>
<td class="text-muted">N/A</td>
</tr>
<tr>
<td>Table actions</td>
<td><code>.table-actions</code></td>
<td class="text-muted">N/A</td>
</tr>
<tr>
<td>Desktop rows</td>
<td><code>.row-desktop</code></td>
<td><code>.row &gt; .col-md-*</code></td>
</tr>
<tr>
<td>Action links</td>
<td><code>.act-*</code></td>
<td class="text-muted">N/A</td>
</tr>
<tr>
<td>Page alerts</td>
<td><code>.pagealert</code></td>
<td><code>.alert-fixed-top</code></td>
</tr>
<tr>
<td>Iconic icons</td>
<td><code>.iconic-*</code></td>
<td class="text-muted">N/A</td>
</tr>
<tr>
<td>Editor textarea</td>
<td><code>.editor</code></td>
<td class="text-muted">N/A</td>
</tr>
</tbody>
</table>
</div><!-- /.table-responsive -->
<h2 id="migration-notes">Additional notes</h2>
<p>Other changes in v3.0 are not immediately apparent. Base classes, key styles, and behaviors have been adjusted for flexibility and our <em>mobile first</em> approach. Here's a partial list:</p>
<ul>
<li>The fileupload plugin has been renamed to fileinput. File upload was poorly chosen, since the plugin allows the creation of a styled file input element. It has nothing to do with how the file is uploaded.</li>
<li class="bs-jasny-only">Tab alignments are still supported in this fork (while dropped in Twitter Bootstrap).</li>
<li>Typeahead has been dropped, in favor of using <a href="http://brianreavis.github.io/selectize.js/">Selectize.js</a>.</li>
<li>Iconic icons are still available from <a href="http://www.somerandomdude.com/work/open-iconic/">P.J. Onori</a>.</li>
</ul>
<p>For more information on upgrading to v3.0, and code snippets from the community, see <a href="http://bootply.com/">Bootply</a>.</p>
</div>

15
docs/index.html Normal file
View File

@@ -0,0 +1,15 @@
---
layout: home
title: Jasny Bootstrap
---
<main class="bs-masthead" id="content" role="main">
<div class="container">
<h1>{{ page.title }}</h1>
<p class="lead">The missing components for you favorite front-end framework.</p>
<p>
<a href="{{ site.download.dist }}" class="btn btn-outline-inverse btn-lg" onclick="_gaq.push(['_trackEvent', 'Jumbotron actions', 'Download', 'Download {{ site.current_version }}']);">Download</a>
or <a href="{{ site.download.source }}" onclick="_gaq.push(['_trackEvent', 'Jumbotron actions', 'Download', 'Download {{ site.current_version }} source']);">Download source</a>
</p>
</div>
</main>

View File

@@ -0,0 +1,15 @@
// NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template.
li
a(href='#less') Less components
li
a(href='#plugins') jQuery plugins
li
a(href='#less-variables') Less variables
ul.nav
each section in sections
if section.customizable
li
a(href='#'+section.id)= section.heading
li
a(href='#download') Download
// NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template.

View File

@@ -0,0 +1,21 @@
// NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-variables.jade template.
each section in sections
if section.customizable
h2(id=section.id)= section.heading
if section.docstring
p!= section.docstring.html
each subsection in section.subsections
if subsection.heading
h3(id=subsection.id)= subsection.heading
div.row
each variable in subsection.variables
div.bs-customizer-input
label(for="input-" + variable.name)= variable.name
input.form-control(
id="input-" + variable.name
type="text"
value=variable.defaultValue
data-var=variable.name)
if variable.docstring
p.help-block!= variable.docstring.html
// NOTE: DO NOT EDIT THE PRECEDING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-variables.jade template.

572
docs/javascript.html Normal file
View File

@@ -0,0 +1,572 @@
---
layout: default
title: JavaScript
slug: js
lead: "Bring Bootstrap's components to life with over a dozen custom jQuery plugins. Easily include them all, or one by one."
base_url: "../"
---
<!-- Overview
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="js-overview">Overview</h1>
</div>
<h3 id="js-individual-compiled">Individual or compiled</h3>
<p>Plugins can be included individually (using Jasny Bootstrap's individual <code>*.js</code> files), or all at once (using <code>jasny-bootstrap.js</code> or the minified <code>jasn-bootstrap.min.js</code>).</p>
<p>The Jasny Bootstrap plugins work with or without loading Twitter Bootstrap's <code>bootstrap.js</code>.</p>
<div class="bs-callout bs-callout-danger">
<h4>Do not attempt to include both.</h4>
<p>Both <code>jasny-bootstrap.js</code> and <code>jasny-bootstrap.min.js</code> contain all plugins in a single file.</p>
</div>
<h3 id="js-data-attrs">Data attributes</h3>
<p>You can use all Jasny Bootstrap plugins purely through the markup API without writing a single line of JavaScript. This is Bootstrap's first-class API and should be your first consideration when using a plugin.</p>
<p>That said, in some situations it may be desirable to turn this functionality off. Therefore, we also provide the ability to disable the data attribute API by unbinding all events on the document namespaced with <code>data-api</code>. This looks like this:
{% highlight js %}
$(document).off('.data-api')
{% endhighlight %}
<p>Alternatively, to target a specific plugin, just include the plugin's name as a namespace along with the data-api namespace like this:</p>
{% highlight js %}
$(document).off('.alert.data-api')
{% endhighlight %}
<h3 id="js-programmatic-api">Programmatic API</h3>
<p>We also believe you should be able to use all Bootstrap plugins purely through the JavaScript API. All public APIs are single, chainable methods, and return the collection acted upon.</p>
{% highlight js %}
$(".fileinput").fileinput().addClass("fat")
{% endhighlight %}
<p>All methods should accept an optional options object, a string which targets a particular method, or nothing (which initiates a plugin with default behavior):</p>
{% highlight js %}
$("#myMenu").offcanvas() // initialized with defaults
$("#myMenu").offcanvas({ autohide: false }) // initialized with no autohide
$("#myMenu").offcanvas('show') // initializes and invokes show immediately</p>
{% endhighlight %}
<p>Each plugin also exposes its raw constructor on a <code>Constructor</code> property: <code>$.fn.popover.Offcanvas</code>. If you'd like to get a particular plugin instance, retrieve it directly from an element: <code>$('.navmenu').data('offcanvas')</code>.</p>
<h3 id="js-noconflict">No conflict</h3>
<p>Sometimes it is necessary to use Bootstrap plugins with other UI frameworks. In these circumstances, namespace collisions can occasionally occur. If this happens, you may call <code>.noConflict</code> on the plugin you wish to revert the value of.</p>
{% highlight js %}
var bootstrapButton = $.fn.button.noConflict() // return $.fn.button to previously assigned value
$.fn.bootstrapBtn = bootstrapButton // give $().bootstrapBtn the Bootstrap functionality
{% endhighlight %}
<h3 id="js-events">Events</h3>
<p>Bootstrap provides custom events for most plugin's unique actions. Generally, these come in an infinitive and past participle form - where the infinitive (ex. <code>show</code>) is triggered at the start of an event, and its past participle form (ex. <code>shown</code>) is trigger on the completion of an action.</p>
<p>As of 3.0.0, all Bootstrap events are namespaced.</p>
<p>All infinitive events provide <code>preventDefault</code> functionality. This provides the ability to stop the execution of an action before it starts.</p>
{% highlight js %}
$('#myMenu').on('show.bs.offcanvas', function (e) {
if (!data) return e.preventDefault() // stops menu from being shown
})
{% endhighlight %}
</div>
<!-- Off canvas
================================================== -->
<div class="bs-docs-section">
<div class="page-header">
<h1 id="offcanvas">Off canvas <small>offcanvas.js</small></h1>
</div>
<h2 id="offcanvas-examples">Example</h2>
<p>The offcanvas plugin allows you to hide an element from sight and than show it by moving either that or any other element. It's intented to be used for off canvas navigation, like push menus.</p>
<div class="bs-example bs-navmenu-offcanvas-example">
<div id="myNavmenuCanvas">
<nav id="myNavmenu" class="navmenu navmenu-default navmenu-fixed-left offcanvas" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</nav>
<div class="navbar navbar-default navbar-fixed-top">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target="#myNavmenu" data-canvas="#myNavmenuCanvas" data-placement="left">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis in aliquet nisl. Praesent sed leo congue, fringilla eros eu, tempus metus. Nam mollis odio ipsum, non vehicula ipsum accumsan sodales. Morbi varius vitae elit euismod cursus. Donec a dapibus justo, in facilisis nisi. Suspendisse ut turpis dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque dui risus, tincidunt at odio ut, ultrices dignissim ipsum. Cras ultrices erat nec leo luctus varius. Nulla sollicitudin tincidunt nulla, ut porta mauris volutpat vitae. Suspendisse ornare dolor sit amet massa venenatis pulvinar.</p>
</div>
</div><!-- /example -->
{% highlight html %}
<nav id="myNavmenu" class="navmenu navmenu-default navmenu-fixed-left offcanvas" role="navigation">
<a class="navmenu-brand" href="#">Brand</a>
<ul class="nav navmenu-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</nav>
<div class="navbar navbar-default navbar-fixed-top">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target="#myNavmenu" data-canvas="body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
{% endhighlight %}
<div class="bs-callout bs-callout-info">
<h4>Examples</h4>
<p>For better understanding, have a look at the <a href="../examples/navmenu/">off canvas slide in menu</a>, <a href="../examples/navmenu-push/">off canvas push menu</a> and <a href="../examples/navmenu-reveal/">off canvas reveal menu</a> exapmles.</p>
</div>
<hr class="bs-docs-separator">
<h2 id="offcanvas-usage">Usage</h2>
<p>Add <code>.offcanvas</code> to hide an element. Alternatively add <code>.offcanvas-*</code> to hide an element up to a specific viewport width. Adding the <code>.offcanvas</code> class is not required. You may also hide an element by any other means.</p>
<p>The effect works best for elements positioned to the top, bottom, left or right of the window, either with absolute or fixed positioning.</p>
<p>When shown, the plugin adds <code>.canvas-slid</code> to the element that has slid.</p>
<h3>Via data attributes</h3>
<p>Add <code>data-toggle="offcanvas"</code> and a <code>data-target</code> to control, assigning it to show and hide the target element. The <code>data-target</code> attribute accepts a CSS selector to apply the collapse to.</p>
<p>Optionally add a <code>data-canvas</code> attribute to slide a canvas instead of only the target element. For a push menu set <code>data-canvas="body"</code>.
<h3>Via JavaScript</h3>
<p>Call the input mask via javascript:</p>
{% highlight js %}
$('.navmenu').offcanvas()
{% endhighlight %}
<h3>Options</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 50px;">type</th>
<th style="width: 100px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>canvas</td>
<td>string</td>
<td>false</td>
<td>If set, the canvas will be moved on show and hide instead of the target element. This creates alternative effects.</td>
</tr>
<tr>
<td>toggle</td>
<td>boolean</td>
<td>true</td>
<td>Toggles the off canvas element on invocation</td>
</tr>
<tr>
<td>placement</td>
<td>string</td>
<td>'auto'</td>
<td>Where to position the element at the start of the animation. For example, if placement is "left", the element will slide from left to right. The default option "auto" guesses the placement based on position and dimension.</td>
</tr>
<tr>
<td>autohide</td>
<td>boolean</td>
<td>true</td>
<td>Hide the off canvas element if clicked anywhere other that the element.</td>
</tr>
<tr>
<td>recalc</td>
<td>boolean</td>
<td>true</td>
<td>Calculate if off canvas should be disabled for this viewport width on window resize. If your elements always gets hidden on window resize, try setting this to false.</td>
</tr>
</tbody>
</table>
<div class="bs-callout bs-callout-danger">
<h4>Graceful degradation</h4>
<p>For browsers that don't support transform (mainly IE8), the <code>target</code> option is ignored. In that case, the plugin will always slide the target element. In that case <code>.canvas-slid</code> will be added to the target element instead.</p>
</div>
<h3>Methods</h3>
<h4>.offcanvas(options)</h4>
<p>Initializes the off canvas element with an optional options.</p>
<h4>.offcanvas('toggle')</h4>
<p>Toggles an off canvas element to shown or hidden.</p>
<h4>.offcanvas('show')</h4>
<p>Shows an off canvas element.</p>
<h4>.offcanvas('hide')</h4>
<p>Hides an off canvas element.</p>
<h3>Events</h3>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>show.bs.offcanvas</td>
<td>This event fires immediately when the show instance method is called.</td>
</tr>
<tr>
<td>shown.bs.offcanvas</td>
<td>This event is fired when the target has been made visible to the user (will wait for CSS transitions to complete).</td>
</tr>
<tr>
<td>hide.bs.offcanvas</td>
<td>This event is fired immediately when the hide instance method has been called.</td>
</tr>
<tr>
<td>hidden.bs.offcanvas</td>
<td>This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete).</td>
</tr>
</tbody>
</table>
</div><!-- ./bs-table-responsive -->
</div>
<!-- Row link
================================================== -->
<div class="bs-docs-section bs-jasny">
<div class="page-header">
<h1 id="rowlink">Row link <small>rowlink.js</small></h1>
</div>
<h2 id="rowlink-examples">Example</h2>
<p>This plugin turns a table row into a clickable link.</p>
<div class="bs-example">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr><th>Name</th><th>Description</th><th>Actions</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<tr><td><a href="#inputmask">Input mask</a></td><td>Input masks can be used to force the user to enter data conform a specific format.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="http://www.jasny.net/" target="_blank">jasny.net</a></td><td>Shared knowledge of Arnold Daniels aka Jasny.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="#rowlinkModal" data-toggle="modal">Launch modal</a></td><td>Toggle a modal via JavaScript by clicking this row.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
</tbody>
</table>
</div>
<div id="rowlinkModal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Rowlink Modal</h4>
</div>
<div class="modal-body">
<p>This modal proves that JavaScript events are triggered correctly by rowlink.</p>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% highlight html %}
<table class="table table-striped table-bordered table-hover">
<thead>
<tr><th>Name</th><th>Description</th><th>Actions</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<tr><td><a href="#inputmask">Input mask</a></td><td>Input masks can be used to force the user to enter data conform a specific format.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="http://www.jasny.net/" target="_blank">jasny.net</a></td><td>Shared knowledge of Arnold Daniels aka Jasny.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="#rowlinkModal" data-toggle="modal">Launch modal</a></td><td>Toggle a modal via JavaScript by clicking this row.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
</tbody>
</table>
{% endhighlight %}
<hr class="bs-docs-separator">
<h2 id="rowlink-usage">Usage</h2>
<h3>Via data attributes</h3>
<p>Add class <code>.rowlink</code> and attribute <code>data-link="row"</code> to a <code>&lt;table&gt;</code> or <code>&lt;tbody&gt;</code> element. For other options append the name to <code>data-</code>, as in <code>data-target="a.mainlink"</code> A cell can be excluded by adding the <code>.rowlink-skip</code> class to the <code>&lt;td&gt;</code>.</p>
<h3>Via JavaScript</h3>
<p>Call the input mask via javascript:</p>
{% highlight js %}
$('tbody.rowlink').rowlink()
{% endhighlight %}
<h3>Options</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 50px;">type</th>
<th style="width: 100px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>target</td>
<td>string</td>
<td>'a'</td>
<td>A jquery selector string, to select the link element within each row.</td>
</tr>
</tbody>
</table>
<h3>Methods</h3>
<h4>.rowlink(options)</h4>
<p>Makes the rows of a table or tbody clickable.</p>
</div>
<!-- Input mask
================================================== -->
<div class="bs-docs-section bs-jasny">
<div class="page-header">
<h1 id="inputmask">Input mask <small>inputmask.js</small></h1>
</div>
<h2 id="inputmask-examples">Example</h2>
<p>Input masks can be used to force the user to enter data conform a specific format. Unlike validation, the user can't enter any other key than the ones specified by the mask.</p>
<div class="bs-example">
<input type="text" class="form-control" data-mask="999-99-999-9999-9" placeholder="ISBN">
</div>
{% highlight html %}
<input type="text" class="form-control" data-mask="999-99-999-9999-9" placeholder="ISBN">
{% endhighlight %}
<hr class="bs-docs-separator">
<h2 id="inputmask-usage">Usage</h2>
<h3>Via data attributes</h3>
<p>Add data attributes to register an element with inputmask functionality as shown in the example above.</p>
<h3>Via JavaScript</h3>
<p>Call the input mask via javascript:</p>
{% highlight js %}
$('.inputmask').inputmask({
mask: '999-99-999-9999-9'
})
{% endhighlight %}
<h3>Options</h3>
<p>Options can be passed via data attributes or JavaScript. For data attributes, append the option name to <code>data-</code>, as in <code>data-mask="999-99-999-9999-9"</code>.</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 50px;">type</th>
<th style="width: 100px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>mask</td>
<td>string</td>
<td>''</td>
<td>A string of formatting and literal characters, defining the input mask (see below).</td>
</tr>
<tr>
<td>placeholder</td>
<td>string</td>
<td>'_'</td>
<td>The character that is displayed where something needs to be typed.</td>
</tr>
</tbody>
</table>
</div>
<h3>Format</h3>
<p>Each typed character needs to match exactly one character in the <code>mask</code> option.</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr><th>Character</th><th>Description</th></tr>
</thead>
<tbody>
<tr><td>9</td><td>Number</td></tr>
<tr><td>a</td><td>Letter</td></tr>
<tr><td>?</td><td>Alphanumeric</td></tr>
<tr><td>*</td><td>Any character</td></tr>
</tbody>
</table>
</div>
<h3>Methods</h3>
<h4>.inputmask(options)</h4>
<p>Initializes an input element with an input mask.</p>
</div>
<!-- File input
================================================== -->
<div class="bs-docs-section bs-jasny">
<div class="page-header">
<h1 id="fileinput">File input <small>fileinput.js</small></h1>
</div>
<h2 id="fileinput-examples">Examples</h2>
<p>The file input plugin allows you to create a visually appealing file or image input widgets.</p>
<h3>File input widgets</h3>
<div class="bs-example">
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="input-group">
<div class="form-control" data-trigger="fileinput"><i class="glyphicon glyphicon-file fileinput-exists"></i> <span class="fileinput-filename"></span></div>
<span class="input-group-addon btn btn-default btn-file"><span class="fileinput-new">Select file</span><span class="fileinput-exists">Change</span><input type="file"></span>
<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
</div>
{% highlight html %}
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="input-group">
<div class="form-control" data-trigger="fileinput"><i class="glyphicon glyphicon-file fileinput-exists"></i> <span class="fileinput-filename"></span></div>
<span class="input-group-addon btn btn-default btn-file"><span class="fileinput-new">Select file</span><span class="fileinput-exists">Change</span><input type="file" name="..."></span>
<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
{% endhighlight %}
<div class="bs-example">
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn btn-default btn-file"><span class="fileinput-new">Select file</span><span class="fileinput-exists">Change</span><input type="file"></span>
<span class="fileinput-filename"></span>
<a href="#" class="close fileinput-exists" data-dismiss="fileinput" style="float: none">&times;</a>
</div>
</div>
{% highlight html %}
<div class="fileinput fileinput-new" data-provides="fileinput">
<span class="btn btn-default btn-file"><span class="fileinput-new">Select file</span><span class="fileinput-exists">Change</span><input type="file" name="..."></span>
<span class="fileinput-filename"></span>
<a href="#" class="close fileinput-exists" data-dismiss="fileinput" style="float: none">&times;</a>
</div>
{% endhighlight %}
<h3>Image upload widgets</h3>
<p>When uploading an image, it's possible to show a thumbnail instead of the filename.</p>
<div class="bs-example">
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-preview thumbnail" data-trigger="fileinput" style="width: 200px; height: 150px;"></div>
<div>
<span class="btn btn-default btn-file"><span class="fileinput-new">Select image</span><span class="fileinput-exists">Change</span><input type="file"></span>
<a href="#" class="btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
</div>
{% highlight html %}
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-preview thumbnail" data-trigger="fileinput" style="width: 200px; height: 150px;"></div>
<div>
<span class="btn btn-default btn-file"><span class="fileinput-new">Select image</span><span class="fileinput-exists">Change</span><input type="file" name="..."></span>
<a href="#" class="btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
{% endhighlight %}
<div class="bs-example">
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
<img data-src="holder.js/100%x100%" alt="Generic placeholder thumbnail" src="data:image/png;base64,">
</div>
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;"></div>
<div>
<span class="btn btn-default btn-file"><span class="fileinput-new">Select image</span><span class="fileinput-exists">Change</span><input type="file"></span>
<a href="#" class="btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
</div>
{% highlight html %}
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
<img data-src="holder.js/100%x100%" alt="...">
</div>
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;"></div>
<div>
<span class="btn btn-default btn-file"><span class="fileinput-new">Select image</span><span class="fileinput-exists">Change</span><input type="file" name="..."></span>
<a href="#" class="btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a>
</div>
</div>
{% endhighlight %}
<div class="bs-callout bs-callout-warning">
<p>Image preview only works in IE10+, FF3.6+, Safari6.0+, Chrome6.0+ and Opera11.1+. In older browsers the filename is shown instead.</p>
</div>
<hr class="bs-docs-separator">
<h2 id="fileinput-usage">Usage</h2>
<p>Add <code>.fileinput</code> to the container. Elements inside the container with <code>.fileinput-new</code> and <code>.fileinput-exists</code> are shown or hidden based on the current state. A preview of the selected file is placed in <code>.fileinput-preview</code>. The text of <code>.fileinput-filename</code> gets set to the name of the selected file.</p>
<p>The file input widget should be placed in a regular <code>&lt;form&gt;</code> replacing a standard <code>&lt;input type="file"&gt;</code>. The server side code should handle the file upload as normal.</p>
<h3>Via data attributes</h3>
<p>Add <code>data-provides="fileinput"</code> to the <code>.fileinput</code> element. Implement a button to clear the file with <code>data-dismiss="fileinput"</code>. Add <code>data-trigger="fileinput"</code> to any element within the <code>.fileinput</code> widget to trigger the file dialog.</p>
<h3>Via JavaScript</h3>
<pre class="prettyprint linenums">$('.fileinput').fileinput()</pre>
<h3>Layout</h3>
<p>Using the given elements, you can layout the upload widget the way you want, either with a fixed <code>width</code> and <code>height</code> or with <code>max-width</code> and <code>max-height</code>.</p>
<h3>Options</h3>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 50px;">type</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>string</td>
<td>Use this option instead of setting the <code>name</code> attribute on the <code>&lt;input&gt;</code> element to prevent it from being part of the post data when not changed.</td>
</tr>
</tbody>
</table>
</div>
<h3>Methods</h3>
<h4>.fileinput(options)</h4>
<p>Initializes a file upload widget.</p>
<h4>.fileinput('clear')</h4>
<p>Clear the selected file.</p>
<h4>.fileinput('reset')</h4>
<p>Reset the form element to the original value.</p>
<h3>Events</h3>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 150px;">Event Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>change.bs.fileinput</td>
<td>This event is fired after a file is selected.</td>
</tr>
<tr>
<td>clear.bs.fileinput</td>
<td>This event is fired when the file input is cleared.</td>
</tr>
<tr>
<td>reset.bs.fileinput</td>
<td>This event is fired when the file input is reset.</td>
</tr>
</tbody>
</table>
</div><!-- ./bs-table-responsive -->
</div>

16
grunt/.jshintrc Normal file
View File

@@ -0,0 +1,16 @@
{
"asi": false,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 2,
"newcap": true,
"noarg": true,
"nonbsp": true,
"quotmark": "single",
"undef": true,
"strict": true,
"trailing": true,
"node" : true
}

236
grunt/bs-lessdoc-parser.js Normal file
View File

@@ -0,0 +1,236 @@
/*!
* Bootstrap Grunt task for parsing Less docstrings
* http://getbootstrap.com
* Copyright 2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var markdown = require('markdown').markdown;
function markdown2html(markdownString) {
// the slice removes the <p>...</p> wrapper output by Markdown processor
return markdown.toHTML(markdownString.trim()).slice(3, -4);
}
/*
Mini-language:
//== This is a normal heading, which starts a section. Sections group variables together.
//## Optional description for the heading
//=== This is a subheading.
//** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `<html>` stuff.
@foo: #ffff;
//-- This is a heading for a section whose variables shouldn't be customizable
All other lines are ignored completely.
*/
var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/;
var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/;
var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/;
var SECTION_DOCSTRING = /^[/]{2}#{2}(.*)$/;
var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]+);[ ]*$/;
var VAR_DOCSTRING = /^[/]{2}[*]{2}(.*)$/;
function Section(heading, customizable) {
this.heading = heading.trim();
this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
this.customizable = customizable;
this.docstring = null;
this.subsections = [];
}
Section.prototype.addSubSection = function (subsection) {
this.subsections.push(subsection);
};
function SubSection(heading) {
this.heading = heading.trim();
this.id = this.heading.replace(/\s+/g, '-').toLowerCase();
this.variables = [];
}
SubSection.prototype.addVar = function (variable) {
this.variables.push(variable);
};
function VarDocstring(markdownString) {
this.html = markdown2html(markdownString);
}
function SectionDocstring(markdownString) {
this.html = markdown2html(markdownString);
}
function Variable(name, defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
this.docstring = null;
}
function Tokenizer(fileContent) {
this._lines = fileContent.split('\n');
this._next = undefined;
}
Tokenizer.prototype.unshift = function (token) {
if (this._next !== undefined) {
throw new Error('Attempted to unshift twice!');
}
this._next = token;
};
Tokenizer.prototype._shift = function () {
// returning null signals EOF
// returning undefined means the line was ignored
if (this._next !== undefined) {
var result = this._next;
this._next = undefined;
return result;
}
if (this._lines.length <= 0) {
return null;
}
var line = this._lines.shift();
var match = null;
match = SUBSECTION_HEADING.exec(line);
if (match !== null) {
return new SubSection(match[1]);
}
match = CUSTOMIZABLE_HEADING.exec(line);
if (match !== null) {
return new Section(match[1], true);
}
match = UNCUSTOMIZABLE_HEADING.exec(line);
if (match !== null) {
return new Section(match[1], false);
}
match = SECTION_DOCSTRING.exec(line);
if (match !== null) {
return new SectionDocstring(match[1]);
}
match = VAR_DOCSTRING.exec(line);
if (match !== null) {
return new VarDocstring(match[1]);
}
var commentStart = line.lastIndexOf('//');
var varLine = (commentStart === -1) ? line : line.slice(0, commentStart);
match = VAR_ASSIGNMENT.exec(varLine);
if (match !== null) {
return new Variable(match[1], match[2]);
}
return undefined;
};
Tokenizer.prototype.shift = function () {
while (true) {
var result = this._shift();
if (result === undefined) {
continue;
}
return result;
}
};
function Parser(fileContent) {
this._tokenizer = new Tokenizer(fileContent);
}
Parser.prototype.parseFile = function () {
var sections = [];
while (true) {
var section = this.parseSection();
if (section === null) {
if (this._tokenizer.shift() !== null) {
throw new Error('Unexpected unparsed section of file remains!');
}
return sections;
}
sections.push(section);
}
};
Parser.prototype.parseSection = function () {
var section = this._tokenizer.shift();
if (section === null) {
return null;
}
if (!(section instanceof Section)) {
throw new Error('Expected section heading; got: ' + JSON.stringify(section));
}
var docstring = this._tokenizer.shift();
if (docstring instanceof SectionDocstring) {
section.docstring = docstring;
}
else {
this._tokenizer.unshift(docstring);
}
this.parseSubSections(section);
return section;
};
Parser.prototype.parseSubSections = function (section) {
while (true) {
var subsection = this.parseSubSection();
if (subsection === null) {
if (section.subsections.length === 0) {
// Presume an implicit initial subsection
subsection = new SubSection('');
this.parseVars(subsection);
}
else {
break;
}
}
section.addSubSection(subsection);
}
if (section.subsections.length === 1 && !(section.subsections[0].heading) && section.subsections[0].variables.length === 0) {
// Ignore lone empty implicit subsection
section.subsections = [];
}
};
Parser.prototype.parseSubSection = function () {
var subsection = this._tokenizer.shift();
if (subsection instanceof SubSection) {
this.parseVars(subsection);
return subsection;
}
this._tokenizer.unshift(subsection);
return null;
};
Parser.prototype.parseVars = function (subsection) {
while (true) {
var variable = this.parseVar();
if (variable === null) {
return;
}
subsection.addVar(variable);
}
};
Parser.prototype.parseVar = function () {
var docstring = this._tokenizer.shift();
if (!(docstring instanceof VarDocstring)) {
this._tokenizer.unshift(docstring);
docstring = null;
}
var variable = this._tokenizer.shift();
if (variable instanceof Variable) {
variable.docstring = docstring;
return variable;
}
this._tokenizer.unshift(variable);
return null;
};
module.exports = Parser;

View File

@@ -0,0 +1,31 @@
/* global btoa: true */
/*!
* Bootstrap Grunt task for generating raw-files.min.js for the Customizer
* http://getbootstrap.com
* Copyright 2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict';
var btoa = require('btoa');
var fs = require('fs');
function getFiles(type) {
var files = {};
fs.readdirSync(type)
.filter(function (path) {
return new RegExp('\\.' + type + '$').test(path);
})
.forEach(function (path) {
var fullPath = type + (path === 'variables.less' ? '/build/' : '/') + path;
files[path] = fs.readFileSync(fullPath, 'utf8');
});
return 'var __' + type + ' = ' + JSON.stringify(files) + '\n';
}
module.exports = function generateRawFilesJs(banner) {
if (!banner) {
banner = '';
}
var files = banner + getFiles('js') + getFiles('less');
fs.writeFileSync('docs/assets/js/raw-files.min.js', files);
};

28
grunt/shrinkwrap.js Normal file
View File

@@ -0,0 +1,28 @@
/*!
* Bootstrap Grunt task for generating npm-shrinkwrap.canonical.json
* http://getbootstrap.com
* Copyright 2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*
This Grunt task updates the npm-shrinkwrap.canonical.json file that's used as the key for Bootstrap's npm packages cache.
This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
*/
'use strict';
var canonicallyJsonStringify = require('canonical-json');
var NON_CANONICAL_FILE = 'npm-shrinkwrap.json';
var DEST_FILE = 'test-infra/npm-shrinkwrap.canonical.json';
function updateShrinkwrap(grunt) {
// Assumption: Non-canonical shrinkwrap already generated by prerequisite Grunt task
var shrinkwrapData = grunt.file.readJSON(NON_CANONICAL_FILE);
grunt.log.writeln('Deleting ' + NON_CANONICAL_FILE.cyan + '...');
grunt.file.delete(NON_CANONICAL_FILE);
// Output as Canonical JSON in correct location
grunt.file.write(DEST_FILE, canonicallyJsonStringify(shrinkwrapData));
grunt.log.writeln('File ' + DEST_FILE.cyan + ' updated.');
}
module.exports = updateShrinkwrap;

15
js/.jscs.json Normal file
View File

@@ -0,0 +1,15 @@
{
"disallowKeywords": ["with"],
"requireLeftStickedOperators": [","],
"disallowLeftStickedOperators": ["?", "+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"disallowRightStickedOperators": ["?", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="],
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~"],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"requireLineFeedAtFileEnd": true,
"requireRightStickedOperators": ["!"],
"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true },
"validateLineBreaks": "LF"
}

14
js/.jshintrc Normal file
View File

@@ -0,0 +1,14 @@
{
"asi" : true,
"boss" : true,
"browser" : true,
"curly" : false,
"debug" : true,
"devel" : true,
"eqeqeq" : false,
"eqnull" : true,
"expr" : true,
"laxbreak" : true,
"laxcomma" : true,
"validthis": true
}

191
js/fileinput.js Normal file
View File

@@ -0,0 +1,191 @@
/* ===========================================================
* Bootstrap: fileinput.js v3.1.0
* http://jasny.github.com/bootstrap/javascript/#fileinput
* ===========================================================
* Copyright 2012-2014 Arnold Daniels
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
+function ($) { "use strict";
var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
// FILEUPLOAD PUBLIC CLASS DEFINITION
// =================================
var Fileinput = function (element, options) {
this.$element = $(element)
this.$input = this.$element.find(':file')
if (this.$input.length === 0) return
this.name = this.$input.attr('name') || options.name
this.$hidden = this.$element.find('input[type=hidden][name="' + this.name + '"]')
if (this.$hidden.length === 0) {
this.$hidden = $('<input type="hidden" />')
this.$element.prepend(this.$hidden)
}
this.$preview = this.$element.find('.fileinput-preview')
var height = this.$preview.css('height')
if (this.$preview.css('display') != 'inline' && height != '0px' && height != 'none') this.$preview.css('line-height', height)
this.original = {
exists: this.$element.hasClass('fileinput-exists'),
preview: this.$preview.html(),
hiddenVal: this.$hidden.val()
}
this.listen()
}
Fileinput.prototype.listen = function() {
this.$input.on('change.bs.fileinput', $.proxy(this.change, this))
$(this.$input[0].form).on('reset.bs.fileinput', $.proxy(this.reset, this))
this.$element.find('[data-trigger="fileinput"]').on('click.bs.fileinput', $.proxy(this.trigger, this))
this.$element.find('[data-dismiss="fileinput"]').on('click.bs.fileinput', $.proxy(this.clear, this))
},
Fileinput.prototype.change = function(e) {
if (e.target.files === undefined) e.target.files = e.target && e.target.value ? [ {name: e.target.value.replace(/^.+\\/, '')} ] : []
if (e.target.files.length === 0) return
this.$hidden.val('')
this.$hidden.attr('name', '')
this.$input.attr('name', this.name)
var file = e.target.files[0]
if (this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
var reader = new FileReader()
var preview = this.$preview
var element = this.$element
reader.onload = function(re) {
var $img = $('<img>') // .attr('src', re.target.result)
$img[0].src = re.target.result
e.target.files[0].result = re.target.result
element.find('.fileinput-filename').text(file.name)
// if parent has max-height, using `(max-)height: 100%` on child doesn't take padding and border into account
if (preview.css('max-height') != 'none') $img.css('max-height', parseInt(preview.css('max-height'), 10) - parseInt(preview.css('padding-top'), 10) - parseInt(preview.css('padding-bottom'), 10) - parseInt(preview.css('border-top'), 10) - parseInt(preview.css('border-bottom'), 10))
preview.html($img)
element.addClass('fileinput-exists').removeClass('fileinput-new')
element.trigger('change.bs.fileinput', e.target.files)
}
reader.readAsDataURL(file)
} else {
this.$element.find('.fileinput-filename').text(file.name)
this.$preview.text(file.name)
this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
this.$element.trigger('change.bs.fileinput')
}
},
Fileinput.prototype.clear = function(e) {
if (e) e.preventDefault()
this.$hidden.val('')
this.$hidden.attr('name', this.name)
this.$input.attr('name', '')
//ie8+ doesn't support changing the value of input with type=file so clone instead
if (isIE) {
var inputClone = this.$input.clone(true);
this.$input.after(inputClone);
this.$input.remove();
this.$input = inputClone;
} else {
this.$input.val('')
}
this.$preview.html('')
this.$element.find('.fileinput-filename').text('')
this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
if (e !== false) {
this.$input.trigger('change')
this.$element.trigger('clear.bs.fileinput')
}
},
Fileinput.prototype.reset = function() {
this.clear(false)
this.$hidden.val(this.original.hiddenVal)
this.$preview.html(this.original.preview)
this.$element.find('.fileinput-filename').text('')
if (this.original.exists) this.$element.addClass('fileinput-exists').removeClass('fileinput-new')
else this.$element.addClass('fileinput-new').removeClass('fileinput-exists')
this.$element.trigger('reset.bs.fileinput')
},
Fileinput.prototype.trigger = function(e) {
this.$input.trigger('click')
e.preventDefault()
}
// FILEUPLOAD PLUGIN DEFINITION
// ===========================
var old = $.fn.fileinput
$.fn.fileinput = function (options) {
return this.each(function () {
var $this = $(this),
data = $this.data('fileinput')
if (!data) $this.data('fileinput', (data = new Fileinput(this, options)))
if (typeof options == 'string') data[options]()
})
}
$.fn.fileinput.Constructor = Fileinput
// FILEINPUT NO CONFLICT
// ====================
$.fn.fileinput.noConflict = function () {
$.fn.fileinput = old
return this
}
// FILEUPLOAD DATA-API
// ==================
$(document).on('click.fileinput.data-api', '[data-provides="fileinput"]', function (e) {
var $this = $(this)
if ($this.data('fileinput')) return
$this.fileinput($this.data())
var $target = $(e.target).closest('[data-dismiss="fileinput"],[data-trigger="fileinput"]');
if ($target.length > 0) {
e.preventDefault()
$target.trigger('click.bs.fileinput')
}
})
}(window.jQuery);

360
js/inputmask.js Normal file
View File

@@ -0,0 +1,360 @@
/* ===========================================================
* Bootstrap: inputmask.js v3.1.0
* http://jasny.github.io/bootstrap/javascript/#inputmask
*
* Based on Masked Input plugin by Josh Bush (digitalbush.com)
* ===========================================================
* Copyright 2012-2014 Arnold Daniels
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
+function ($) { "use strict";
var isIphone = (window.orientation !== undefined)
var isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1
var isIE = window.navigator.appName == 'Microsoft Internet Explorer'
// INPUTMASK PUBLIC CLASS DEFINITION
// =================================
var Inputmask = function (element, options) {
if (isAndroid) return // No support because caret positioning doesn't work on Android
this.$element = $(element)
this.options = $.extend({}, Inputmask.DEFAULS, options)
this.mask = String(this.options.mask)
this.init()
this.listen()
this.checkVal() //Perform initial check for existing values
}
Inputmask.DEFAULS = {
mask: "",
placeholder: "_",
definitions: {
'9': "[0-9]",
'a': "[A-Za-z]",
'?': "[A-Za-z0-9]",
'*': "."
}
}
Inputmask.prototype.init = function() {
var defs = this.options.definitions
var len = this.mask.length
this.tests = []
this.partialPosition = this.mask.length
this.firstNonMaskPos = null
$.each(this.mask.split(""), $.proxy(function(i, c) {
if (c == '?') {
len--
this.partialPosition = i
} else if (defs[c]) {
this.tests.push(new RegExp(defs[c]))
if (this.firstNonMaskPos === null)
this.firstNonMaskPos = this.tests.length - 1
} else {
this.tests.push(null)
}
}, this))
this.buffer = $.map(this.mask.split(""), $.proxy(function(c, i) {
if (c != '?') return defs[c] ? this.options.placeholder : c
}, this))
this.focusText = this.$element.val()
this.$element.data("rawMaskFn", $.proxy(function() {
return $.map(this.buffer, function(c, i) {
return this.tests[i] && c != this.options.placeholder ? c : null
}).join('')
}, this))
}
Inputmask.prototype.listen = function() {
if (this.$element.attr("readonly")) return
var pasteEventName = (isIE ? 'paste' : 'input') + ".mask"
this.$element
.on("unmask.bs.inputmask", $.proxy(this.unmask, this))
.on("focus.bs.inputmask", $.proxy(this.focusEvent, this))
.on("blur.bs.inputmask", $.proxy(this.blurEvent, this))
.on("keydown.bs.inputmask", $.proxy(this.keydownEvent, this))
.on("keypress.bs.inputmask", $.proxy(this.keypressEvent, this))
.on(pasteEventName, $.proxy(this.pasteEvent, this))
}
//Helper Function for Caret positioning
Inputmask.prototype.caret = function(begin, end) {
if (this.$element.length === 0) return
if (typeof begin == 'number') {
end = (typeof end == 'number') ? end : begin
return this.$element.each(function() {
if (this.setSelectionRange) {
this.setSelectionRange(begin, end)
} else if (this.createTextRange) {
var range = this.createTextRange()
range.collapse(true)
range.moveEnd('character', end)
range.moveStart('character', begin)
range.select()
}
})
} else {
if (this.$element[0].setSelectionRange) {
begin = this.$element[0].selectionStart
end = this.$element[0].selectionEnd
} else if (document.selection && document.selection.createRange) {
var range = document.selection.createRange()
begin = 0 - range.duplicate().moveStart('character', -100000)
end = begin + range.text.length
}
return {
begin: begin,
end: end
}
}
}
Inputmask.prototype.seekNext = function(pos) {
var len = this.mask.length
while (++pos <= len && !this.tests[pos]);
return pos
}
Inputmask.prototype.seekPrev = function(pos) {
while (--pos >= 0 && !this.tests[pos]);
return pos
}
Inputmask.prototype.shiftL = function(begin,end) {
var len = this.mask.length
if (begin < 0) return
for (var i = begin, j = this.seekNext(end); i < len; i++) {
if (this.tests[i]) {
if (j < len && this.tests[i].test(this.buffer[j])) {
this.buffer[i] = this.buffer[j]
this.buffer[j] = this.options.placeholder
} else
break
j = this.seekNext(j)
}
}
this.writeBuffer()
this.caret(Math.max(this.firstNonMaskPos, begin))
}
Inputmask.prototype.shiftR = function(pos) {
var len = this.mask.length
for (var i = pos, c = this.options.placeholder; i < len; i++) {
if (this.tests[i]) {
var j = this.seekNext(i)
var t = this.buffer[i]
this.buffer[i] = c
if (j < len && this.tests[j].test(t))
c = t
else
break
}
}
},
Inputmask.prototype.unmask = function() {
this.$element
.unbind(".mask")
.removeData("inputmask")
}
Inputmask.prototype.focusEvent = function() {
this.focusText = this.$element.val()
var len = this.mask.length
var pos = this.checkVal()
this.writeBuffer()
var that = this
var moveCaret = function() {
if (pos == len)
that.caret(0, pos)
else
that.caret(pos)
}
moveCaret()
setTimeout(moveCaret, 50)
}
Inputmask.prototype.blurEvent = function() {
this.checkVal()
if (this.$element.val() !== this.focusText)
this.$element.trigger('change')
}
Inputmask.prototype.keydownEvent = function(e) {
var k = e.which
//backspace, delete, and escape get special treatment
if (k == 8 || k == 46 || (isIphone && k == 127)) {
var pos = this.caret(),
begin = pos.begin,
end = pos.end
if (end - begin === 0) {
begin = k != 46 ? this.seekPrev(begin) : (end = this.seekNext(begin - 1))
end = k == 46 ? this.seekNext(end) : end
}
this.clearBuffer(begin, end)
this.shiftL(begin, end - 1)
return false
} else if (k == 27) {//escape
this.$element.val(this.focusText)
this.caret(0, this.checkVal())
return false
}
}
Inputmask.prototype.keypressEvent = function(e) {
var len = this.mask.length
var k = e.which,
pos = this.caret()
if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
return true
} else if (k) {
if (pos.end - pos.begin !== 0) {
this.clearBuffer(pos.begin, pos.end)
this.shiftL(pos.begin, pos.end - 1)
}
var p = this.seekNext(pos.begin - 1)
if (p < len) {
var c = String.fromCharCode(k)
if (this.tests[p].test(c)) {
this.shiftR(p)
this.buffer[p] = c
this.writeBuffer()
var next = this.seekNext(p)
this.caret(next)
}
}
return false
}
}
Inputmask.prototype.pasteEvent = function() {
var that = this
setTimeout(function() {
that.caret(that.checkVal(true))
}, 0)
}
Inputmask.prototype.clearBuffer = function(start, end) {
var len = this.mask.length
for (var i = start; i < end && i < len; i++) {
if (this.tests[i])
this.buffer[i] = this.options.placeholder
}
}
Inputmask.prototype.writeBuffer = function() {
return this.$element.val(this.buffer.join('')).val()
}
Inputmask.prototype.checkVal = function(allow) {
var len = this.mask.length
//try to place characters where they belong
var test = this.$element.val()
var lastMatch = -1
for (var i = 0, pos = 0; i < len; i++) {
if (this.tests[i]) {
this.buffer[i] = this.options.placeholder
while (pos++ < test.length) {
var c = test.charAt(pos - 1)
if (this.tests[i].test(c)) {
this.buffer[i] = c
lastMatch = i
break
}
}
if (pos > test.length)
break
} else if (this.buffer[i] == test.charAt(pos) && i != this.partialPosition) {
pos++
lastMatch = i
}
}
if (!allow && lastMatch + 1 < this.partialPosition) {
this.$element.val("")
this.clearBuffer(0, len)
} else if (allow || lastMatch + 1 >= this.partialPosition) {
this.writeBuffer()
if (!allow) this.$element.val(this.$element.val().substring(0, lastMatch + 1))
}
return (this.partialPosition ? i : this.firstNonMaskPos)
}
// INPUTMASK PLUGIN DEFINITION
// ===========================
var old = $.fn.inputmask
$.fn.inputmask = function (options) {
return this.each(function () {
var $this = $(this)
var data = $this.data('inputmask')
if (!data) $this.data('inputmask', (data = new Inputmask(this, options)))
})
}
$.fn.inputmask.Constructor = Inputmask
// INPUTMASK NO CONFLICT
// ====================
$.fn.inputmask.noConflict = function () {
$.fn.inputmask = old
return this
}
// INPUTMASK DATA-API
// ==================
$(document).on('focus.bs.inputmask.data-api', '[data-mask]', function (e) {
var $this = $(this)
if ($this.data('inputmask')) return
$this.inputmask($this.data())
})
}(window.jQuery);

296
js/offcanvas.js Normal file
View File

@@ -0,0 +1,296 @@
/* ========================================================================
* Bootstrap: offcanvas.js v3.1.0
* http://jasny.github.io/bootstrap/javascript/#offcanvas
*
* Based on Boostrap collapse.js by Twitter, Inc.
* ========================================================================
* Copyright 2013-2014 Arnold Daniels
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================================== */
+function ($) { "use strict";
// OFFCANVAS PUBLIC CLASS DEFINITION
// =================================
var OffCanvas = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, OffCanvas.DEFAULTS, options)
this.state = null
if (this.options.recalc) {
this.calcClone()
$(window).on('resize', $.proxy(this.recalc, this))
}
if (this.options.autohide)
$(document).on('click', $.proxy(this.autohide, this))
if (this.options.toggle) this.toggle()
}
OffCanvas.DEFAULTS = {
toggle: true,
placement: 'left',
autohide: true,
recalc: true
}
OffCanvas.prototype.offset = function () {
switch (this.options.placement) {
case 'left':
case 'right': return this.$element.outerWidth()
case 'top':
case 'bottom': return this.$element.outerHeight()
}
}
OffCanvas.prototype.calcPlacement = function () {
var horizontal = $(window).width() / this.$element.width(),
vertical = $(window).height() / this.$element.height()
if (!this.$element.hasClass('in')) {
this.$element.css('visiblity', 'hidden !important').addClass('in')
}
var element = this.$element
function ab(a, b) {
if (element.css(b) === 'auto') return a
if (element.css(a) === 'auto') return b
var size_a = parseInt(element.css(a), 10),
size_b = parseInt(element.css(b), 10)
return size_a > size_b ? b : a
}
this.options.placement = horizontal > vertical ? ab('left', 'right') : ab('top', 'bottom')
if (this.$element.css('visibility') === 'hidden !important') {
this.$element.removeClass('in').css('visiblity', '')
}
}
OffCanvas.prototype.opposite = function (placement) {
switch (placement) {
case 'top': return 'bottom'
case 'left': return 'right'
case 'bottom': return 'top'
case 'right': return 'left'
}
}
OffCanvas.prototype.getCanvasElements = function() {
// Return a set containing the canvas plus all fixed elements
var canvas = this.options.canvas ? $(this.options.canvas) : this.$element
var fixed_elements = canvas.find('*').filter(function() {
return $(this).css('position') === 'fixed'
}).not(this.options.exclude)
return canvas.add(fixed_elements)
}
OffCanvas.prototype.slide = function (elements, offset, callback) {
// Use jQuery animation if CSS transitions aren't supported
if (!$.support.transition) {
var anim = {}
anim[this.options.placement] = "+=" + offset
return elements.animate(anim, 350, callback)
}
var placement = this.options.placement,
opposite = this.opposite(placement)
elements.each(function() {
if ($(this).css(placement) !== 'auto')
$(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
if ($(this).css(opposite) !== 'auto')
$(this).css(opposite, (parseInt($(this).css(opposite), 10) || 0) - offset)
})
this.$element
.one($.support.transition.end, callback)
.emulateTransitionEnd(350)
}
OffCanvas.prototype.disableScrolling = function() {
var bodyWidth = $('body').width()
var prop = 'padding-' + this.opposite(this.options.placement)
if ($('body').data('offcanvas-style') === undefined) $('body').data('offcanvas-style', $('body').attr('style'))
$('body').css('overflow', 'hidden')
if ($('body').width() > bodyWidth) {
var padding = parseInt($('body').css(prop), 10) + $('body').width() - bodyWidth
setTimeout(function() {
$('body').css(prop, padding)
}, 1)
}
}
OffCanvas.prototype.show = function () {
if (this.state) return
var startEvent = $.Event('show.bs.offcanvas')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
if (this.options.placement === 'auto') this.calcPlacement()
this.state = 'sliding'
var elements = this.getCanvasElements()
var offset = this.offset(),
placement = this.options.placement,
opposite = this.opposite(placement)
elements.addClass('canvas-sliding').each(function() {
$(this).data('offcanvas-style', $(this).attr('style') || '')
if ($(this).css('position') === 'static') $(this).css('position', 'relative')
if (($(this).css(placement) === 'auto' || $(this).css(placement) === '0px') &&
($(this).css(opposite) === 'auto' || $(this).css(opposite) === '0px')) {
$(this).css(placement, 0)
}
})
if (elements.index(this.$element) !== -1) this.$element.css(placement, -1 * offset)
this.disableScrolling()
var complete = function () {
this.state = 'slid'
elements.removeClass('canvas-sliding').addClass('canvas-slid')
this.$element.trigger('shown.bs.offcanvas')
}
setTimeout($.proxy(function() {
this.$element.addClass('in')
this.slide(elements, offset, $.proxy(complete, this))
}, this), 1)
}
OffCanvas.prototype.hide = function (fast) {
if (this.state !== 'slid') return
var startEvent = $.Event('hide.bs.offcanvas')
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
this.state = 'sliding'
var elements = $('.canvas-slid')
var offset = -1 * this.offset()
var complete = function () {
this.state = null
this.$element.removeClass('in')
elements.removeClass('canvas-sliding')
elements.add('body').each(function() {
$(this).attr('style', $(this).data('offcanvas-style')).removeData('offcanvas-style')
})
this.$element.trigger('hidden.bs.offcanvas')
}
elements.removeClass('canvas-slid').addClass('canvas-sliding')
setTimeout($.proxy(function() {
this.slide(elements, offset, $.proxy(complete, this))
}, this), 1)
}
OffCanvas.prototype.toggle = function () {
if (this.state === 'sliding') return
this[this.state === 'slid' ? 'hide' : 'show']()
}
OffCanvas.prototype.calcClone = function() {
this.$calcClone = this.$element.clone()
.html('')
.addClass('offcanvas-clone').removeClass('in')
.appendTo($('body'))
}
OffCanvas.prototype.recalc = function () {
if (this.state() !== 'slid' || this.$calcClone.css('display') === 'none') return
var offset = -1 * this.offset()
var placement = this.options.placement
this.getCanvasElements().each(function() {
$(this).css(placement, (parseInt($(this).css(placement), 10) || 0) + offset)
}).removeClass('canvas-slid')
$('body').css('overflow', '')
this.$element.css(placement, '').removeClass('in canvas-slid')
}
OffCanvas.prototype.autohide = function (e) {
if ($(e.target).closest(this.$element).length === 0) this.hide()
}
// OFFCANVAS PLUGIN DEFINITION
// ==========================
var old = $.fn.offcanvas
$.fn.offcanvas = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.offcanvas')
var options = $.extend({}, OffCanvas.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('bs.offcanvas', (data = new OffCanvas(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.offcanvas.Constructor = OffCanvas
// OFFCANVAS NO CONFLICT
// ====================
$.fn.offcanvas.noConflict = function () {
$.fn.offcanvas = old
return this
}
// OFFCANVAS DATA-API
// =================
$(document).on('click.bs.offcanvas.data-api', '[data-toggle=offcanvas]', function (e) {
var $this = $(this), href
var target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
var $canvas = $(target)
var data = $canvas.data('bs.offcanvas')
var option = data ? 'toggle' : $this.data()
e.stopPropagation()
if (data) data.toggle()
else $canvas.offcanvas(option)
})
}(window.jQuery);

84
js/rowlink.js Normal file
View File

@@ -0,0 +1,84 @@
/* ============================================================
* Bootstrap: rowlink.js v3.1.0
* http://jasny.github.io/bootstrap/javascript/#rowlink
* ============================================================
* Copyright 2012-2014 Arnold Daniels
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
+function ($) { "use strict";
var Rowlink = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, Rowlink.DEFAULTS, options)
this.$element.on('click.bs.rowlink', 'td:not(.rowlink-skip)', $.proxy(this.click, this))
}
Rowlink.DEFAULTS = {
target: "a"
}
Rowlink.prototype.click = function(e) {
var target = $(e.currentTarget).closest('tr').find(this.options.target)[0]
if ($(e.target)[0] === target) return
e.preventDefault();
if (target.click) {
target.click()
} else if (document.createEvent) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
target.dispatchEvent(evt);
}
}
// ROWLINK PLUGIN DEFINITION
// ===========================
var old = $.fn.rowlink
$.fn.rowlink = function (options) {
return this.each(function () {
var $this = $(this)
var data = $this.data('rowlink')
if (!data) $this.data('rowlink', (data = new Rowlink(this, options)))
})
}
$.fn.rowlink.Constructor = Rowlink
// ROWLINK NO CONFLICT
// ====================
$.fn.rowlink.noConflict = function () {
$.fn.rowlink = old
return this
}
// ROWLINK DATA-API
// ==================
$(document).on('click.bs.rowlink.data-api', '[data-link="row"]', function (e) {
var $this = $(this)
if ($this.data('rowlink')) return
$this.rowlink($this.data())
$(e.target).trigger('click.bs.rowlink')
})
}(window.jQuery);

39
js/tests/index.html Normal file
View File

@@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bootstrap Plugin Test Suite</title>
<!-- jquery -->
<script src="vendor/jquery.js"></script>
<!-- qunit -->
<link rel="stylesheet" href="vendor/qunit.css" media="screen">
<script src="vendor/qunit.js"></script>
<script>
// See https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit
QUnit.done(function(results) {
window.global_test_results = results
})
</script>
<!-- plugin sources -->
<script>$.support.transition = false</script>
<script src="../../js/fileinput.js"></script>
<script src="../../js/inputmask.js"></script>
<script src="../../js/offcanvas.js"></script>
<script src="../../js/rowlink.js"></script>
<!-- unit tests -->
<script src="unit/fileinput.js"></script>
<script src="unit/inputmask.js"></script>
<script src="unit/offcanvas.js"></script>
<script src="unit/rowlink.js"></script>
</head>
<body>
<div>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</div>
</body>
</html>

View File

@@ -0,0 +1,20 @@
$(function () {
module('fileinput')
test('should provide no conflict', function () {
var fileinput = $.fn.fileinput.noConflict()
ok(!$.fn.fileinput, 'fileinput was set back to undefined (org value)')
$.fn.fileinput = fileinput
})
test('should be defined on jquery object', function () {
ok($(document.body).fileinput, 'fileinput method is defined')
})
test('should return element', function () {
ok($(document.body).fileinput()[0] == document.body, 'document.body returned')
})
// TODO: add fileinput tests
})

View File

@@ -0,0 +1,20 @@
$(function () {
module('inputmask')
test('should provide no conflict', function () {
var inputmask = $.fn.inputmask.noConflict()
ok(!$.fn.inputmask, 'inputmask was set back to undefined (org value)')
$.fn.inputmask = inputmask
})
test('should be defined on jquery object', function () {
ok($(document.body).inputmask, 'inputmask method is defined')
})
test('should return element', function () {
ok($(document.body).inputmask()[0] == document.body, 'document.body returned')
})
// TODO: add inputmask tests
})

View File

@@ -0,0 +1,20 @@
$(function () {
module('offcanvas')
test('should provide no conflict', function () {
var offcanvas = $.fn.offcanvas.noConflict()
ok(!$.fn.offcanvas, 'offcanvas was set back to undefined (org value)')
$.fn.offcanvas = offcanvas
})
test('should be defined on jquery object', function () {
ok($(document.body).offcanvas, 'offcanvas method is defined')
})
test('should return element', function () {
ok($(document.body).offcanvas()[0] == document.body, 'document.body returned')
})
// TODO: add offcanvas tests
})

69
js/tests/unit/phantom.js Normal file
View File

@@ -0,0 +1,69 @@
/*
* grunt-contrib-qunit
* http://gruntjs.com/
*
* Copyright (c) 2013 'Cowboy' Ben Alman, contributors
* Licensed under the MIT license.
*/
/*global QUnit:true, alert:true*/
(function () {
'use strict';
// Don't re-order tests.
QUnit.config.reorder = false
// Run tests serially, not in parallel.
QUnit.config.autorun = false
// Send messages to the parent PhantomJS process via alert! Good times!!
function sendMessage() {
var args = [].slice.call(arguments)
alert(JSON.stringify(args))
}
// These methods connect QUnit to PhantomJS.
QUnit.log = function (obj) {
// What is this I dont even
if (obj.message === '[object Object], undefined:undefined') { return }
// Parse some stuff before sending it.
var actual = QUnit.jsDump.parse(obj.actual)
var expected = QUnit.jsDump.parse(obj.expected)
// Send it.
sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
}
QUnit.testStart = function (obj) {
sendMessage('qunit.testStart', obj.name)
}
QUnit.testDone = function (obj) {
sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total)
}
QUnit.moduleStart = function (obj) {
sendMessage('qunit.moduleStart', obj.name)
}
QUnit.begin = function () {
sendMessage('qunit.begin')
console.log('Starting test suite')
console.log('================================================\n')
}
QUnit.moduleDone = function (opts) {
if (opts.failed === 0) {
console.log('\r\u2714 All tests passed in "' + opts.name + '" module')
} else {
console.log('\u2716 ' + opts.failed + ' tests failed in "' + opts.name + '" module')
}
sendMessage('qunit.moduleDone', opts.name, opts.failed, opts.passed, opts.total)
}
QUnit.done = function (opts) {
console.log('\n================================================')
console.log('Tests completed in ' + opts.runtime + ' milliseconds')
console.log(opts.passed + ' tests of ' + opts.total + ' passed, ' + opts.failed + ' failed.')
sendMessage('qunit.done', opts.failed, opts.passed, opts.total, opts.runtime)
}
}())

20
js/tests/unit/rowlink.js Normal file
View File

@@ -0,0 +1,20 @@
$(function () {
module('rowlink')
test('should provide no conflict', function () {
var rowlink = $.fn.rowlink.noConflict()
ok(!$.fn.rowlink, 'rowlink was set back to undefined (org value)')
$.fn.rowlink = rowlink
})
test('should be defined on jquery object', function () {
ok($(document.body).rowlink, 'rowlink method is defined')
})
test('should return element', function () {
ok($(document.body).rowlink()[0] == document.body, 'document.body returned')
})
// TODO: add rowlink tests
})

4
js/tests/vendor/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

245
js/tests/vendor/qunit.css vendored Normal file
View File

@@ -0,0 +1,245 @@
/*!
* QUnit 1.13.0
* http://qunitjs.com/
*
* Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-01-04T17:09Z
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
-webkit-border-top-right-radius: 5px;
-webkit-border-top-left-radius: 5px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-testrunner-toolbar label {
display: inline-block;
padding: 0 .5em 0 .1em;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
overflow: hidden;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
#qunit-modulefilter-container {
float: right;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests li .runtime {
float: right;
font-size: smaller;
}
.qunit-assert-list {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.qunit-collapsed {
display: none;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
padding: 5px;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #3c510c;
background-color: #fff;
border-left: 10px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

2210
js/tests/vendor/qunit.js vendored Normal file

File diff suppressed because it is too large Load Diff

297
less/.csscomb.json Normal file
View File

@@ -0,0 +1,297 @@
{
"always-semicolon": true,
"block-indent": 2,
"colon-space": true,
"color-case": "lower",
"color-shorthand": true,
"combinator-space": true,
"element-case": "lower",
"eof-newline": true,
"leading-zero": false,
"remove-empty-rulesets": true,
"rule-indent": 2,
"stick-brace": true,
"strip-spaces": true,
"unitless-zero": true,
"vendor-prefix-align": true,
"sort-order": [
[
"position",
"top",
"right",
"bottom",
"left",
"z-index",
"display",
"float",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
"-webkit-box-sizing",
"-moz-box-sizing",
"box-sizing",
"-webkit-appearance",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"overflow",
"overflow-x",
"overflow-y",
"-webkit-overflow-scrolling",
"-ms-overflow-x",
"-ms-overflow-y",
"-ms-overflow-style",
"clip",
"clear",
"font",
"font-family",
"font-size",
"font-style",
"font-weight",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"-webkit-hyphens",
"-moz-hyphens",
"hyphens",
"line-height",
"color",
"text-align",
"-webkit-text-align-last",
"-moz-text-align-last",
"-ms-text-align-last",
"text-align-last",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-decoration",
"text-indent",
"text-justify",
"text-outline",
"-ms-text-overflow",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"text-shadow",
"text-transform",
"text-wrap",
"-webkit-text-size-adjust",
"-ms-text-size-adjust",
"letter-spacing",
"-ms-word-break",
"word-break",
"word-spacing",
"-ms-word-wrap",
"word-wrap",
"-moz-tab-size",
"-o-tab-size",
"tab-size",
"white-space",
"vertical-align",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
"pointer-events",
"cursor",
"visibility",
"zoom",
"flex-direction",
"flex-order",
"flex-pack",
"flex-align",
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"-webkit-user-select",
"-moz-user-select",
"-ms-user-select",
"-o-user-select",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"background",
"background-color",
"background-image",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
"filter:progid:DXImageTransform.Microsoft.gradient",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
"filter",
"background-repeat",
"background-attachment",
"background-position",
"background-position-x",
"background-position-y",
"-webkit-background-clip",
"-moz-background-clip",
"background-clip",
"background-origin",
"-webkit-background-size",
"-moz-background-size",
"-o-background-size",
"background-size",
"border",
"border-color",
"border-style",
"border-width",
"border-top",
"border-top-color",
"border-top-style",
"border-top-width",
"border-right",
"border-right-color",
"border-right-style",
"border-right-width",
"border-bottom",
"border-bottom-color",
"border-bottom-style",
"border-bottom-width",
"border-left",
"border-left-color",
"border-left-style",
"border-left-width",
"border-radius",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"-webkit-border-image",
"-moz-border-image",
"-o-border-image",
"border-image",
"-webkit-border-image-source",
"-moz-border-image-source",
"-o-border-image-source",
"border-image-source",
"-webkit-border-image-slice",
"-moz-border-image-slice",
"-o-border-image-slice",
"border-image-slice",
"-webkit-border-image-width",
"-moz-border-image-width",
"-o-border-image-width",
"border-image-width",
"-webkit-border-image-outset",
"-moz-border-image-outset",
"-o-border-image-outset",
"border-image-outset",
"-webkit-border-image-repeat",
"-moz-border-image-repeat",
"-o-border-image-repeat",
"border-image-repeat",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"-webkit-box-shadow",
"-moz-box-shadow",
"box-shadow",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"opacity",
"-ms-interpolation-mode",
"-webkit-transition",
"-moz-transition",
"-ms-transition",
"-o-transition",
"transition",
"-webkit-transition-delay",
"-moz-transition-delay",
"-ms-transition-delay",
"-o-transition-delay",
"transition-delay",
"-webkit-transition-timing-function",
"-moz-transition-timing-function",
"-ms-transition-timing-function",
"-o-transition-timing-function",
"transition-timing-function",
"-webkit-transition-duration",
"-moz-transition-duration",
"-ms-transition-duration",
"-o-transition-duration",
"transition-duration",
"-webkit-transition-property",
"-moz-transition-property",
"-ms-transition-property",
"-o-transition-property",
"transition-property",
"-webkit-transform",
"-moz-transform",
"-ms-transform",
"-o-transform",
"transform",
"-webkit-transform-origin",
"-moz-transform-origin",
"-ms-transform-origin",
"-o-transform-origin",
"transform-origin",
"-webkit-animation",
"-moz-animation",
"-ms-animation",
"-o-animation",
"animation",
"-webkit-animation-name",
"-moz-animation-name",
"-ms-animation-name",
"-o-animation-name",
"animation-name",
"-webkit-animation-duration",
"-moz-animation-duration",
"-ms-animation-duration",
"-o-animation-duration",
"animation-duration",
"-webkit-animation-play-state",
"-moz-animation-play-state",
"-ms-animation-play-state",
"-o-animation-play-state",
"animation-play-state",
"-webkit-animation-timing-function",
"-moz-animation-timing-function",
"-ms-animation-timing-function",
"-o-animation-timing-function",
"animation-timing-function",
"-webkit-animation-delay",
"-moz-animation-delay",
"-ms-animation-delay",
"-o-animation-delay",
"animation-delay",
"-webkit-animation-iteration-count",
"-moz-animation-iteration-count",
"-ms-animation-iteration-count",
"-o-animation-iteration-count",
"animation-iteration-count",
"-webkit-animation-direction",
"-moz-animation-direction",
"-ms-animation-direction",
"-o-animation-direction",
"animation-direction"
]
]
}

20
less/.csslintrc Normal file
View File

@@ -0,0 +1,20 @@
{
"adjoining-classes": false,
"box-sizing": false,
"box-model": false,
"compatible-vendor-prefixes": false,
"fallback-colors": false,
"floats": false,
"font-sizes": false,
"gradients": false,
"important": false,
"known-properties": false,
"outline-none": false,
"qualified-headings": false,
"regex-selectors": false,
"shorthand": false,
"text-indent": false,
"unique-headings": false,
"universal-selector": false,
"unqualified-attributes": false
}

39
less/alerts-fixed.less Normal file
View File

@@ -0,0 +1,39 @@
// Fixed alerts
//
// Position to the top or bottom.
.alert-fixed-top,
.alert-fixed-bottom {
position: fixed;
width: 100%;
z-index: @zindex-alert-fixed;
border-radius: 0;
margin: 0;
left: 0;
@media (min-width: @alert-fixed-width) {
width: @alert-fixed-width;
left: 50%;
margin-left: (-1 * (@alert-fixed-width / 2));
}
}
.alert-fixed-top {
top: 0;
border-width: 0 0 1px 0;
@media (min-width: @alert-fixed-width) {
.border-bottom-radius(@alert-border-radius);
border-width: 0 1px 1px 1px;
}
}
.alert-fixed-bottom {
bottom: 0;
border-width: 1px 0 0 0;
@media (min-width: @alert-fixed-width) {
.border-top-radius(@alert-border-radius);
border-width: 1px 1px 0 1px;
}
}

View File

@@ -0,0 +1,4 @@
// Jasny Bootstrap with default variables
@import "variables.less";
@import "../jasny-bootstrap.less";

216
less/build/variables.less Normal file
View File

@@ -0,0 +1,216 @@
//
// These variables are used when Jasny Bootstrap is built
// without importing Twitter Bootstrap.
// --------------------------------------------------------
//-- Colors
//
//## Gray colors for use across Bootstrap.
@gray-darker: lighten(#000, 13.5%); // #222
@gray-dark: lighten(#000, 20%); // #333
@gray: lighten(#000, 33.5%); // #555
@gray-light: lighten(#000, 60%); // #999
@gray-lighter: lighten(#000, 93.5%); // #eee
//-- Typography
//
//## Font size and line-height.
@font-size-base: 14px;
@font-size-large: ceil((@font-size-base * 1.25)); // ~18px
@font-size-small: ceil((@font-size-base * 0.85)); // ~12px
//** Unit-less `line-height` for use in components like buttons.
@line-height-base: 1.428571429; // 20/14
//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
@line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px
//== Components
//
//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
@padding-base-vertical: 6px;
@padding-base-horizontal: 12px;
@padding-large-vertical: 10px;
@padding-large-horizontal: 16px;
@padding-small-vertical: 5px;
@padding-small-horizontal: 10px;
@padding-xs-vertical: 1px;
@padding-xs-horizontal: 5px;
@line-height-large: 1.33;
@line-height-small: 1.5;
@border-radius-base: 4px;
@border-radius-large: 6px;
@border-radius-small: 3px;
//== Tables
//
//## Customizes the `.table` component with basic values, each used across all table variations.
//** Background color used for `.table-hover`.
@table-bg-hover: #f5f5f5;
//-- Z-index master list
//
// Warning: Avoid customizing these values. They're used for a bird's eye view
// of components dependent on the z-axis and are designed to all work together.
//
// Note: These variables are not generated into the Customizer.
@zindex-navmenu-fixed: 1030;
@zindex-alert-fixed: 1035;
//== Media queries breakpoints
//
//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
// Extra small screen / phone
@screen-xs: 480px;
// Small screen / tablet
@screen-sm: 768px;
// Medium screen / desktop
@screen-md: 992px;
// Large screen / wide desktop
@screen-lg: 1200px;
//-- So media queries don't overlap when required, provide a maximum
//
// Note: These variables are not generated into the Customizer.
@screen-xs-min: @screen-xs;
@screen-sm-min: @screen-sm;
@screen-md-min: @screen-md;
@screen-lg-min: @screen-lg;
@screen-xs-max: (@screen-sm-min - 1);
@screen-sm-max: (@screen-md-min - 1);
@screen-md-max: (@screen-lg-min - 1);
//--
@container-lg: ((1140px + @grid-gutter-width));
//== Grid system
//
//## Define your custom responsive grid.
//** Padding between columns. Gets divided in half for the left and right.
@grid-gutter-width: 30px;
//** Point at which the navbar becomes uncollapsed.
@grid-float-breakpoint: 768px;
//** Maximum with of a smooth container.
@container-smooth: @container-lg;
//== Navbar
//
//##
// Basics of a navbar
@navbar-height: 50px;
@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
//== Navmenu
//
//##
// Basics of a navmenu
@navmenu-width: 300px;
@navmenu-margin-vertical: (0.5 * @line-height-computed);
@navmenu-default-color: #777;
@navmenu-default-bg: #f8f8f8;
@navmenu-default-border: darken(@navmenu-default-bg, 6.5%);
// Navmenu links
@navmenu-default-link-color: #777;
@navmenu-default-link-hover-color: #333;
@navmenu-default-link-hover-bg: transparent;
@navmenu-default-link-active-color: #555;
@navmenu-default-link-active-bg: darken(@navmenu-default-bg, 6.5%);
@navmenu-default-link-disabled-color: #ccc;
@navmenu-default-link-disabled-bg: transparent;
// Navmenu brand label
@navmenu-default-brand-color: @navmenu-default-link-color;
@navmenu-default-brand-hover-color: darken(@navmenu-default-link-color, 10%);
@navmenu-default-brand-hover-bg: transparent;
// Inverted navmenu
//
// Reset inverted navmenu basics
@navmenu-inverse-color: @gray-light;
@navmenu-inverse-bg: #222;
@navmenu-inverse-border: darken(@navmenu-inverse-bg, 10%);
// Inverted navmenu links
@navmenu-inverse-link-color: @gray-light;
@navmenu-inverse-link-hover-color: #fff;
@navmenu-inverse-link-hover-bg: transparent;
@navmenu-inverse-link-active-color: @navmenu-inverse-link-hover-color;
@navmenu-inverse-link-active-bg: darken(@navmenu-inverse-bg, 10%);
@navmenu-inverse-link-disabled-color: #444;
@navmenu-inverse-link-disabled-bg: transparent;
// Inverted navmenu brand label
@navmenu-inverse-brand-color: @navmenu-inverse-link-color;
@navmenu-inverse-brand-hover-color: #fff;
@navmenu-inverse-brand-hover-bg: transparent;
// Inverted navmenu search
// Normal navmenu needs no special styles or vars
@navmenu-inverse-search-bg: lighten(@navmenu-inverse-bg, 25%);
@navmenu-inverse-search-bg-focus: #fff;
@navmenu-inverse-search-border: @navmenu-inverse-bg;
@navmenu-inverse-search-placeholder-color: #ccc;
//== Navs
//
//##
@nav-link-padding: 10px 15px;
@nav-tabs-active-link-hover-border-color: #ddd;
@nav-tabs-border-color: #ddd;
//== Form states and alerts
//
//## Define colors for form feedback states and, by default, alerts.
@state-success-text: #3c763d;
@state-success-bg: #dff0d8;
@state-success-border: darken(spin(@state-success-bg, -10), 5%);
@state-info-text: #31708f;
@state-info-bg: #d9edf7;
@state-info-border: darken(spin(@state-info-bg, -10), 7%);
@state-warning-text: #8a6d3b;
@state-warning-bg: #fcf8e3;
@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
@state-danger-text: #a94442;
@state-danger-bg: #f2dede;
@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
//== Alerts
//
//## Define alert colors, border radius, and padding.
@alert-border-radius: @border-radius-base;
@alert-fixed-width: @screen-md;

25
less/button-labels.less Normal file
View File

@@ -0,0 +1,25 @@
// Labels for buttons
// --------------------------------------------------
.btn-labeled {
padding-top: 0;
padding-bottom: 0;
}
.btn-label {
position: relative;
background: transparent;
background: rgba(0, 0, 0, 0.15);
display: inline-block;
.button-label-size(@padding-base-vertical; @padding-base-horizontal; @border-radius-base);
}
.btn-lg .btn-label {
.button-label-size(@padding-large-vertical; @padding-large-horizontal; @border-radius-large);
}
.btn-sm .btn-label {
.button-label-size(@padding-small-vertical; @padding-small-horizontal; @border-radius-small);
}
.btn-xs .btn-label {
.button-label-size(1px; 5px; @border-radius-small);
}

Some files were not shown because too many files have changed in this diff Show More