├── dist ├── less │ ├── search.less │ ├── combobox.less │ ├── select.less │ ├── spinner.less │ ├── radio.less │ ├── checkbox.less │ ├── pillbox.less │ ├── fuelux-responsive.less │ ├── tree.less │ ├── fuelux.less │ ├── wizard.less │ └── datagrid.less ├── fuelux.zip ├── img │ ├── form.png │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── util.js ├── pillbox.js ├── checkbox.js ├── radio.js ├── search.js └── combobox.js ├── lib └── bootstrap │ ├── .travis.yml │ ├── img │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png │ ├── component.json │ ├── js │ ├── .jshintrc │ ├── tests │ │ ├── server.js │ │ ├── unit │ │ │ ├── bootstrap-transition.js │ │ │ ├── bootstrap-phantom.js │ │ │ ├── bootstrap-affix.js │ │ │ ├── bootstrap-scrollspy.js │ │ │ ├── bootstrap-alert.js │ │ │ ├── bootstrap-tab.js │ │ │ ├── bootstrap-collapse.js │ │ │ ├── bootstrap-button.js │ │ │ ├── bootstrap-popover.js │ │ │ └── bootstrap-modal.js │ │ ├── index.html │ │ └── phantom.js │ ├── bootstrap-transition.js │ ├── bootstrap-alert.js │ ├── bootstrap-button.js │ ├── bootstrap-popover.js │ ├── bootstrap-affix.js │ └── bootstrap-tab.js │ ├── composer.json │ ├── less │ ├── layouts.less │ ├── component-animations.less │ ├── utilities.less │ ├── grid.less │ ├── breadcrumbs.less │ ├── responsive-768px-979px.less │ ├── hero-unit.less │ ├── wells.less │ ├── responsive-1200px-min.less │ ├── close.less │ ├── accordion.less │ ├── pager.less │ ├── media.less │ ├── scaffolding.less │ ├── responsive.less │ ├── thumbnails.less │ ├── code.less │ ├── alerts.less │ ├── bootstrap.less │ ├── responsive-utilities.less │ ├── tooltip.less │ ├── labels-badges.less │ ├── modals.less │ ├── tests │ │ ├── forms-responsive.html │ │ └── forms.html │ ├── pagination.less │ ├── carousel.less │ ├── progress-bars.less │ ├── popovers.less │ └── responsive-767px-max.less │ ├── package.json │ └── CONTRIBUTING.md ├── src ├── less │ ├── search.less │ ├── combobox.less │ ├── select.less │ ├── spinner.less │ ├── radio.less │ ├── checkbox.less │ ├── pillbox.less │ ├── fuelux-responsive.less │ ├── tree.less │ ├── fuelux.less │ ├── wizard.less │ └── datagrid.less ├── img │ └── form.png ├── loader.js ├── util.js ├── all.js ├── pillbox.js ├── checkbox.js ├── radio.js ├── search.js └── combobox.js ├── .gitignore ├── testem.json ├── .travis.yml ├── sample ├── datasourceTree.js └── datasource.js ├── test ├── pillbox-test.js ├── fuelux.html ├── fuelux-test.js ├── radio-test.js ├── spinner-test.js ├── checkbox-test.js ├── search-test.js └── select-test.js ├── util └── update-bootstrap.sh ├── package.json ├── COPYING └── grunt.js /dist/less/search.less: -------------------------------------------------------------------------------- 1 | .search { 2 | display: inline-block; 3 | } -------------------------------------------------------------------------------- /lib/bootstrap/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.6 -------------------------------------------------------------------------------- /src/less/search.less: -------------------------------------------------------------------------------- 1 | .search { 2 | display: inline-block; 3 | } -------------------------------------------------------------------------------- /dist/fuelux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/dist/fuelux.zip -------------------------------------------------------------------------------- /src/img/form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/src/img/form.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .DS_Store 6 | .idea 7 | *.log 8 | -------------------------------------------------------------------------------- /dist/img/form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/dist/img/form.png -------------------------------------------------------------------------------- /dist/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/dist/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /dist/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/dist/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /lib/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/lib/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "launch_in_dev": ["chrome", "firefox", "phantomjs"], 3 | "test_page": "test/fuelux.html", 4 | "framework": "qunit" 5 | } -------------------------------------------------------------------------------- /lib/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leodido/fuelux-jam/master/lib/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 4 | - 0.6 5 | before_script: 6 | - "export DISPLAY=:99.0" 7 | - "sh -e /etc/init.d/xvfb start" 8 | -------------------------------------------------------------------------------- /lib/bootstrap/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "version": "2.3.2", 4 | "main": ["./docs/assets/js/bootstrap.js", "./docs/assets/css/bootstrap.css"], 5 | "dependencies": { 6 | "jquery": "~1.8.0" 7 | } 8 | } -------------------------------------------------------------------------------- /dist/less/combobox.less: -------------------------------------------------------------------------------- 1 | .combobox { 2 | display: inline-block; 3 | 4 | a { 5 | font-size: @baseFontSize; 6 | } 7 | 8 | button.btn { 9 | border-radius: 0 @inputBorderRadius @inputBorderRadius 0; 10 | } 11 | } -------------------------------------------------------------------------------- /src/less/combobox.less: -------------------------------------------------------------------------------- 1 | .combobox { 2 | display: inline-block; 3 | 4 | a { 5 | font-size: @baseFontSize; 6 | } 7 | 8 | button.btn { 9 | border-radius: 0 @inputBorderRadius @inputBorderRadius 0; 10 | } 11 | } -------------------------------------------------------------------------------- /lib/bootstrap/js/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "validthis": true, 3 | "laxcomma" : true, 4 | "laxbreak" : true, 5 | "browser" : true, 6 | "eqnull" : true, 7 | "debug" : true, 8 | "devel" : true, 9 | "boss" : true, 10 | "expr" : true, 11 | "asi" : true 12 | } -------------------------------------------------------------------------------- /src/loader.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define('jquery', [], function () { return jQuery; }); 10 | 11 | define('fuelux/loader', ['fuelux/all'], function () {}); 12 | 13 | require('fuelux/loader'); -------------------------------------------------------------------------------- /lib/bootstrap/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitter/bootstrap" 3 | , "description": "Sleek, intuitive, and powerful front-end framework for faster and easier web development." 4 | , "keywords": ["bootstrap", "css"] 5 | , "homepage": "http://twitter.github.com/bootstrap/" 6 | , "author": "Twitter Inc." 7 | , "license": "Apache-2.0" 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/less/select.less: -------------------------------------------------------------------------------- 1 | .select { 2 | .dropdown-label { 3 | padding: 0 10px 0 0; 4 | margin: 0; 5 | display: inline-block; 6 | text-align: left; 7 | font-weight: normal; 8 | color: #333; 9 | } 10 | } 11 | 12 | #selectTextSize { 13 | display: inline-block; 14 | position: absolute; 15 | visibility: hidden; 16 | top: 0; 17 | } -------------------------------------------------------------------------------- /dist/less/select.less: -------------------------------------------------------------------------------- 1 | .select { 2 | .dropdown-label { 3 | padding: 0 10px 0 0; 4 | margin: 0; 5 | display: inline-block; 6 | text-align: left; 7 | font-weight: normal; 8 | color: #333; 9 | } 10 | } 11 | 12 | #selectTextSize { 13 | display: inline-block; 14 | position: absolute; 15 | visibility: hidden; 16 | top: 0; 17 | } -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple connect server for phantom.js 3 | * Adapted from Modernizr 4 | */ 5 | 6 | var connect = require('connect') 7 | , http = require('http') 8 | , fs = require('fs') 9 | , app = connect() 10 | .use(connect.static(__dirname + '/../../')); 11 | 12 | http.createServer(app).listen(3000); 13 | 14 | fs.writeFileSync(__dirname + '/pid.txt', process.pid, 'utf-8') -------------------------------------------------------------------------------- /lib/bootstrap/less/layouts.less: -------------------------------------------------------------------------------- 1 | // 2 | // Layouts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Container (centered, fixed-width layouts) 7 | .container { 8 | .container-fixed(); 9 | } 10 | 11 | // Fluid layouts (left aligned, with sidebar, min- & max-width content) 12 | .container-fluid { 13 | padding-right: @gridGutterWidth; 14 | padding-left: @gridGutterWidth; 15 | .clearfix(); 16 | } -------------------------------------------------------------------------------- /lib/bootstrap/less/component-animations.less: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | 6 | .fade { 7 | opacity: 0; 8 | .transition(opacity .15s linear); 9 | &.in { 10 | opacity: 1; 11 | } 12 | } 13 | 14 | .collapse { 15 | position: relative; 16 | height: 0; 17 | overflow: hidden; 18 | .transition(height .35s ease); 19 | &.in { 20 | height: auto; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-transition.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-transition") 4 | 5 | test("should be defined on jquery support object", function () { 6 | ok($.support.transition !== undefined, 'transition object is defined') 7 | }) 8 | 9 | test("should provide an end object", function () { 10 | ok($.support.transition ? $.support.transition.end : true, 'end string is defined') 11 | }) 12 | 13 | }) -------------------------------------------------------------------------------- /lib/bootstrap/less/utilities.less: -------------------------------------------------------------------------------- 1 | // 2 | // Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // Quick floats 7 | .pull-right { 8 | float: right; 9 | } 10 | .pull-left { 11 | float: left; 12 | } 13 | 14 | // Toggling content 15 | .hide { 16 | display: none; 17 | } 18 | .show { 19 | display: block; 20 | } 21 | 22 | // Visibility 23 | .invisible { 24 | visibility: hidden; 25 | } 26 | 27 | // For Affix plugin 28 | .affix { 29 | position: fixed; 30 | } 31 | -------------------------------------------------------------------------------- /lib/bootstrap/less/grid.less: -------------------------------------------------------------------------------- 1 | // 2 | // Grid system 3 | // -------------------------------------------------- 4 | 5 | 6 | // Fixed (940px) 7 | #grid > .core(@gridColumnWidth, @gridGutterWidth); 8 | 9 | // Fluid (940px) 10 | #grid > .fluid(@fluidGridColumnWidth, @fluidGridGutterWidth); 11 | 12 | // Reset utility classes due to specificity 13 | [class*="span"].hide, 14 | .row-fluid [class*="span"].hide { 15 | display: none; 16 | } 17 | 18 | [class*="span"].pull-right, 19 | .row-fluid [class*="span"].pull-right { 20 | float: right; 21 | } 22 | -------------------------------------------------------------------------------- /lib/bootstrap/less/breadcrumbs.less: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: 8px 15px; 8 | margin: 0 0 @baseLineHeight; 9 | list-style: none; 10 | background-color: #f5f5f5; 11 | .border-radius(@baseBorderRadius); 12 | > li { 13 | display: inline-block; 14 | .ie7-inline-block(); 15 | text-shadow: 0 1px 0 @white; 16 | > .divider { 17 | padding: 0 5px; 18 | color: #ccc; 19 | } 20 | } 21 | > .active { 22 | color: @grayLight; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/bootstrap/less/responsive-768px-979px.less: -------------------------------------------------------------------------------- 1 | // 2 | // Responsive: Tablet to desktop 3 | // -------------------------------------------------- 4 | 5 | 6 | @media (min-width: 768px) and (max-width: 979px) { 7 | 8 | // Fixed grid 9 | #grid > .core(@gridColumnWidth768, @gridGutterWidth768); 10 | 11 | // Fluid grid 12 | #grid > .fluid(@fluidGridColumnWidth768, @fluidGridGutterWidth768); 13 | 14 | // Input grid 15 | #grid > .input(@gridColumnWidth768, @gridGutterWidth768); 16 | 17 | // No need to reset .thumbnails here since it's the same @gridGutterWidth 18 | 19 | } 20 | -------------------------------------------------------------------------------- /lib/bootstrap/less/hero-unit.less: -------------------------------------------------------------------------------- 1 | // 2 | // Hero unit 3 | // -------------------------------------------------- 4 | 5 | 6 | .hero-unit { 7 | padding: 60px; 8 | margin-bottom: 30px; 9 | font-size: 18px; 10 | font-weight: 200; 11 | line-height: @baseLineHeight * 1.5; 12 | color: @heroUnitLeadColor; 13 | background-color: @heroUnitBackground; 14 | .border-radius(6px); 15 | h1 { 16 | margin-bottom: 0; 17 | font-size: 60px; 18 | line-height: 1; 19 | color: @heroUnitHeadingColor; 20 | letter-spacing: -1px; 21 | } 22 | li { 23 | line-height: @baseLineHeight * 1.5; // Reset since we specify in type.less 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/bootstrap/less/wells.less: -------------------------------------------------------------------------------- 1 | // 2 | // Wells 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .well { 8 | min-height: 20px; 9 | padding: 19px; 10 | margin-bottom: 20px; 11 | background-color: @wellBackground; 12 | border: 1px solid darken(@wellBackground, 7%); 13 | .border-radius(@baseBorderRadius); 14 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); 15 | blockquote { 16 | border-color: #ddd; 17 | border-color: rgba(0,0,0,.15); 18 | } 19 | } 20 | 21 | // Sizes 22 | .well-large { 23 | padding: 24px; 24 | .border-radius(@borderRadiusLarge); 25 | } 26 | .well-small { 27 | padding: 9px; 28 | .border-radius(@borderRadiusSmall); 29 | } 30 | -------------------------------------------------------------------------------- /lib/bootstrap/less/responsive-1200px-min.less: -------------------------------------------------------------------------------- 1 | // 2 | // Responsive: Large desktop and up 3 | // -------------------------------------------------- 4 | 5 | 6 | @media (min-width: 1200px) { 7 | 8 | // Fixed grid 9 | #grid > .core(@gridColumnWidth1200, @gridGutterWidth1200); 10 | 11 | // Fluid grid 12 | #grid > .fluid(@fluidGridColumnWidth1200, @fluidGridGutterWidth1200); 13 | 14 | // Input grid 15 | #grid > .input(@gridColumnWidth1200, @gridGutterWidth1200); 16 | 17 | // Thumbnails 18 | .thumbnails { 19 | margin-left: -@gridGutterWidth1200; 20 | } 21 | .thumbnails > li { 22 | margin-left: @gridGutterWidth1200; 23 | } 24 | .row-fluid .thumbnails { 25 | margin-left: 0; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Utilities 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function (require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | // custom case-insensitive match expression 14 | function fuelTextExactCI(elem, text) { 15 | return (elem.textContent || elem.innerText || $(elem).text() || '').toLowerCase() === (text || '').toLowerCase(); 16 | } 17 | 18 | $.expr[':'].fuelTextExactCI = $.expr.createPseudo ? 19 | $.expr.createPseudo(function (text) { 20 | return function (elem) { 21 | return fuelTextExactCI(elem, text); 22 | }; 23 | }) : 24 | function (elem, i, match) { 25 | return fuelTextExactCI(elem, match[3]); 26 | }; 27 | 28 | }); -------------------------------------------------------------------------------- /dist/util.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Utilities 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(['require','jquery'],function (require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | // custom case-insensitive match expression 14 | function fuelTextExactCI(elem, text) { 15 | return (elem.textContent || elem.innerText || $(elem).text() || '').toLowerCase() === (text || '').toLowerCase(); 16 | } 17 | 18 | $.expr[':'].fuelTextExactCI = $.expr.createPseudo ? 19 | $.expr.createPseudo(function (text) { 20 | return function (elem) { 21 | return fuelTextExactCI(elem, text); 22 | }; 23 | }) : 24 | function (elem, i, match) { 25 | return fuelTextExactCI(elem, match[3]); 26 | }; 27 | 28 | }); -------------------------------------------------------------------------------- /lib/bootstrap/less/close.less: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: 20px; 9 | font-weight: bold; 10 | line-height: @baseLineHeight; 11 | color: @black; 12 | text-shadow: 0 1px 0 rgba(255,255,255,1); 13 | .opacity(20); 14 | &:hover, 15 | &:focus { 16 | color: @black; 17 | text-decoration: none; 18 | cursor: pointer; 19 | .opacity(40); 20 | } 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | button.close { 27 | padding: 0; 28 | cursor: pointer; 29 | background: transparent; 30 | border: 0; 31 | -webkit-appearance: none; 32 | } -------------------------------------------------------------------------------- /lib/bootstrap/less/accordion.less: -------------------------------------------------------------------------------- 1 | // 2 | // Accordion 3 | // -------------------------------------------------- 4 | 5 | 6 | // Parent container 7 | .accordion { 8 | margin-bottom: @baseLineHeight; 9 | } 10 | 11 | // Group == heading + body 12 | .accordion-group { 13 | margin-bottom: 2px; 14 | border: 1px solid #e5e5e5; 15 | .border-radius(@baseBorderRadius); 16 | } 17 | .accordion-heading { 18 | border-bottom: 0; 19 | } 20 | .accordion-heading .accordion-toggle { 21 | display: block; 22 | padding: 8px 15px; 23 | } 24 | 25 | // General toggle styles 26 | .accordion-toggle { 27 | cursor: pointer; 28 | } 29 | 30 | // Inner needs the styles because you can't animate properly with any styles on the element 31 | .accordion-inner { 32 | padding: 9px 15px; 33 | border-top: 1px solid #e5e5e5; 34 | } 35 | -------------------------------------------------------------------------------- /lib/bootstrap/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap" 3 | , "description": "Sleek, intuitive, and powerful front-end framework for faster and easier web development." 4 | , "version": "2.3.2" 5 | , "keywords": ["bootstrap", "css"] 6 | , "homepage": "http://twitter.github.com/bootstrap/" 7 | , "author": "Twitter Inc." 8 | , "scripts": { "test": "make test" } 9 | , "repository": { 10 | "type": "git" 11 | , "url": "https://github.com/twitter/bootstrap.git" 12 | } 13 | , "licenses": [ 14 | { 15 | "type": "Apache-2.0" 16 | , "url": "http://www.apache.org/licenses/LICENSE-2.0" 17 | } 18 | ] 19 | , "devDependencies": { 20 | "uglify-js": "1.3.4" 21 | , "jshint": "0.9.1" 22 | , "recess": "1.1.6" 23 | , "connect": "2.1.3" 24 | , "hogan.js": "2.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-phantom.js: -------------------------------------------------------------------------------- 1 | // Logging setup for phantom integration 2 | // adapted from Modernizr 3 | 4 | QUnit.begin = function () { 5 | console.log("Starting test suite") 6 | console.log("================================================\n") 7 | } 8 | 9 | QUnit.moduleDone = function (opts) { 10 | if (opts.failed === 0) { 11 | console.log("\u2714 All tests passed in '" + opts.name + "' module") 12 | } else { 13 | console.log("\u2716 " + opts.failed + " tests failed in '" + opts.name + "' module") 14 | } 15 | } 16 | 17 | QUnit.done = function (opts) { 18 | console.log("\n================================================") 19 | console.log("Tests completed in " + opts.runtime + " milliseconds") 20 | console.log(opts.passed + " tests of " + opts.total + " passed, " + opts.failed + " failed.") 21 | } -------------------------------------------------------------------------------- /dist/less/spinner.less: -------------------------------------------------------------------------------- 1 | .spinner{ 2 | 3 | input { 4 | width: 43px; 5 | float: left; 6 | } 7 | 8 | .btn { 9 | position: relative; 10 | width: 20px; 11 | height: 14px; 12 | padding-top: 0; 13 | padding-right: 9px; 14 | padding-left: 9px; 15 | 16 | &.disabled { 17 | cursor: not-allowed; 18 | } 19 | } 20 | 21 | .spinner-buttons { 22 | position: relative; 23 | float: left; 24 | height: 28px; 25 | width: 20px; 26 | left: -22px; 27 | } 28 | 29 | .spinner-up { 30 | 31 | padding: 0 0 4px 1px; 32 | top: 2px; 33 | 34 | i { 35 | position:relative; 36 | top: -4px; 37 | } 38 | } 39 | 40 | .spinner-down { 41 | 42 | padding: 0 0 4px 1px; 43 | top: 2px; 44 | height: 13px; 45 | 46 | i { 47 | position:relative; 48 | top: -5px; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/less/spinner.less: -------------------------------------------------------------------------------- 1 | .spinner{ 2 | 3 | input { 4 | width: 43px; 5 | float: left; 6 | } 7 | 8 | .btn { 9 | position: relative; 10 | width: 20px; 11 | height: 14px; 12 | padding-top: 0; 13 | padding-right: 9px; 14 | padding-left: 9px; 15 | 16 | &.disabled { 17 | cursor: not-allowed; 18 | } 19 | } 20 | 21 | .spinner-buttons { 22 | position: relative; 23 | float: left; 24 | height: 28px; 25 | width: 20px; 26 | left: -22px; 27 | } 28 | 29 | .spinner-up { 30 | 31 | padding: 0 0 4px 1px; 32 | top: 2px; 33 | 34 | i { 35 | position:relative; 36 | top: -4px; 37 | } 38 | } 39 | 40 | .spinner-down { 41 | 42 | padding: 0 0 4px 1px; 43 | top: 2px; 44 | height: 13px; 45 | 46 | i { 47 | position:relative; 48 | top: -5px; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-affix.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-affix") 4 | 5 | test("should provide no conflict", function () { 6 | var affix = $.fn.affix.noConflict() 7 | ok(!$.fn.affix, 'affix was set back to undefined (org value)') 8 | $.fn.affix = affix 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).affix, 'affix method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).affix()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should exit early if element is not visible", function () { 20 | var $affix = $('
').affix() 21 | $affix.data('affix').checkPosition() 22 | ok(!$affix.hasClass('affix'), 'affix class was not added') 23 | }) 24 | 25 | }) -------------------------------------------------------------------------------- /sample/datasourceTree.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Data components - static data source 3 | * https://github.com/ExactTarget/fuelux-data 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | (function (root, factory) { 10 | if (typeof define === 'function' && define.amd) { 11 | define(['underscore'], factory); 12 | } else { 13 | root.TreeDataSource = factory(); 14 | } 15 | }(this, function () { 16 | 17 | var DataSourceTree = function (options) { 18 | this._data = options.data; 19 | this._delay = options.delay; 20 | }; 21 | 22 | DataSourceTree.prototype = { 23 | 24 | data: function (options, callback) { 25 | var self = this; 26 | 27 | setTimeout(function () { 28 | var data = $.extend(true, [], self._data); 29 | 30 | callback({ data: data }); 31 | 32 | }, this._delay) 33 | } 34 | 35 | }; 36 | 37 | return DataSourceTree; 38 | })); 39 | -------------------------------------------------------------------------------- /lib/bootstrap/less/pager.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pager pagination 3 | // -------------------------------------------------- 4 | 5 | 6 | .pager { 7 | margin: @baseLineHeight 0; 8 | list-style: none; 9 | text-align: center; 10 | .clearfix(); 11 | } 12 | .pager li { 13 | display: inline; 14 | } 15 | .pager li > a, 16 | .pager li > span { 17 | display: inline-block; 18 | padding: 5px 14px; 19 | background-color: #fff; 20 | border: 1px solid #ddd; 21 | .border-radius(15px); 22 | } 23 | .pager li > a:hover, 24 | .pager li > a:focus { 25 | text-decoration: none; 26 | background-color: #f5f5f5; 27 | } 28 | .pager .next > a, 29 | .pager .next > span { 30 | float: right; 31 | } 32 | .pager .previous > a, 33 | .pager .previous > span { 34 | float: left; 35 | } 36 | .pager .disabled > a, 37 | .pager .disabled > a:hover, 38 | .pager .disabled > a:focus, 39 | .pager .disabled > span { 40 | color: @grayLight; 41 | background-color: #fff; 42 | cursor: default; 43 | } -------------------------------------------------------------------------------- /dist/less/radio.less: -------------------------------------------------------------------------------- 1 | .radio-custom { 2 | input[type=radio] { 3 | display: none; 4 | } 5 | 6 | i { 7 | background-image: url(../img/form.png); 8 | background-position: 0 -15px; 9 | background-repeat: no-repeat; 10 | margin-left: -20px; 11 | margin-right: 4px; 12 | padding-left: 16px; 13 | width: 16px; 14 | height: 16px; 15 | 16 | &.checked { 17 | /* checked */ 18 | background-position: -48px -15px; 19 | } 20 | 21 | &.disabled { 22 | /* disabled */ 23 | background-position: -64px -15px; 24 | 25 | &.checked { 26 | /* disabled and checked */ 27 | background-position: -80px -15px; 28 | } 29 | } 30 | } 31 | } 32 | 33 | .radio-custom:hover { 34 | i { 35 | background-position: -16px -15px; 36 | 37 | &.checked { 38 | /* checked */ 39 | background-position: -32px -15px; 40 | } 41 | 42 | &.disabled { 43 | /* disabled */ 44 | background-position: -64px -15px; 45 | 46 | &.checked { 47 | /* disabled and checked */ 48 | background-position: -80px -15px; 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/less/radio.less: -------------------------------------------------------------------------------- 1 | .radio-custom { 2 | input[type=radio] { 3 | display: none; 4 | } 5 | 6 | i { 7 | background-image: url(../img/form.png); 8 | background-position: 0 -15px; 9 | background-repeat: no-repeat; 10 | margin-left: -20px; 11 | margin-right: 4px; 12 | padding-left: 16px; 13 | width: 16px; 14 | height: 16px; 15 | 16 | &.checked { 17 | /* checked */ 18 | background-position: -48px -15px; 19 | } 20 | 21 | &.disabled { 22 | /* disabled */ 23 | background-position: -64px -15px; 24 | 25 | &.checked { 26 | /* disabled and checked */ 27 | background-position: -80px -15px; 28 | } 29 | } 30 | } 31 | } 32 | 33 | .radio-custom:hover { 34 | i { 35 | background-position: -16px -15px; 36 | 37 | &.checked { 38 | /* checked */ 39 | background-position: -32px -15px; 40 | } 41 | 42 | &.disabled { 43 | /* disabled */ 44 | background-position: -64px -15px; 45 | 46 | &.checked { 47 | /* disabled and checked */ 48 | background-position: -80px -15px; 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /lib/bootstrap/less/media.less: -------------------------------------------------------------------------------- 1 | // Media objects 2 | // Source: http://stubbornella.org/content/?p=497 3 | // -------------------------------------------------- 4 | 5 | 6 | // Common styles 7 | // ------------------------- 8 | 9 | // Clear the floats 10 | .media, 11 | .media-body { 12 | overflow: hidden; 13 | *overflow: visible; 14 | zoom: 1; 15 | } 16 | 17 | // Proper spacing between instances of .media 18 | .media, 19 | .media .media { 20 | margin-top: 15px; 21 | } 22 | .media:first-child { 23 | margin-top: 0; 24 | } 25 | 26 | // For images and videos, set to block 27 | .media-object { 28 | display: block; 29 | } 30 | 31 | // Reset margins on headings for tighter default spacing 32 | .media-heading { 33 | margin: 0 0 5px; 34 | } 35 | 36 | 37 | // Media image alignment 38 | // ------------------------- 39 | 40 | .media > .pull-left { 41 | margin-right: 10px; 42 | } 43 | .media > .pull-right { 44 | margin-left: 10px; 45 | } 46 | 47 | 48 | // Media list variation 49 | // ------------------------- 50 | 51 | // Undo default ul/ol styles 52 | .media-list { 53 | margin-left: 0; 54 | list-style: none; 55 | } 56 | -------------------------------------------------------------------------------- /src/all.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function (require) { 10 | require('jquery'); 11 | require('bootstrap/bootstrap-affix'); 12 | require('bootstrap/bootstrap-alert'); 13 | require('bootstrap/bootstrap-button'); 14 | require('bootstrap/bootstrap-carousel'); 15 | require('bootstrap/bootstrap-collapse'); 16 | require('bootstrap/bootstrap-dropdown'); 17 | require('bootstrap/bootstrap-modal'); 18 | require('bootstrap/bootstrap-popover'); 19 | require('bootstrap/bootstrap-scrollspy'); 20 | require('bootstrap/bootstrap-tab'); 21 | require('bootstrap/bootstrap-tooltip'); 22 | require('bootstrap/bootstrap-transition'); 23 | require('bootstrap/bootstrap-typeahead'); 24 | require('fuelux/checkbox'); 25 | require('fuelux/combobox'); 26 | require('fuelux/datagrid'); 27 | require('fuelux/pillbox'); 28 | require('fuelux/radio'); 29 | require('fuelux/search'); 30 | require('fuelux/spinner'); 31 | require('fuelux/select'); 32 | require('fuelux/tree'); 33 | require('fuelux/wizard'); 34 | }); 35 | -------------------------------------------------------------------------------- /lib/bootstrap/less/scaffolding.less: -------------------------------------------------------------------------------- 1 | // 2 | // Scaffolding 3 | // -------------------------------------------------- 4 | 5 | 6 | // Body reset 7 | // ------------------------- 8 | 9 | body { 10 | margin: 0; 11 | font-family: @baseFontFamily; 12 | font-size: @baseFontSize; 13 | line-height: @baseLineHeight; 14 | color: @textColor; 15 | background-color: @bodyBackground; 16 | } 17 | 18 | 19 | // Links 20 | // ------------------------- 21 | 22 | a { 23 | color: @linkColor; 24 | text-decoration: none; 25 | } 26 | a:hover, 27 | a:focus { 28 | color: @linkColorHover; 29 | text-decoration: underline; 30 | } 31 | 32 | 33 | // Images 34 | // ------------------------- 35 | 36 | // Rounded corners 37 | .img-rounded { 38 | .border-radius(6px); 39 | } 40 | 41 | // Add polaroid-esque trim 42 | .img-polaroid { 43 | padding: 4px; 44 | background-color: #fff; 45 | border: 1px solid #ccc; 46 | border: 1px solid rgba(0,0,0,.2); 47 | .box-shadow(0 1px 3px rgba(0,0,0,.1)); 48 | } 49 | 50 | // Perfect circle 51 | .img-circle { 52 | .border-radius(500px); // crank the border-radius so it works with most reasonably sized images 53 | } 54 | -------------------------------------------------------------------------------- /dist/less/checkbox.less: -------------------------------------------------------------------------------- 1 | .form-inline { 2 | .checkbox-custom { 3 | padding-left: 20px; 4 | } 5 | 6 | .checkbox-custom .checkbox { 7 | padding-left: 16px; 8 | } 9 | } 10 | 11 | .checkbox-custom { 12 | input[type=checkbox] { 13 | display: none; 14 | } 15 | 16 | i { 17 | background-image: url(../img/form.png); 18 | background-position: 0 1px; 19 | background-repeat: no-repeat; 20 | margin-left: -20px; 21 | margin-right: 4px; 22 | padding-left: 16px; 23 | width: 16px; 24 | height: 16px; 25 | 26 | &.checked { 27 | /* checked */ 28 | background-position: -48px 1px; 29 | } 30 | 31 | &.disabled { 32 | /* disabled */ 33 | background-position: -64px 1px; 34 | 35 | &.checked { 36 | /* disabled and checked */ 37 | background-position: -80px 1px; 38 | } 39 | } 40 | } 41 | } 42 | 43 | .checkbox-custom:hover { 44 | i { 45 | background-position: -16px 1px; 46 | 47 | &.checked { 48 | /* checked */ 49 | background-position: -32px 1px; 50 | } 51 | 52 | &.disabled { 53 | /* disabled */ 54 | background-position: -64px 1px; 55 | 56 | &.checked { 57 | /* disabled and checked */ 58 | background-position: -80px 1px; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/less/checkbox.less: -------------------------------------------------------------------------------- 1 | .form-inline { 2 | .checkbox-custom { 3 | padding-left: 20px; 4 | } 5 | 6 | .checkbox-custom .checkbox { 7 | padding-left: 16px; 8 | } 9 | } 10 | 11 | .checkbox-custom { 12 | input[type=checkbox] { 13 | display: none; 14 | } 15 | 16 | i { 17 | background-image: url(../img/form.png); 18 | background-position: 0 1px; 19 | background-repeat: no-repeat; 20 | margin-left: -20px; 21 | margin-right: 4px; 22 | padding-left: 16px; 23 | width: 16px; 24 | height: 16px; 25 | 26 | &.checked { 27 | /* checked */ 28 | background-position: -48px 1px; 29 | } 30 | 31 | &.disabled { 32 | /* disabled */ 33 | background-position: -64px 1px; 34 | 35 | &.checked { 36 | /* disabled and checked */ 37 | background-position: -80px 1px; 38 | } 39 | } 40 | } 41 | } 42 | 43 | .checkbox-custom:hover { 44 | i { 45 | background-position: -16px 1px; 46 | 47 | &.checked { 48 | /* checked */ 49 | background-position: -32px 1px; 50 | } 51 | 52 | &.disabled { 53 | /* disabled */ 54 | background-position: -64px 1px; 55 | 56 | &.checked { 57 | /* disabled and checked */ 58 | background-position: -80px 1px; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /test/pillbox-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/pillbox'], function($) { 6 | 7 | module("Fuel UX pillbox", { 8 | setup: function(){ 9 | this.pillboxHTML = '
'; 12 | } 13 | }); 14 | 15 | test("should be defined on jquery object", function () { 16 | ok($(this.pillboxHTML).pillbox, 'pillbox method is defined'); 17 | }); 18 | test("should return element", function () { 19 | var $pillbox = $(this.pillboxHTML); 20 | ok($pillbox.pillbox() === $pillbox, 'pillbox should be initialized'); 21 | }); 22 | test("should behave as designed", function () { 23 | var $pillbox = $(this.pillboxHTML).pillbox(); 24 | 25 | equal($pillbox.pillbox('items').length, 2, 'pillbox returns both items'); 26 | 27 | $pillbox.find('li').eq(1).click(); 28 | 29 | equal($pillbox.pillbox('items').length, 1, 'pillbox removed an item'); 30 | deepEqual($pillbox.pillbox('items')[0], {text: 'one', value: 'foo'}, 'pillbox returns item data'); 31 | }); 32 | 33 | }); -------------------------------------------------------------------------------- /lib/bootstrap/less/responsive.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | 12 | // Responsive.less 13 | // For phone and tablet devices 14 | // ------------------------------------------------------------- 15 | 16 | 17 | // REPEAT VARIABLES & MIXINS 18 | // ------------------------- 19 | // Required since we compile the responsive stuff separately 20 | 21 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 22 | @import "mixins.less"; 23 | 24 | 25 | // RESPONSIVE CLASSES 26 | // ------------------ 27 | 28 | @import "responsive-utilities.less"; 29 | 30 | 31 | // MEDIA QUERIES 32 | // ------------------ 33 | 34 | // Large desktops 35 | @import "responsive-1200px-min.less"; 36 | 37 | // Tablets to regular desktops 38 | @import "responsive-768px-979px.less"; 39 | 40 | // Phones to portrait tablets and narrow desktops 41 | @import "responsive-767px-max.less"; 42 | 43 | 44 | // RESPONSIVE NAVBAR 45 | // ------------------ 46 | 47 | // From 979px and below, show a button to toggle navbar contents 48 | @import "responsive-navbar.less"; 49 | -------------------------------------------------------------------------------- /util/update-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf lib/bootstrap 4 | 5 | volo add -nostamp bootstrap 6 | 7 | volo amdify lib/bootstrap/js/bootstrap-transition.js depends=jquery 8 | volo amdify lib/bootstrap/js/bootstrap-affix.js depends=bootstrap/bootstrap-transition 9 | volo amdify lib/bootstrap/js/bootstrap-alert.js depends=bootstrap/bootstrap-transition 10 | volo amdify lib/bootstrap/js/bootstrap-button.js depends=bootstrap/bootstrap-transition 11 | volo amdify lib/bootstrap/js/bootstrap-carousel.js depends=bootstrap/bootstrap-transition 12 | volo amdify lib/bootstrap/js/bootstrap-collapse.js depends=bootstrap/bootstrap-transition 13 | volo amdify lib/bootstrap/js/bootstrap-dropdown.js depends=bootstrap/bootstrap-transition 14 | volo amdify lib/bootstrap/js/bootstrap-modal.js depends=bootstrap/bootstrap-transition 15 | volo amdify lib/bootstrap/js/bootstrap-popover.js depends=bootstrap/bootstrap-transition,bootstrap/bootstrap-tooltip 16 | volo amdify lib/bootstrap/js/bootstrap-scrollspy.js depends=bootstrap/bootstrap-transition 17 | volo amdify lib/bootstrap/js/bootstrap-tab.js depends=bootstrap/bootstrap-transition 18 | volo amdify lib/bootstrap/js/bootstrap-tooltip.js depends=bootstrap/bootstrap-transition 19 | volo amdify lib/bootstrap/js/bootstrap-typeahead.js depends=bootstrap/bootstrap-transition 20 | 21 | -------------------------------------------------------------------------------- /test/fuelux.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Fuel UX Test Suite 6 | 7 | 8 | 9 | 10 | 11 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |

Fuel UX Test Suite

36 | 37 |

38 | 39 |
40 |

41 |
    42 |
    43 | 44 |
    45 | 46 | 47 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-scrollspy.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-scrollspy") 4 | 5 | test("should provide no conflict", function () { 6 | var scrollspy = $.fn.scrollspy.noConflict() 7 | ok(!$.fn.scrollspy, 'scrollspy was set back to undefined (org value)') 8 | $.fn.scrollspy = scrollspy 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).scrollspy, 'scrollspy method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).scrollspy()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should switch active class on scroll", function () { 20 | var sectionHTML = '
    ' 21 | , $section = $(sectionHTML).append('#qunit-fixture') 22 | , topbarHTML ='
    ' 23 | + '
    ' 24 | + '
    ' 25 | + '

    Bootstrap

    ' 26 | + '' 29 | + '
    ' 30 | + '
    ' 31 | + '
    ' 32 | , $topbar = $(topbarHTML).scrollspy() 33 | 34 | ok($topbar.find('.active', true)) 35 | }) 36 | 37 | }) -------------------------------------------------------------------------------- /lib/bootstrap/less/thumbnails.less: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Note: `.thumbnails` and `.thumbnails > li` are overriden in responsive files 7 | 8 | // Make wrapper ul behave like the grid 9 | .thumbnails { 10 | margin-left: -@gridGutterWidth; 11 | list-style: none; 12 | .clearfix(); 13 | } 14 | // Fluid rows have no left margin 15 | .row-fluid .thumbnails { 16 | margin-left: 0; 17 | } 18 | 19 | // Float li to make thumbnails appear in a row 20 | .thumbnails > li { 21 | float: left; // Explicity set the float since we don't require .span* classes 22 | margin-bottom: @baseLineHeight; 23 | margin-left: @gridGutterWidth; 24 | } 25 | 26 | // The actual thumbnail (can be `a` or `div`) 27 | .thumbnail { 28 | display: block; 29 | padding: 4px; 30 | line-height: @baseLineHeight; 31 | border: 1px solid #ddd; 32 | .border-radius(@baseBorderRadius); 33 | .box-shadow(0 1px 3px rgba(0,0,0,.055)); 34 | .transition(all .2s ease-in-out); 35 | } 36 | // Add a hover/focus state for linked versions only 37 | a.thumbnail:hover, 38 | a.thumbnail:focus { 39 | border-color: @linkColor; 40 | .box-shadow(0 1px 4px rgba(0,105,214,.25)); 41 | } 42 | 43 | // Images and captions 44 | .thumbnail > img { 45 | display: block; 46 | max-width: 100%; 47 | margin-left: auto; 48 | margin-right: auto; 49 | } 50 | .thumbnail .caption { 51 | padding: 9px; 52 | color: @gray; 53 | } 54 | -------------------------------------------------------------------------------- /dist/less/pillbox.less: -------------------------------------------------------------------------------- 1 | .pillbox { 2 | 3 | padding: 3px; 4 | 5 | ul { 6 | display: inline-block; 7 | margin: 0; 8 | } 9 | 10 | li { 11 | 12 | // Begin Bootstrap .label 13 | font-size: @baseFontSize * .846; 14 | font-weight: bold; 15 | line-height: 21px; // modified 16 | color: @white; 17 | vertical-align: baseline; 18 | //white-space: nowrap; //removed 19 | text-shadow: 0 -1px 0 rgba(0,0,0,.25); 20 | background-color: @grayLight; 21 | padding: 1px 4px 2px; 22 | .border-radius(3px); 23 | // End Bootstrap .label 24 | 25 | display: inline-block; 26 | margin: 2px; 27 | cursor: pointer; 28 | float:left; 29 | 30 | &:after { 31 | 32 | // Begin Bootstrap .close 33 | float: right; 34 | font-size: 20px; 35 | font-weight: bold; 36 | line-height: @baseLineHeight; 37 | color: @black; 38 | text-shadow: 0 1px 0 rgba(255,255,255,1); 39 | .opacity(20); 40 | // End Bootstrap .close 41 | 42 | padding-left: 4px; 43 | position: relative; 44 | top: -2px; 45 | content: " \00D7" 46 | } 47 | 48 | &:hover { 49 | &:after { 50 | .opacity(40); 51 | } 52 | } 53 | 54 | &.status { 55 | &-important { 56 | background-color: @errorText; 57 | } 58 | 59 | &-warning { 60 | background-color: @orange; 61 | } 62 | 63 | &-success { 64 | background-color: @successText; 65 | } 66 | 67 | &-info { 68 | background-color: @infoText; 69 | } 70 | } 71 | 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /src/less/pillbox.less: -------------------------------------------------------------------------------- 1 | .pillbox { 2 | 3 | padding: 3px; 4 | 5 | ul { 6 | display: inline-block; 7 | margin: 0; 8 | } 9 | 10 | li { 11 | 12 | // Begin Bootstrap .label 13 | font-size: @baseFontSize * .846; 14 | font-weight: bold; 15 | line-height: 21px; // modified 16 | color: @white; 17 | vertical-align: baseline; 18 | //white-space: nowrap; //removed 19 | text-shadow: 0 -1px 0 rgba(0,0,0,.25); 20 | background-color: @grayLight; 21 | padding: 1px 4px 2px; 22 | .border-radius(3px); 23 | // End Bootstrap .label 24 | 25 | display: inline-block; 26 | margin: 2px; 27 | cursor: pointer; 28 | float:left; 29 | 30 | &:after { 31 | 32 | // Begin Bootstrap .close 33 | float: right; 34 | font-size: 20px; 35 | font-weight: bold; 36 | line-height: @baseLineHeight; 37 | color: @black; 38 | text-shadow: 0 1px 0 rgba(255,255,255,1); 39 | .opacity(20); 40 | // End Bootstrap .close 41 | 42 | padding-left: 4px; 43 | position: relative; 44 | top: -2px; 45 | content: " \00D7" 46 | } 47 | 48 | &:hover { 49 | &:after { 50 | .opacity(40); 51 | } 52 | } 53 | 54 | &.status { 55 | &-important { 56 | background-color: @errorText; 57 | } 58 | 59 | &-warning { 60 | background-color: @orange; 61 | } 62 | 63 | &-success { 64 | background-color: @successText; 65 | } 66 | 67 | &-info { 68 | background-color: @infoText; 69 | } 70 | } 71 | 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuelux-jam", 3 | "title": "Fuel UX", 4 | "version": "2.3.0", 5 | "description": "Base Fuel UX styles and controls.", 6 | "homepage": "https://github.com/ExactTarget/fuelux", 7 | "author": { 8 | "name": "ExactTarget", 9 | "email": "aalexander@exacttarget.com", 10 | "url": "http://code.exacttarget.com" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/ExactTarget/fuelux.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/ExactTarget/fuelux/issues" 18 | }, 19 | "licenses": [ 20 | { 21 | "type": "MIT", 22 | "url": "https://github.com/ExactTarget/fuelux/blob/master/COPYING" 23 | } 24 | ], 25 | "engines": { 26 | "node": ">= 0.6.0" 27 | }, 28 | "scripts": { 29 | "test": "grunt qunit" 30 | }, 31 | "devDependencies": { 32 | "grunt": "~0.3.11", 33 | "grunt-contrib": "~0.1.0", 34 | "grunt-recess": "~0.1.0" 35 | }, 36 | "private": true, 37 | "volo": { 38 | "baseDir": "lib", 39 | "url": "https://raw.github.com/ExactTarget/fuelux/{version}/dist/fuelux.zip", 40 | "type": "directory", 41 | "dependencies": { 42 | } 43 | }, 44 | "keywords": [ 45 | "package", 46 | "jam", 47 | "fuelux", 48 | "fuel ux" 49 | ], 50 | "jam": { 51 | "dependencies": { }, 52 | "shim": { 53 | "deps": [], 54 | "exports": "fuelux" 55 | } 56 | }, 57 | "github": "https://github.com/leodido/fuelux-jam" 58 | } 59 | -------------------------------------------------------------------------------- /dist/less/fuelux-responsive.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .fuelux { 12 | 13 | // Responsive.less 14 | // For phone and tablet devices 15 | // ------------------------------------------------------------- 16 | 17 | 18 | // REPEAT VARIABLES & MIXINS 19 | // ------------------------- 20 | // Required since we compile the responsive stuff separately 21 | 22 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 23 | @import "../../lib/bootstrap/less/mixins.less"; 24 | 25 | 26 | // RESPONSIVE CLASSES 27 | // ------------------ 28 | 29 | @import "../../lib/bootstrap/less/responsive-utilities.less"; 30 | 31 | 32 | // MEDIA QUERIES 33 | // ------------------ 34 | 35 | // Large desktops 36 | @import "../../lib/bootstrap/less/responsive-1200px-min.less"; 37 | 38 | // Tablets to regular desktops 39 | @import "../../lib/bootstrap/less/responsive-768px-979px.less"; 40 | 41 | // Phones to portrait tablets and narrow desktops 42 | @import "../../lib/bootstrap/less/responsive-767px-max.less"; 43 | 44 | 45 | // RESPONSIVE NAVBAR 46 | // ------------------ 47 | 48 | // From 979px and below, show a button to toggle navbar contents 49 | @import "../../lib/bootstrap/less/responsive-navbar.less"; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/less/fuelux-responsive.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .fuelux { 12 | 13 | // Responsive.less 14 | // For phone and tablet devices 15 | // ------------------------------------------------------------- 16 | 17 | 18 | // REPEAT VARIABLES & MIXINS 19 | // ------------------------- 20 | // Required since we compile the responsive stuff separately 21 | 22 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 23 | @import "../../lib/bootstrap/less/mixins.less"; 24 | 25 | 26 | // RESPONSIVE CLASSES 27 | // ------------------ 28 | 29 | @import "../../lib/bootstrap/less/responsive-utilities.less"; 30 | 31 | 32 | // MEDIA QUERIES 33 | // ------------------ 34 | 35 | // Large desktops 36 | @import "../../lib/bootstrap/less/responsive-1200px-min.less"; 37 | 38 | // Tablets to regular desktops 39 | @import "../../lib/bootstrap/less/responsive-768px-979px.less"; 40 | 41 | // Phones to portrait tablets and narrow desktops 42 | @import "../../lib/bootstrap/less/responsive-767px-max.less"; 43 | 44 | 45 | // RESPONSIVE NAVBAR 46 | // ------------------ 47 | 48 | // From 979px and below, show a button to toggle navbar contents 49 | @import "../../lib/bootstrap/less/responsive-navbar.less"; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /lib/bootstrap/less/code.less: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and blocK) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | pre { 9 | padding: 0 3px 2px; 10 | #font > #family > .monospace; 11 | font-size: @baseFontSize - 2; 12 | color: @grayDark; 13 | .border-radius(3px); 14 | } 15 | 16 | // Inline code 17 | code { 18 | padding: 2px 4px; 19 | color: #d14; 20 | background-color: #f7f7f9; 21 | border: 1px solid #e1e1e8; 22 | white-space: nowrap; 23 | } 24 | 25 | // Blocks of code 26 | pre { 27 | display: block; 28 | padding: (@baseLineHeight - 1) / 2; 29 | margin: 0 0 @baseLineHeight / 2; 30 | font-size: @baseFontSize - 1; // 14px to 13px 31 | line-height: @baseLineHeight; 32 | word-break: break-all; 33 | word-wrap: break-word; 34 | white-space: pre; 35 | white-space: pre-wrap; 36 | background-color: #f5f5f5; 37 | border: 1px solid #ccc; // fallback for IE7-8 38 | border: 1px solid rgba(0,0,0,.15); 39 | .border-radius(@baseBorderRadius); 40 | 41 | // Make prettyprint styles more spaced out for readability 42 | &.prettyprint { 43 | margin-bottom: @baseLineHeight; 44 | } 45 | 46 | // Account for some code outputs that place code tags in pre tags 47 | code { 48 | padding: 0; 49 | color: inherit; 50 | white-space: pre; 51 | white-space: pre-wrap; 52 | background-color: transparent; 53 | border: 0; 54 | } 55 | } 56 | 57 | // Enable scrollable blocks of code 58 | .pre-scrollable { 59 | max-height: 340px; 60 | overflow-y: scroll; 61 | } -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012, ExactTarget, Inc. 2 | All rights reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in the 6 | Software without restriction, including without limitation the rights to use, copy, 7 | modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 8 | and to permit persons to whom the Software is furnished to do so, subject to the 9 | following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 16 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 17 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 18 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | ==================================================================== 22 | 23 | The above license does not apply to the following bundled components: 24 | 25 | • jQuery located at lib/jquery.js 26 | • Bootstrap Apache 2.0 Located under lib/bootstrap 27 | • RequireJS located at lib/require.js 28 | • QUnit located under lib/qunit 29 | • Grunt located under node-modules/grunt 30 | • Grunt-contrib located under node-modules/grunt-contrib 31 | • Grunt-recess located under node-modules/grunt-recess 32 | 33 | Licensing information regarding the above packages can be found in the THIRD-PARTY file. -------------------------------------------------------------------------------- /lib/bootstrap/less/alerts.less: -------------------------------------------------------------------------------- 1 | // 2 | // Alerts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // ------------------------- 8 | 9 | .alert { 10 | padding: 8px 35px 8px 14px; 11 | margin-bottom: @baseLineHeight; 12 | text-shadow: 0 1px 0 rgba(255,255,255,.5); 13 | background-color: @warningBackground; 14 | border: 1px solid @warningBorder; 15 | .border-radius(@baseBorderRadius); 16 | } 17 | .alert, 18 | .alert h4 { 19 | // Specified for the h4 to prevent conflicts of changing @headingsColor 20 | color: @warningText; 21 | } 22 | .alert h4 { 23 | margin: 0; 24 | } 25 | 26 | // Adjust close link position 27 | .alert .close { 28 | position: relative; 29 | top: -2px; 30 | right: -21px; 31 | line-height: @baseLineHeight; 32 | } 33 | 34 | 35 | // Alternate styles 36 | // ------------------------- 37 | 38 | .alert-success { 39 | background-color: @successBackground; 40 | border-color: @successBorder; 41 | color: @successText; 42 | } 43 | .alert-success h4 { 44 | color: @successText; 45 | } 46 | .alert-danger, 47 | .alert-error { 48 | background-color: @errorBackground; 49 | border-color: @errorBorder; 50 | color: @errorText; 51 | } 52 | .alert-danger h4, 53 | .alert-error h4 { 54 | color: @errorText; 55 | } 56 | .alert-info { 57 | background-color: @infoBackground; 58 | border-color: @infoBorder; 59 | color: @infoText; 60 | } 61 | .alert-info h4 { 62 | color: @infoText; 63 | } 64 | 65 | 66 | // Block alerts 67 | // ------------------------- 68 | 69 | .alert-block { 70 | padding-top: 14px; 71 | padding-bottom: 14px; 72 | } 73 | .alert-block > p, 74 | .alert-block > ul { 75 | margin-bottom: 0; 76 | } 77 | .alert-block p + p { 78 | margin-top: 5px; 79 | } 80 | -------------------------------------------------------------------------------- /lib/bootstrap/less/bootstrap.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | // Core variables and mixins 12 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 13 | @import "mixins.less"; 14 | 15 | // CSS Reset 16 | @import "reset.less"; 17 | 18 | // Grid system and page structure 19 | @import "scaffolding.less"; 20 | @import "grid.less"; 21 | @import "layouts.less"; 22 | 23 | // Base CSS 24 | @import "type.less"; 25 | @import "code.less"; 26 | @import "forms.less"; 27 | @import "tables.less"; 28 | 29 | // Components: common 30 | @import "sprites.less"; 31 | @import "dropdowns.less"; 32 | @import "wells.less"; 33 | @import "component-animations.less"; 34 | @import "close.less"; 35 | 36 | // Components: Buttons & Alerts 37 | @import "buttons.less"; 38 | @import "button-groups.less"; 39 | @import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less 40 | 41 | // Components: Nav 42 | @import "navs.less"; 43 | @import "navbar.less"; 44 | @import "breadcrumbs.less"; 45 | @import "pagination.less"; 46 | @import "pager.less"; 47 | 48 | // Components: Popovers 49 | @import "modals.less"; 50 | @import "tooltip.less"; 51 | @import "popovers.less"; 52 | 53 | // Components: Misc 54 | @import "thumbnails.less"; 55 | @import "media.less"; 56 | @import "labels-badges.less"; 57 | @import "progress-bars.less"; 58 | @import "accordion.less"; 59 | @import "carousel.less"; 60 | @import "hero-unit.less"; 61 | 62 | // Utility classes 63 | @import "utilities.less"; // Has to be last to override when necessary 64 | -------------------------------------------------------------------------------- /src/pillbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Pillbox 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function(require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // PILLBOX CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Pillbox = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.pillbox.defaults, options); 19 | this.$element.on('click', 'li', $.proxy(this.itemclicked, this)); 20 | }; 21 | 22 | Pillbox.prototype = { 23 | constructor: Pillbox, 24 | 25 | items: function() { 26 | return this.$element.find('li').map(function() { 27 | var $this = $(this); 28 | return $.extend({ text: $this.text() }, $this.data()); 29 | }).get(); 30 | }, 31 | 32 | itemclicked: function (e) { 33 | $(e.currentTarget).remove(); 34 | e.preventDefault(); 35 | } 36 | }; 37 | 38 | 39 | // PILLBOX PLUGIN DEFINITION 40 | 41 | $.fn.pillbox = function (option) { 42 | var methodReturn; 43 | 44 | var $set = this.each(function () { 45 | var $this = $(this); 46 | var data = $this.data('pillbox'); 47 | var options = typeof option === 'object' && option; 48 | 49 | if (!data) $this.data('pillbox', (data = new Pillbox(this, options))); 50 | if (typeof option === 'string') methodReturn = data[option](); 51 | }); 52 | 53 | return (methodReturn === undefined) ? $set : methodReturn; 54 | }; 55 | 56 | $.fn.pillbox.defaults = {}; 57 | 58 | $.fn.pillbox.Constructor = Pillbox; 59 | 60 | 61 | // PILLBOX DATA-API 62 | 63 | $(function () { 64 | $('body').on('mousedown.pillbox.data-api', '.pillbox', function (e) { 65 | var $this = $(this); 66 | if ($this.data('pillbox')) return; 67 | $this.pillbox($this.data()); 68 | }); 69 | }); 70 | 71 | }); 72 | 73 | -------------------------------------------------------------------------------- /dist/pillbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Pillbox 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(['require','jquery'],function(require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // PILLBOX CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Pillbox = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.pillbox.defaults, options); 19 | this.$element.on('click', 'li', $.proxy(this.itemclicked, this)); 20 | }; 21 | 22 | Pillbox.prototype = { 23 | constructor: Pillbox, 24 | 25 | items: function() { 26 | return this.$element.find('li').map(function() { 27 | var $this = $(this); 28 | return $.extend({ text: $this.text() }, $this.data()); 29 | }).get(); 30 | }, 31 | 32 | itemclicked: function (e) { 33 | $(e.currentTarget).remove(); 34 | e.preventDefault(); 35 | } 36 | }; 37 | 38 | 39 | // PILLBOX PLUGIN DEFINITION 40 | 41 | $.fn.pillbox = function (option) { 42 | var methodReturn; 43 | 44 | var $set = this.each(function () { 45 | var $this = $(this); 46 | var data = $this.data('pillbox'); 47 | var options = typeof option === 'object' && option; 48 | 49 | if (!data) $this.data('pillbox', (data = new Pillbox(this, options))); 50 | if (typeof option === 'string') methodReturn = data[option](); 51 | }); 52 | 53 | return (methodReturn === undefined) ? $set : methodReturn; 54 | }; 55 | 56 | $.fn.pillbox.defaults = {}; 57 | 58 | $.fn.pillbox.Constructor = Pillbox; 59 | 60 | 61 | // PILLBOX DATA-API 62 | 63 | $(function () { 64 | $('body').on('mousedown.pillbox.data-api', '.pillbox', function (e) { 65 | var $this = $(this); 66 | if ($this.data('pillbox')) return; 67 | $this.pillbox($this.data()); 68 | }); 69 | }); 70 | 71 | }); 72 | 73 | -------------------------------------------------------------------------------- /lib/bootstrap/less/responsive-utilities.less: -------------------------------------------------------------------------------- 1 | // 2 | // Responsive: Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // IE10 Metro responsive 7 | // Required for Windows 8 Metro split-screen snapping with IE10 8 | // Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/ 9 | @-ms-viewport{ 10 | width: device-width; 11 | } 12 | 13 | // Hide from screenreaders and browsers 14 | // Credit: HTML5 Boilerplate 15 | .hidden { 16 | display: none; 17 | visibility: hidden; 18 | } 19 | 20 | // Visibility utilities 21 | 22 | // For desktops 23 | .visible-phone { display: none !important; } 24 | .visible-tablet { display: none !important; } 25 | .hidden-phone { } 26 | .hidden-tablet { } 27 | .hidden-desktop { display: none !important; } 28 | .visible-desktop { display: inherit !important; } 29 | 30 | // Tablets & small desktops only 31 | @media (min-width: 768px) and (max-width: 979px) { 32 | // Hide everything else 33 | .hidden-desktop { display: inherit !important; } 34 | .visible-desktop { display: none !important ; } 35 | // Show 36 | .visible-tablet { display: inherit !important; } 37 | // Hide 38 | .hidden-tablet { display: none !important; } 39 | } 40 | 41 | // Phones only 42 | @media (max-width: 767px) { 43 | // Hide everything else 44 | .hidden-desktop { display: inherit !important; } 45 | .visible-desktop { display: none !important; } 46 | // Show 47 | .visible-phone { display: inherit !important; } // Use inherit to restore previous behavior 48 | // Hide 49 | .hidden-phone { display: none !important; } 50 | } 51 | 52 | // Print utilities 53 | .visible-print { display: none !important; } 54 | .hidden-print { } 55 | 56 | @media print { 57 | .visible-print { display: inherit !important; } 58 | .hidden-print { display: none !important; } 59 | } 60 | -------------------------------------------------------------------------------- /lib/bootstrap/less/tooltip.less: -------------------------------------------------------------------------------- 1 | // 2 | // Tooltips 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .tooltip { 8 | position: absolute; 9 | z-index: @zindexTooltip; 10 | display: block; 11 | visibility: visible; 12 | font-size: 11px; 13 | line-height: 1.4; 14 | .opacity(0); 15 | &.in { .opacity(80); } 16 | &.top { margin-top: -3px; padding: 5px 0; } 17 | &.right { margin-left: 3px; padding: 0 5px; } 18 | &.bottom { margin-top: 3px; padding: 5px 0; } 19 | &.left { margin-left: -3px; padding: 0 5px; } 20 | } 21 | 22 | // Wrapper for the tooltip content 23 | .tooltip-inner { 24 | max-width: 200px; 25 | padding: 8px; 26 | color: @tooltipColor; 27 | text-align: center; 28 | text-decoration: none; 29 | background-color: @tooltipBackground; 30 | .border-radius(@baseBorderRadius); 31 | } 32 | 33 | // Arrows 34 | .tooltip-arrow { 35 | position: absolute; 36 | width: 0; 37 | height: 0; 38 | border-color: transparent; 39 | border-style: solid; 40 | } 41 | .tooltip { 42 | &.top .tooltip-arrow { 43 | bottom: 0; 44 | left: 50%; 45 | margin-left: -@tooltipArrowWidth; 46 | border-width: @tooltipArrowWidth @tooltipArrowWidth 0; 47 | border-top-color: @tooltipArrowColor; 48 | } 49 | &.right .tooltip-arrow { 50 | top: 50%; 51 | left: 0; 52 | margin-top: -@tooltipArrowWidth; 53 | border-width: @tooltipArrowWidth @tooltipArrowWidth @tooltipArrowWidth 0; 54 | border-right-color: @tooltipArrowColor; 55 | } 56 | &.left .tooltip-arrow { 57 | top: 50%; 58 | right: 0; 59 | margin-top: -@tooltipArrowWidth; 60 | border-width: @tooltipArrowWidth 0 @tooltipArrowWidth @tooltipArrowWidth; 61 | border-left-color: @tooltipArrowColor; 62 | } 63 | &.bottom .tooltip-arrow { 64 | top: 0; 65 | left: 50%; 66 | margin-left: -@tooltipArrowWidth; 67 | border-width: 0 @tooltipArrowWidth @tooltipArrowWidth; 68 | border-bottom-color: @tooltipArrowColor; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /dist/less/tree.less: -------------------------------------------------------------------------------- 1 | .tree { 2 | 3 | border: 1px solid #BBBBBB; 4 | border-radius: 4px 4px 4px 4px; 5 | overflow-y: auto; 6 | overflow-x: hidden; 7 | padding: 10px 15px 0 15px; 8 | position: relative; 9 | 10 | .tree-folder { 11 | 12 | width: 100%; 13 | min-height: 20px; 14 | cursor: pointer; 15 | margin-top: 1px; 16 | 17 | .tree-folder-header { 18 | 19 | position: relative; 20 | height: 20px; 21 | -webkit-border-radius: 6px; 22 | -moz-border-radius: 6px; 23 | border-radius: 6px; 24 | 25 | &:hover { 26 | background-color: @treeBackgroundHover; 27 | } 28 | 29 | i { 30 | position: absolute; 31 | float: left; 32 | top: 1px; 33 | left: 5px; 34 | } 35 | 36 | .tree-folder-name { 37 | padding-left: 29px; 38 | white-space: nowrap; 39 | overflow: hidden; 40 | text-overflow: ellipsis; 41 | } 42 | 43 | } 44 | 45 | .tree-folder-content { 46 | margin-left: 23px; 47 | } 48 | 49 | } 50 | 51 | .tree-item { 52 | 53 | position: relative; 54 | width: 100%; 55 | height: 20px; 56 | cursor: pointer; 57 | margin-top: 1px; 58 | -webkit-border-radius: 6px; 59 | -moz-border-radius: 6px; 60 | border-radius: 6px; 61 | 62 | &:hover { 63 | background-color: @treeBackgroundHover; 64 | } 65 | 66 | .tree-item-name { 67 | position: absolute; 68 | left: 29px; 69 | } 70 | 71 | .tree-dot { 72 | position: absolute; 73 | top: 8px; 74 | left: 10px; 75 | display: block; 76 | width: 4px; 77 | height: 4px; 78 | background-color: @grayDark; 79 | -webkit-border-radius: 6px; 80 | -moz-border-radius: 6px; 81 | border-radius: 6px; 82 | } 83 | 84 | .icon-ok { 85 | position: absolute; 86 | top: 1px; 87 | left: 5px; 88 | } 89 | 90 | } 91 | 92 | .tree-selected { 93 | background-color: @treeBackgroundSelect; 94 | 95 | &:hover { 96 | background-color: @treeBackgroundSelect; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/less/tree.less: -------------------------------------------------------------------------------- 1 | .tree { 2 | 3 | border: 1px solid #BBBBBB; 4 | border-radius: 4px 4px 4px 4px; 5 | overflow-y: auto; 6 | overflow-x: hidden; 7 | padding: 10px 15px 0 15px; 8 | position: relative; 9 | 10 | .tree-folder { 11 | 12 | width: 100%; 13 | min-height: 20px; 14 | cursor: pointer; 15 | margin-top: 1px; 16 | 17 | .tree-folder-header { 18 | 19 | position: relative; 20 | height: 20px; 21 | -webkit-border-radius: 6px; 22 | -moz-border-radius: 6px; 23 | border-radius: 6px; 24 | 25 | &:hover { 26 | background-color: @treeBackgroundHover; 27 | } 28 | 29 | i { 30 | position: absolute; 31 | float: left; 32 | top: 1px; 33 | left: 5px; 34 | } 35 | 36 | .tree-folder-name { 37 | padding-left: 29px; 38 | white-space: nowrap; 39 | overflow: hidden; 40 | text-overflow: ellipsis; 41 | } 42 | 43 | } 44 | 45 | .tree-folder-content { 46 | margin-left: 23px; 47 | } 48 | 49 | } 50 | 51 | .tree-item { 52 | 53 | position: relative; 54 | width: 100%; 55 | height: 20px; 56 | cursor: pointer; 57 | margin-top: 1px; 58 | -webkit-border-radius: 6px; 59 | -moz-border-radius: 6px; 60 | border-radius: 6px; 61 | 62 | &:hover { 63 | background-color: @treeBackgroundHover; 64 | } 65 | 66 | .tree-item-name { 67 | position: absolute; 68 | left: 29px; 69 | } 70 | 71 | .tree-dot { 72 | position: absolute; 73 | top: 8px; 74 | left: 10px; 75 | display: block; 76 | width: 4px; 77 | height: 4px; 78 | background-color: @grayDark; 79 | -webkit-border-radius: 6px; 80 | -moz-border-radius: 6px; 81 | border-radius: 6px; 82 | } 83 | 84 | .icon-ok { 85 | position: absolute; 86 | top: 1px; 87 | left: 5px; 88 | } 89 | 90 | } 91 | 92 | .tree-selected { 93 | background-color: @treeBackgroundSelect; 94 | 95 | &:hover { 96 | background-color: @treeBackgroundSelect; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/bootstrap/js/bootstrap-transition.js: -------------------------------------------------------------------------------- 1 | //Wrapped in an outer function to preserve global this 2 | (function (root) { var amdExports; define(['jquery'], function () { (function () { 3 | 4 | /* =================================================== 5 | * bootstrap-transition.js v2.3.2 6 | * http://twitter.github.com/bootstrap/javascript.html#transitions 7 | * =================================================== 8 | * Copyright 2012 Twitter, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * ========================================================== */ 22 | 23 | 24 | !function ($) { 25 | 26 | "use strict"; // jshint ;_; 27 | 28 | 29 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) 30 | * ======================================================= */ 31 | 32 | $(function () { 33 | 34 | $.support.transition = (function () { 35 | 36 | var transitionEnd = (function () { 37 | 38 | var el = document.createElement('bootstrap') 39 | , transEndEventNames = { 40 | 'WebkitTransition' : 'webkitTransitionEnd' 41 | , 'MozTransition' : 'transitionend' 42 | , 'OTransition' : 'oTransitionEnd otransitionend' 43 | , 'transition' : 'transitionend' 44 | } 45 | , name 46 | 47 | for (name in transEndEventNames){ 48 | if (el.style[name] !== undefined) { 49 | return transEndEventNames[name] 50 | } 51 | } 52 | 53 | }()) 54 | 55 | return transitionEnd && { 56 | end: transitionEnd 57 | } 58 | 59 | })() 60 | 61 | }) 62 | 63 | }(window.jQuery); 64 | 65 | 66 | }.call(root)); 67 | return amdExports; 68 | }); }(this)); 69 | -------------------------------------------------------------------------------- /lib/bootstrap/less/labels-badges.less: -------------------------------------------------------------------------------- 1 | // 2 | // Labels and badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base classes 7 | .label, 8 | .badge { 9 | display: inline-block; 10 | padding: 2px 4px; 11 | font-size: @baseFontSize * .846; 12 | font-weight: bold; 13 | line-height: 14px; // ensure proper line-height if floated 14 | color: @white; 15 | vertical-align: baseline; 16 | white-space: nowrap; 17 | text-shadow: 0 -1px 0 rgba(0,0,0,.25); 18 | background-color: @grayLight; 19 | } 20 | // Set unique padding and border-radii 21 | .label { 22 | .border-radius(3px); 23 | } 24 | .badge { 25 | padding-left: 9px; 26 | padding-right: 9px; 27 | .border-radius(9px); 28 | } 29 | 30 | // Empty labels/badges collapse 31 | .label, 32 | .badge { 33 | &:empty { 34 | display: none; 35 | } 36 | } 37 | 38 | // Hover/focus state, but only for links 39 | a { 40 | &.label:hover, 41 | &.label:focus, 42 | &.badge:hover, 43 | &.badge:focus { 44 | color: @white; 45 | text-decoration: none; 46 | cursor: pointer; 47 | } 48 | } 49 | 50 | // Colors 51 | // Only give background-color difference to links (and to simplify, we don't qualifty with `a` but [href] attribute) 52 | .label, 53 | .badge { 54 | // Important (red) 55 | &-important { background-color: @errorText; } 56 | &-important[href] { background-color: darken(@errorText, 10%); } 57 | // Warnings (orange) 58 | &-warning { background-color: @orange; } 59 | &-warning[href] { background-color: darken(@orange, 10%); } 60 | // Success (green) 61 | &-success { background-color: @successText; } 62 | &-success[href] { background-color: darken(@successText, 10%); } 63 | // Info (turquoise) 64 | &-info { background-color: @infoText; } 65 | &-info[href] { background-color: darken(@infoText, 10%); } 66 | // Inverse (black) 67 | &-inverse { background-color: @grayDark; } 68 | &-inverse[href] { background-color: darken(@grayDark, 10%); } 69 | } 70 | 71 | // Quick fix for labels/badges in buttons 72 | .btn { 73 | .label, 74 | .badge { 75 | position: relative; 76 | top: -1px; 77 | } 78 | } 79 | .btn-mini { 80 | .label, 81 | .badge { 82 | top: 0; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /test/fuelux-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/all'], function($) { 6 | 7 | module('Twitter Bootstrap plugins', { 8 | setup: function() { 9 | this.elems = $('#qunit-fixture').children(); 10 | } 11 | }); 12 | 13 | test('transitions are initialized', function() { 14 | strictEqual(typeof $.support.transition, 'object', 'transitions should be initialized'); 15 | }); 16 | 17 | test('modal is initialized', function() { 18 | ok(this.elems.modal() === this.elems, 'modal should be initilized'); 19 | }); 20 | 21 | test('dropdown is initialized', function() { 22 | ok(this.elems.dropdown() === this.elems, 'dropdown should be initialized'); 23 | }); 24 | 25 | test('scrollspy is initialized', function() { 26 | ok(this.elems.scrollspy() === this.elems, 'scrollspy should be initialized'); 27 | }); 28 | 29 | test('tab is initialized', function() { 30 | ok(this.elems.tab() === this.elems, 'tab should be initialized'); 31 | }); 32 | 33 | test('tooltip is initialized', function() { 34 | ok(this.elems.tooltip() === this.elems, 'tooltip should be initialized'); 35 | }); 36 | 37 | test('popover is initialized', function() { 38 | ok(this.elems.popover() === this.elems, 'popover should be initialized'); 39 | }); 40 | 41 | test('affix is initialized', function() { 42 | ok(this.elems.affix() === this.elems, 'affix should be initialized'); 43 | }); 44 | 45 | test('alert is initialized', function() { 46 | ok(this.elems.alert() === this.elems, 'alert should be initialized'); 47 | }); 48 | 49 | test('button is initialized', function() { 50 | ok(this.elems.button() === this.elems, 'button should be initialized'); 51 | }); 52 | 53 | test('collapse is initialized', function() { 54 | ok(this.elems.collapse() === this.elems, 'collapse should be initialized'); 55 | }); 56 | 57 | test('carousel is initialized', function() { 58 | ok(this.elems.carousel() === this.elems, 'carousel should be initialized'); 59 | }); 60 | 61 | test('typeahead is initialized', function() { 62 | ok(this.elems.typeahead() === this.elems, 'typeahead should be initialized'); 63 | }); 64 | }); -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bootstrap Plugin Test Suite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
    49 |

    Bootstrap Plugin Test Suite

    50 |

    51 |

    52 |
      53 |
      54 |
      55 | 56 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-alert.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-alerts") 4 | 5 | test("should provide no conflict", function () { 6 | var alert = $.fn.alert.noConflict() 7 | ok(!$.fn.alert, 'alert was set back to undefined (org value)') 8 | $.fn.alert = alert 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).alert, 'alert method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).alert()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should fade element out on clicking .close", function () { 20 | var alertHTML = '
      ' 21 | + '×' 22 | + '

      Holy guacamole! Best check yo self, you\'re not looking too good.

      ' 23 | + '
      ' 24 | , alert = $(alertHTML).alert() 25 | 26 | alert.find('.close').click() 27 | 28 | ok(!alert.hasClass('in'), 'remove .in class on .close click') 29 | }) 30 | 31 | test("should remove element when clicking .close", function () { 32 | $.support.transition = false 33 | 34 | var alertHTML = '
      ' 35 | + '×' 36 | + '

      Holy guacamole! Best check yo self, you\'re not looking too good.

      ' 37 | + '
      ' 38 | , alert = $(alertHTML).appendTo('#qunit-fixture').alert() 39 | 40 | ok($('#qunit-fixture').find('.alert-message').length, 'element added to dom') 41 | 42 | alert.find('.close').click() 43 | 44 | ok(!$('#qunit-fixture').find('.alert-message').length, 'element removed from dom') 45 | }) 46 | 47 | test("should not fire closed when close is prevented", function () { 48 | $.support.transition = false 49 | stop(); 50 | $('
      ') 51 | .bind('close', function (e) { 52 | e.preventDefault(); 53 | ok(true); 54 | start(); 55 | }) 56 | .bind('closed', function () { 57 | ok(false); 58 | }) 59 | .alert('close') 60 | }) 61 | 62 | }) -------------------------------------------------------------------------------- /lib/bootstrap/less/modals.less: -------------------------------------------------------------------------------- 1 | // 2 | // Modals 3 | // -------------------------------------------------- 4 | 5 | // Background 6 | .modal-backdrop { 7 | position: fixed; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: @zindexModalBackdrop; 13 | background-color: @black; 14 | // Fade for backdrop 15 | &.fade { opacity: 0; } 16 | } 17 | 18 | .modal-backdrop, 19 | .modal-backdrop.fade.in { 20 | .opacity(80); 21 | } 22 | 23 | // Base modal 24 | .modal { 25 | position: fixed; 26 | top: 10%; 27 | left: 50%; 28 | z-index: @zindexModal; 29 | width: 560px; 30 | margin-left: -280px; 31 | background-color: @white; 32 | border: 1px solid #999; 33 | border: 1px solid rgba(0,0,0,.3); 34 | *border: 1px solid #999; /* IE6-7 */ 35 | .border-radius(6px); 36 | .box-shadow(0 3px 7px rgba(0,0,0,0.3)); 37 | .background-clip(padding-box); 38 | // Remove focus outline from opened modal 39 | outline: none; 40 | 41 | &.fade { 42 | .transition(e('opacity .3s linear, top .3s ease-out')); 43 | top: -25%; 44 | } 45 | &.fade.in { top: 10%; } 46 | } 47 | .modal-header { 48 | padding: 9px 15px; 49 | border-bottom: 1px solid #eee; 50 | // Close icon 51 | .close { margin-top: 2px; } 52 | // Heading 53 | h3 { 54 | margin: 0; 55 | line-height: 30px; 56 | } 57 | } 58 | 59 | // Body (where all modal content resides) 60 | .modal-body { 61 | position: relative; 62 | overflow-y: auto; 63 | max-height: 400px; 64 | padding: 15px; 65 | } 66 | // Remove bottom margin if need be 67 | .modal-form { 68 | margin-bottom: 0; 69 | } 70 | 71 | // Footer (for actions) 72 | .modal-footer { 73 | padding: 14px 15px 15px; 74 | margin-bottom: 0; 75 | text-align: right; // right align buttons 76 | background-color: #f5f5f5; 77 | border-top: 1px solid #ddd; 78 | .border-radius(0 0 6px 6px); 79 | .box-shadow(inset 0 1px 0 @white); 80 | .clearfix(); // clear it in case folks use .pull-* classes on buttons 81 | 82 | // Properly space out buttons 83 | .btn + .btn { 84 | margin-left: 5px; 85 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs 86 | } 87 | // but override that for button groups 88 | .btn-group .btn + .btn { 89 | margin-left: -1px; 90 | } 91 | // and override it for block buttons as well 92 | .btn-block + .btn-block { 93 | margin-left: 0; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/phantom.js: -------------------------------------------------------------------------------- 1 | // Simple phantom.js integration script 2 | // Adapted from Modernizr 3 | 4 | function waitFor(testFx, onReady, timeOutMillis) { 5 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 5001 //< Default Max Timout is 5s 6 | , start = new Date().getTime() 7 | , condition = false 8 | , interval = setInterval(function () { 9 | if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { 10 | // If not time-out yet and condition not yet fulfilled 11 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()) //< defensive code 12 | } else { 13 | if (!condition) { 14 | // If condition still not fulfilled (timeout but condition is 'false') 15 | console.log("'waitFor()' timeout") 16 | phantom.exit(1) 17 | } else { 18 | // Condition fulfilled (timeout and/or condition is 'true') 19 | typeof(onReady) === "string" ? eval(onReady) : onReady() //< Do what it's supposed to do once the condition is fulfilled 20 | clearInterval(interval) //< Stop this interval 21 | } 22 | } 23 | }, 100) //< repeat check every 100ms 24 | } 25 | 26 | 27 | if (phantom.args.length === 0 || phantom.args.length > 2) { 28 | console.log('Usage: phantom.js URL') 29 | phantom.exit() 30 | } 31 | 32 | var page = new WebPage() 33 | 34 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 35 | page.onConsoleMessage = function(msg) { 36 | console.log(msg) 37 | }; 38 | 39 | page.open(phantom.args[0], function(status){ 40 | if (status !== "success") { 41 | console.log("Unable to access network") 42 | phantom.exit() 43 | } else { 44 | waitFor(function(){ 45 | return page.evaluate(function(){ 46 | var el = document.getElementById('qunit-testresult') 47 | if (el && el.innerText.match('completed')) { 48 | return true 49 | } 50 | return false 51 | }) 52 | }, function(){ 53 | var failedNum = page.evaluate(function(){ 54 | var el = document.getElementById('qunit-testresult') 55 | try { 56 | return el.getElementsByClassName('failed')[0].innerHTML 57 | } catch (e) { } 58 | return 10000 59 | }); 60 | phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0) 61 | }) 62 | } 63 | }) -------------------------------------------------------------------------------- /sample/datasource.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Data components - static data source 3 | * https://github.com/ExactTarget/fuelux-data 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | (function (root, factory) { 10 | if (typeof define === 'function' && define.amd) { 11 | define(['underscore'], factory); 12 | } else { 13 | root.StaticDataSource = factory(); 14 | } 15 | }(this, function () { 16 | 17 | var StaticDataSource = function (options) { 18 | this._formatter = options.formatter; 19 | this._columns = options.columns; 20 | this._delay = options.delay || 0; 21 | this._data = options.data; 22 | }; 23 | 24 | StaticDataSource.prototype = { 25 | 26 | columns: function () { 27 | return this._columns; 28 | }, 29 | 30 | data: function (options, callback) { 31 | var self = this; 32 | 33 | setTimeout(function () { 34 | var data = $.extend(true, [], self._data); 35 | 36 | // SEARCHING 37 | if (options.search) { 38 | data = _.filter(data, function (item) { 39 | var match = false; 40 | 41 | _.each(item, function (prop) { 42 | if (_.isString(prop) || _.isFinite(prop)) { 43 | if (prop.toString().toLowerCase().indexOf(options.search.toLowerCase()) !== -1) match = true; 44 | } 45 | }); 46 | 47 | return match; 48 | }); 49 | } 50 | 51 | // FILTERING 52 | if (options.filter) { 53 | data = _.filter(data, function (item) { 54 | switch(options.filter.value) { 55 | case 'lt5m': 56 | if(item.population < 5000000) return true; 57 | break; 58 | case 'gte5m': 59 | if(item.population >= 5000000) return true; 60 | break; 61 | default: 62 | return true; 63 | break; 64 | } 65 | }); 66 | } 67 | 68 | var count = data.length; 69 | 70 | // SORTING 71 | if (options.sortProperty) { 72 | data = _.sortBy(data, options.sortProperty); 73 | if (options.sortDirection === 'desc') data.reverse(); 74 | } 75 | 76 | // PAGING 77 | var startIndex = options.pageIndex * options.pageSize; 78 | var endIndex = startIndex + options.pageSize; 79 | var end = (endIndex > count) ? count : endIndex; 80 | var pages = Math.ceil(count / options.pageSize); 81 | var page = options.pageIndex + 1; 82 | var start = startIndex + 1; 83 | 84 | data = data.slice(startIndex, endIndex); 85 | 86 | if (self._formatter) self._formatter(data); 87 | 88 | callback({ data: data, start: start, end: end, count: count, pages: pages, page: page }); 89 | 90 | }, this._delay) 91 | } 92 | }; 93 | 94 | return StaticDataSource; 95 | })); 96 | -------------------------------------------------------------------------------- /lib/bootstrap/less/tests/forms-responsive.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Bootstrap, from Twitter 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
      36 | 37 | 40 | 41 |

      Vertical alignment

      42 | 43 | 44 | span1 45 | 46 |

      Width across elements

      47 |
      48 | 49 |
      50 |
      51 | 52 |
      53 |
      54 | span2 55 |
      56 | 57 | 58 | 61 | 62 |
      63 | 64 | 65 | span1 66 |
      67 | 68 |
      69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/radio-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/radio'], function ($) { 6 | 7 | var html = '
      ' + 8 | '' + 9 | '' + 10 | '' + 11 | '' + 12 | '
      '; 13 | 14 | module("Fuel UX radio"); 15 | 16 | test("should be defined on jquery object", function () { 17 | ok($(document.body).radio, 'radio method is defined'); 18 | }); 19 | 20 | test("should return element", function () { 21 | ok($(document.body).radio()[0] === document.body, 'document.body returned'); 22 | }); 23 | 24 | test("should set initial state", function () { 25 | var $list = $(html); 26 | var $radios = $list.find('input').radio(); 27 | 28 | // checked/enabled 29 | var i1 = $list.find('#lbl1 i'); 30 | equal(i1.hasClass('checked'), true, 'radio1 has checked class'); 31 | equal(i1.hasClass('disabled'), false, 'radio1 does not have disabled class'); 32 | 33 | // unchecked/enabled 34 | var i2 = $list.find('#lbl2 i'); 35 | equal(i2.hasClass('checked'), false, 'radio2 does not have checked class'); 36 | equal(i2.hasClass('disabled'), false, 'radio2 does not have disabled class'); 37 | 38 | // checked/disabled 39 | var i3 = $list.find('#lbl3 i'); 40 | equal(i3.hasClass('checked'), true, 'radio3 has checked class'); 41 | equal(i3.hasClass('disabled'), true, 'radio3 has disabled class'); 42 | 43 | // unchecked/disabled 44 | var i4 = $list.find('#lbl4 i'); 45 | equal(i4.hasClass('checked'), false, 'radio4 does not have checked class'); 46 | equal(i4.hasClass('disabled'), true, 'radio4 has disabled class'); 47 | }); 48 | 49 | test("should disable/enable radio", function () { 50 | var $radio1 = $(html).find('#radio1'); 51 | 52 | equal($radio1.is(':disabled'), false, 'enabled - default state'); 53 | $radio1.radio('disable'); 54 | equal($radio1.is(':disabled'), true, 'disabled'); 55 | $radio1.radio('enable'); 56 | equal($radio1.is(':disabled'), false, 're-enabled'); 57 | }); 58 | 59 | }); -------------------------------------------------------------------------------- /test/spinner-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/spinner'], function($) { 6 | 7 | module("Fuel UX spinner"); 8 | 9 | test("should be defined on jquery object", function () { 10 | ok($(document.body).spinner, 'spinner method is defined'); 11 | }); 12 | 13 | test("should return element", function () { 14 | ok($(document.body).spinner()[0] === document.body, 'document.body returned'); 15 | }); 16 | 17 | var spinnerHTML = '
      ' + 18 | '' + 19 | '' + 22 | '' + 25 | '
      '; 26 | 27 | test("should behave as designed", function () { 28 | var $spinner = $(spinnerHTML).spinner(); 29 | 30 | //returning default value 31 | equal($spinner.spinner('value'), 1, 'spinner returns selected item'); 32 | 33 | //set number value 34 | $spinner.spinner('value',2); 35 | equal($spinner.spinner('value'), 2, 'spinner sets number value'); 36 | 37 | //set numeric string value 38 | $spinner.spinner('value','2.1'); 39 | equal($spinner.spinner('value'), 2.1, 'spinner sets floating point numeric string value'); 40 | 41 | $spinner.spinner('value','2'); 42 | equal($spinner.spinner('value'), 2, 'spinner sets integer numeric string value'); 43 | 44 | //disable 45 | $spinner.spinner('disable'); 46 | equal($spinner.find('.spinner-input').attr('disabled'), "disabled", 'spinner sets disabled'); 47 | 48 | //enable 49 | $spinner.spinner('enable'); 50 | equal($spinner.find('.spinner-input').attr('disabled') ? false : true, true, 'spinner sets enabled'); 51 | 52 | //change 53 | $spinner.spinner('value','b2'); 54 | $spinner.spinner('change'); 55 | equal($spinner.spinner('value'), 2, 'spinner change not working for alpha strings'); 56 | 57 | //increment positive 58 | $spinner.spinner('step',true); 59 | equal($spinner.spinner('value'), 3, 'spinner increments positive'); 60 | 61 | //increment nagative 62 | $spinner.spinner('step',false); 63 | equal($spinner.spinner('value'), 2, 'spinner increments negative'); 64 | 65 | }); 66 | 67 | test("should allow setting value to zero", function () { 68 | var $spinner = $(spinnerHTML).spinner(); 69 | $spinner.spinner('value', 0); 70 | equal($spinner.spinner('value'), 0, 'spinner value was set to zero'); 71 | }); 72 | 73 | }); 74 | -------------------------------------------------------------------------------- /src/checkbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Checkbox 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function (require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // CHECKBOX CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Checkbox = function (element, options) { 17 | 18 | this.$element = $(element); 19 | this.options = $.extend({}, $.fn.checkbox.defaults, options); 20 | 21 | // cache elements 22 | this.$label = this.$element.parent(); 23 | this.$icon = this.$label.find('i'); 24 | this.$chk = this.$label.find('input[type=checkbox]'); 25 | 26 | // set default state 27 | this.setState(this.$chk); 28 | 29 | // handle events 30 | this.$chk.on('change', $.proxy(this.itemchecked, this)); 31 | }; 32 | 33 | Checkbox.prototype = { 34 | 35 | constructor: Checkbox, 36 | 37 | setState: function ($chk) { 38 | var checked = $chk.is(':checked'); 39 | var disabled = $chk.is(':disabled'); 40 | 41 | // reset classes 42 | this.$icon.removeClass('checked').removeClass('disabled'); 43 | 44 | // set state of checkbox 45 | if (checked === true) { 46 | this.$icon.addClass('checked'); 47 | } 48 | if (disabled === true) { 49 | this.$icon.addClass('disabled'); 50 | } 51 | }, 52 | 53 | enable: function () { 54 | this.$chk.attr('disabled', false); 55 | this.$icon.removeClass('disabled'); 56 | }, 57 | 58 | disable: function () { 59 | this.$chk.attr('disabled', true); 60 | this.$icon.addClass('disabled'); 61 | }, 62 | 63 | toggle: function () { 64 | this.$chk.click(); 65 | }, 66 | 67 | itemchecked: function (e) { 68 | var chk = $(e.target); 69 | this.setState(chk); 70 | } 71 | }; 72 | 73 | 74 | // CHECKBOX PLUGIN DEFINITION 75 | 76 | $.fn.checkbox = function (option, value) { 77 | var methodReturn; 78 | 79 | var $set = this.each(function () { 80 | var $this = $(this); 81 | var data = $this.data('checkbox'); 82 | var options = typeof option === 'object' && option; 83 | 84 | if (!data) $this.data('checkbox', (data = new Checkbox(this, options))); 85 | if (typeof option === 'string') methodReturn = data[option](value); 86 | }); 87 | 88 | return (methodReturn === undefined) ? $set : methodReturn; 89 | }; 90 | 91 | $.fn.checkbox.defaults = {}; 92 | 93 | $.fn.checkbox.Constructor = Checkbox; 94 | 95 | 96 | // CHECKBOX DATA-API 97 | 98 | $(function () { 99 | $(window).on('load', function () { 100 | //$('i.checkbox').each(function () { 101 | $('.checkbox-custom > input[type=checkbox]').each(function () { 102 | var $this = $(this); 103 | if ($this.data('checkbox')) return; 104 | $this.checkbox($this.data()); 105 | }); 106 | }); 107 | }); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /dist/checkbox.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Checkbox 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(['require','jquery'],function (require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // CHECKBOX CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Checkbox = function (element, options) { 17 | 18 | this.$element = $(element); 19 | this.options = $.extend({}, $.fn.checkbox.defaults, options); 20 | 21 | // cache elements 22 | this.$label = this.$element.parent(); 23 | this.$icon = this.$label.find('i'); 24 | this.$chk = this.$label.find('input[type=checkbox]'); 25 | 26 | // set default state 27 | this.setState(this.$chk); 28 | 29 | // handle events 30 | this.$chk.on('change', $.proxy(this.itemchecked, this)); 31 | }; 32 | 33 | Checkbox.prototype = { 34 | 35 | constructor: Checkbox, 36 | 37 | setState: function ($chk) { 38 | var checked = $chk.is(':checked'); 39 | var disabled = $chk.is(':disabled'); 40 | 41 | // reset classes 42 | this.$icon.removeClass('checked').removeClass('disabled'); 43 | 44 | // set state of checkbox 45 | if (checked === true) { 46 | this.$icon.addClass('checked'); 47 | } 48 | if (disabled === true) { 49 | this.$icon.addClass('disabled'); 50 | } 51 | }, 52 | 53 | enable: function () { 54 | this.$chk.attr('disabled', false); 55 | this.$icon.removeClass('disabled'); 56 | }, 57 | 58 | disable: function () { 59 | this.$chk.attr('disabled', true); 60 | this.$icon.addClass('disabled'); 61 | }, 62 | 63 | toggle: function () { 64 | this.$chk.click(); 65 | }, 66 | 67 | itemchecked: function (e) { 68 | var chk = $(e.target); 69 | this.setState(chk); 70 | } 71 | }; 72 | 73 | 74 | // CHECKBOX PLUGIN DEFINITION 75 | 76 | $.fn.checkbox = function (option, value) { 77 | var methodReturn; 78 | 79 | var $set = this.each(function () { 80 | var $this = $(this); 81 | var data = $this.data('checkbox'); 82 | var options = typeof option === 'object' && option; 83 | 84 | if (!data) $this.data('checkbox', (data = new Checkbox(this, options))); 85 | if (typeof option === 'string') methodReturn = data[option](value); 86 | }); 87 | 88 | return (methodReturn === undefined) ? $set : methodReturn; 89 | }; 90 | 91 | $.fn.checkbox.defaults = {}; 92 | 93 | $.fn.checkbox.Constructor = Checkbox; 94 | 95 | 96 | // CHECKBOX DATA-API 97 | 98 | $(function () { 99 | $(window).on('load', function () { 100 | //$('i.checkbox').each(function () { 101 | $('.checkbox-custom > input[type=checkbox]').each(function () { 102 | var $this = $(this); 103 | if ($this.data('checkbox')) return; 104 | $this.checkbox($this.data()); 105 | }); 106 | }); 107 | }); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /src/radio.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Radio 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function (require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // RADIO CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Radio = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.radio.defaults, options); 19 | 20 | // cache elements 21 | this.$label = this.$element.parent(); 22 | this.$icon = this.$label.find('i'); 23 | this.$radio = this.$label.find('input[type=radio]'); 24 | this.groupName = this.$radio.attr('name'); 25 | 26 | // set default state 27 | this.setState(this.$radio); 28 | 29 | // handle events 30 | this.$radio.on('change', $.proxy(this.itemchecked, this)); 31 | }; 32 | 33 | Radio.prototype = { 34 | 35 | constructor: Radio, 36 | 37 | setState: function ($radio, resetGroupState) { 38 | var checked = $radio.is(':checked'); 39 | var disabled = $radio.is(':disabled'); 40 | 41 | // set state of radio 42 | if (checked === true) { 43 | this.$icon.addClass('checked'); 44 | } 45 | if (disabled === true) { 46 | this.$icon.addClass('disabled'); 47 | } 48 | }, 49 | 50 | resetGroup: function () { 51 | // reset all radio buttons in group 52 | $('input[name=' + this.groupName + ']').next().removeClass('checked'); 53 | }, 54 | 55 | enable: function () { 56 | this.$radio.attr('disabled', false); 57 | this.$icon.removeClass('disabled'); 58 | }, 59 | 60 | disable: function () { 61 | this.$radio.attr('disabled', true); 62 | this.$icon.addClass('disabled'); 63 | }, 64 | 65 | itemchecked: function (e) { 66 | var radio = $(e.target); 67 | 68 | this.resetGroup(); 69 | this.setState(radio); 70 | } 71 | }; 72 | 73 | 74 | // RADIO PLUGIN DEFINITION 75 | 76 | $.fn.radio = function (option, value) { 77 | var methodReturn; 78 | 79 | var $set = this.each(function () { 80 | var $this = $(this); 81 | var data = $this.data('radio'); 82 | var options = typeof option === 'object' && option; 83 | 84 | if (!data) $this.data('radio', (data = new Radio(this, options))); 85 | if (typeof option === 'string') methodReturn = data[option](value); 86 | }); 87 | 88 | return (methodReturn === undefined) ? $set : methodReturn; 89 | }; 90 | 91 | $.fn.radio.defaults = {}; 92 | 93 | $.fn.radio.Constructor = Radio; 94 | 95 | 96 | // RADIO DATA-API 97 | 98 | $(function () { 99 | $(window).on('load', function () { 100 | //$('i.radio').each(function () { 101 | $('.radio-custom > input[type=radio]').each(function () { 102 | var $this = $(this); 103 | if ($this.data('radio')) return; 104 | $this.radio($this.data()); 105 | }); 106 | }); 107 | }); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /dist/radio.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Radio 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(['require','jquery'],function (require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // RADIO CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Radio = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.radio.defaults, options); 19 | 20 | // cache elements 21 | this.$label = this.$element.parent(); 22 | this.$icon = this.$label.find('i'); 23 | this.$radio = this.$label.find('input[type=radio]'); 24 | this.groupName = this.$radio.attr('name'); 25 | 26 | // set default state 27 | this.setState(this.$radio); 28 | 29 | // handle events 30 | this.$radio.on('change', $.proxy(this.itemchecked, this)); 31 | }; 32 | 33 | Radio.prototype = { 34 | 35 | constructor: Radio, 36 | 37 | setState: function ($radio, resetGroupState) { 38 | var checked = $radio.is(':checked'); 39 | var disabled = $radio.is(':disabled'); 40 | 41 | // set state of radio 42 | if (checked === true) { 43 | this.$icon.addClass('checked'); 44 | } 45 | if (disabled === true) { 46 | this.$icon.addClass('disabled'); 47 | } 48 | }, 49 | 50 | resetGroup: function () { 51 | // reset all radio buttons in group 52 | $('input[name=' + this.groupName + ']').next().removeClass('checked'); 53 | }, 54 | 55 | enable: function () { 56 | this.$radio.attr('disabled', false); 57 | this.$icon.removeClass('disabled'); 58 | }, 59 | 60 | disable: function () { 61 | this.$radio.attr('disabled', true); 62 | this.$icon.addClass('disabled'); 63 | }, 64 | 65 | itemchecked: function (e) { 66 | var radio = $(e.target); 67 | 68 | this.resetGroup(); 69 | this.setState(radio); 70 | } 71 | }; 72 | 73 | 74 | // RADIO PLUGIN DEFINITION 75 | 76 | $.fn.radio = function (option, value) { 77 | var methodReturn; 78 | 79 | var $set = this.each(function () { 80 | var $this = $(this); 81 | var data = $this.data('radio'); 82 | var options = typeof option === 'object' && option; 83 | 84 | if (!data) $this.data('radio', (data = new Radio(this, options))); 85 | if (typeof option === 'string') methodReturn = data[option](value); 86 | }); 87 | 88 | return (methodReturn === undefined) ? $set : methodReturn; 89 | }; 90 | 91 | $.fn.radio.defaults = {}; 92 | 93 | $.fn.radio.Constructor = Radio; 94 | 95 | 96 | // RADIO DATA-API 97 | 98 | $(function () { 99 | $(window).on('load', function () { 100 | //$('i.radio').each(function () { 101 | $('.radio-custom > input[type=radio]').each(function () { 102 | var $this = $(this); 103 | if ($this.data('radio')) return; 104 | $this.radio($this.data()); 105 | }); 106 | }); 107 | }); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /src/less/fuelux.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .fuelux { 12 | 13 | // Core variables and mixins 14 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 15 | @import "../../lib/bootstrap/less/mixins.less"; 16 | 17 | // CSS Reset 18 | @import "../../lib/bootstrap/less/reset.less"; 19 | 20 | // Grid system and page structure 21 | @import "../../lib/bootstrap/less/scaffolding.less"; 22 | @import "../../lib/bootstrap/less/grid.less"; 23 | @import "../../lib/bootstrap/less/layouts.less"; 24 | 25 | // Base CSS 26 | @import "../../lib/bootstrap/less/type.less"; 27 | @import "../../lib/bootstrap/less/code.less"; 28 | @import "../../lib/bootstrap/less/forms.less"; 29 | @import "../../lib/bootstrap/less/tables.less"; 30 | 31 | // Components: common 32 | @import "../../lib/bootstrap/less/sprites.less"; 33 | @import "../../lib/bootstrap/less/dropdowns.less"; 34 | @import "../../lib/bootstrap/less/wells.less"; 35 | @import "../../lib/bootstrap/less/component-animations.less"; 36 | @import "../../lib/bootstrap/less/close.less"; 37 | 38 | // Components: Buttons & Alerts 39 | @import "../../lib/bootstrap/less/buttons.less"; 40 | @import "../../lib/bootstrap/less/button-groups.less"; 41 | @import "../../lib/bootstrap/less/alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less 42 | 43 | // Components: Nav 44 | @import "../../lib/bootstrap/less/navs.less"; 45 | @import "../../lib/bootstrap/less/navbar.less"; 46 | @import "../../lib/bootstrap/less/breadcrumbs.less"; 47 | @import "../../lib/bootstrap/less/pagination.less"; 48 | @import "../../lib/bootstrap/less/pager.less"; 49 | 50 | // Components: Popovers 51 | @import "../../lib/bootstrap/less/modals.less"; 52 | @import "../../lib/bootstrap/less/tooltip.less"; 53 | @import "../../lib/bootstrap/less/popovers.less"; 54 | 55 | // Components: Misc 56 | @import "../../lib/bootstrap/less/thumbnails.less"; 57 | @import "../../lib/bootstrap/less/media.less"; 58 | @import "../../lib/bootstrap/less/labels-badges.less"; 59 | @import "../../lib/bootstrap/less/progress-bars.less"; 60 | @import "../../lib/bootstrap/less/accordion.less"; 61 | @import "../../lib/bootstrap/less/carousel.less"; 62 | @import "../../lib/bootstrap/less/hero-unit.less"; 63 | 64 | // Utility classes 65 | @import "../../lib/bootstrap/less/utilities.less"; // Has to be last to override when necessary 66 | 67 | // Fuel UX controls 68 | @import "checkbox.less"; 69 | @import "combobox.less"; 70 | @import "datagrid.less"; 71 | @import "pillbox.less"; 72 | @import "radio.less"; 73 | @import "spinner.less"; 74 | @import "search.less"; 75 | @import "select.less"; 76 | @import "tree.less"; 77 | @import "wizard.less"; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /dist/less/fuelux.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .fuelux { 12 | 13 | // Core variables and mixins 14 | @import "variables.less"; // Modify this for custom colors, font-sizes, etc 15 | @import "../../lib/bootstrap/less/mixins.less"; 16 | 17 | // CSS Reset 18 | @import "../../lib/bootstrap/less/reset.less"; 19 | 20 | // Grid system and page structure 21 | @import "../../lib/bootstrap/less/scaffolding.less"; 22 | @import "../../lib/bootstrap/less/grid.less"; 23 | @import "../../lib/bootstrap/less/layouts.less"; 24 | 25 | // Base CSS 26 | @import "../../lib/bootstrap/less/type.less"; 27 | @import "../../lib/bootstrap/less/code.less"; 28 | @import "../../lib/bootstrap/less/forms.less"; 29 | @import "../../lib/bootstrap/less/tables.less"; 30 | 31 | // Components: common 32 | @import "../../lib/bootstrap/less/sprites.less"; 33 | @import "../../lib/bootstrap/less/dropdowns.less"; 34 | @import "../../lib/bootstrap/less/wells.less"; 35 | @import "../../lib/bootstrap/less/component-animations.less"; 36 | @import "../../lib/bootstrap/less/close.less"; 37 | 38 | // Components: Buttons & Alerts 39 | @import "../../lib/bootstrap/less/buttons.less"; 40 | @import "../../lib/bootstrap/less/button-groups.less"; 41 | @import "../../lib/bootstrap/less/alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less 42 | 43 | // Components: Nav 44 | @import "../../lib/bootstrap/less/navs.less"; 45 | @import "../../lib/bootstrap/less/navbar.less"; 46 | @import "../../lib/bootstrap/less/breadcrumbs.less"; 47 | @import "../../lib/bootstrap/less/pagination.less"; 48 | @import "../../lib/bootstrap/less/pager.less"; 49 | 50 | // Components: Popovers 51 | @import "../../lib/bootstrap/less/modals.less"; 52 | @import "../../lib/bootstrap/less/tooltip.less"; 53 | @import "../../lib/bootstrap/less/popovers.less"; 54 | 55 | // Components: Misc 56 | @import "../../lib/bootstrap/less/thumbnails.less"; 57 | @import "../../lib/bootstrap/less/media.less"; 58 | @import "../../lib/bootstrap/less/labels-badges.less"; 59 | @import "../../lib/bootstrap/less/progress-bars.less"; 60 | @import "../../lib/bootstrap/less/accordion.less"; 61 | @import "../../lib/bootstrap/less/carousel.less"; 62 | @import "../../lib/bootstrap/less/hero-unit.less"; 63 | 64 | // Utility classes 65 | @import "../../lib/bootstrap/less/utilities.less"; // Has to be last to override when necessary 66 | 67 | // Fuel UX controls 68 | @import "checkbox.less"; 69 | @import "combobox.less"; 70 | @import "datagrid.less"; 71 | @import "pillbox.less"; 72 | @import "radio.less"; 73 | @import "spinner.less"; 74 | @import "search.less"; 75 | @import "select.less"; 76 | @import "tree.less"; 77 | @import "wizard.less"; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /dist/less/wizard.less: -------------------------------------------------------------------------------- 1 | .wizard { 2 | 3 | .clearfix; 4 | 5 | border: 1px solid @navbarBorder; 6 | .border-radius(@baseBorderRadius); 7 | .box-shadow(0 1px 4px rgba(0,0,0,.065)); 8 | background-color: @tableBackgroundAccent; 9 | 10 | ul { 11 | list-style: none outside none; 12 | padding: 0; 13 | margin: 0; 14 | 15 | li { 16 | float: left; 17 | margin: 0; 18 | padding: 0 20px 0 30px; 19 | height: 46px; 20 | line-height: 46px; 21 | position: relative; 22 | background: #ededed; 23 | color: @grayLight; 24 | font-size: 16px; 25 | cursor: default; 26 | 27 | .chevron { 28 | border: 24px solid transparent; 29 | border-left: 14px solid @navbarBorder; 30 | border-right: 0; 31 | display: block; 32 | position: absolute; 33 | right: -14px; 34 | top: 0; 35 | } 36 | 37 | .chevron:before { 38 | border: 24px solid transparent; 39 | border-left: 14px solid #ededed; 40 | border-right: 0; 41 | content: ""; 42 | display: block; 43 | position: absolute; 44 | right: 1px; 45 | top: -24px; 46 | } 47 | 48 | &.complete { 49 | background: #f3f4f5; 50 | color: @successText; 51 | 52 | &:hover { 53 | background: #e7eff8; 54 | cursor: pointer; 55 | 56 | .chevron:before { 57 | border-left: 14px solid #e7eff8; 58 | } 59 | } 60 | 61 | .chevron:before { 62 | border-left: 14px solid #f3f4f5; 63 | } 64 | } 65 | &.active { 66 | background: #f1f6fc; 67 | color: @infoText; 68 | 69 | .chevron:before { 70 | border-left: 14px solid #f1f6fc; 71 | } 72 | } 73 | .badge { 74 | margin-right: 8px; 75 | } 76 | } 77 | 78 | /* set z-index on steps for chevron overlap */ 79 | li:nth-child(1) { 80 | border-radius: 4px 0 0 4px; 81 | padding-left: 20px; 82 | z-index: 10; 83 | } 84 | li:nth-child(2) { 85 | z-index: 9; 86 | } 87 | li:nth-child(3) { 88 | z-index: 8; 89 | } 90 | li:nth-child(4) { 91 | z-index: 7; 92 | } 93 | li:nth-child(5) { 94 | z-index: 6; 95 | } 96 | li:nth-child(6) { 97 | z-index: 5; 98 | } 99 | li:nth-child(7) { 100 | z-index: 4; 101 | } 102 | li:nth-child(8) { 103 | z-index: 3; 104 | } 105 | li:nth-child(9) { 106 | z-index: 2; 107 | } 108 | li:nth-child(10) { 109 | z-index: 1; 110 | } 111 | } 112 | 113 | .actions { 114 | line-height: 44px; 115 | float: right; 116 | padding-right: 15px; 117 | vertical-align: middle; 118 | 119 | a { 120 | line-height: 45px; 121 | font-size: 12px; 122 | margin-right: 8px; 123 | } 124 | 125 | .btn-prev { 126 | i { 127 | margin-right: 5px; 128 | } 129 | } 130 | 131 | .btn-next { 132 | i { 133 | margin-left: 5px; 134 | } 135 | } 136 | } 137 | } 138 | 139 | .step-content { 140 | .step-pane { 141 | display: none; 142 | } 143 | 144 | .active { 145 | display: block; 146 | } 147 | } -------------------------------------------------------------------------------- /src/less/wizard.less: -------------------------------------------------------------------------------- 1 | .wizard { 2 | 3 | .clearfix; 4 | 5 | border: 1px solid @navbarBorder; 6 | .border-radius(@baseBorderRadius); 7 | .box-shadow(0 1px 4px rgba(0,0,0,.065)); 8 | background-color: @tableBackgroundAccent; 9 | 10 | ul { 11 | list-style: none outside none; 12 | padding: 0; 13 | margin: 0; 14 | 15 | li { 16 | float: left; 17 | margin: 0; 18 | padding: 0 20px 0 30px; 19 | height: 46px; 20 | line-height: 46px; 21 | position: relative; 22 | background: #ededed; 23 | color: @grayLight; 24 | font-size: 16px; 25 | cursor: default; 26 | 27 | .chevron { 28 | border: 24px solid transparent; 29 | border-left: 14px solid @navbarBorder; 30 | border-right: 0; 31 | display: block; 32 | position: absolute; 33 | right: -14px; 34 | top: 0; 35 | } 36 | 37 | .chevron:before { 38 | border: 24px solid transparent; 39 | border-left: 14px solid #ededed; 40 | border-right: 0; 41 | content: ""; 42 | display: block; 43 | position: absolute; 44 | right: 1px; 45 | top: -24px; 46 | } 47 | 48 | &.complete { 49 | background: #f3f4f5; 50 | color: @successText; 51 | 52 | &:hover { 53 | background: #e7eff8; 54 | cursor: pointer; 55 | 56 | .chevron:before { 57 | border-left: 14px solid #e7eff8; 58 | } 59 | } 60 | 61 | .chevron:before { 62 | border-left: 14px solid #f3f4f5; 63 | } 64 | } 65 | &.active { 66 | background: #f1f6fc; 67 | color: @infoText; 68 | 69 | .chevron:before { 70 | border-left: 14px solid #f1f6fc; 71 | } 72 | } 73 | .badge { 74 | margin-right: 8px; 75 | } 76 | } 77 | 78 | /* set z-index on steps for chevron overlap */ 79 | li:nth-child(1) { 80 | border-radius: 4px 0 0 4px; 81 | padding-left: 20px; 82 | z-index: 10; 83 | } 84 | li:nth-child(2) { 85 | z-index: 9; 86 | } 87 | li:nth-child(3) { 88 | z-index: 8; 89 | } 90 | li:nth-child(4) { 91 | z-index: 7; 92 | } 93 | li:nth-child(5) { 94 | z-index: 6; 95 | } 96 | li:nth-child(6) { 97 | z-index: 5; 98 | } 99 | li:nth-child(7) { 100 | z-index: 4; 101 | } 102 | li:nth-child(8) { 103 | z-index: 3; 104 | } 105 | li:nth-child(9) { 106 | z-index: 2; 107 | } 108 | li:nth-child(10) { 109 | z-index: 1; 110 | } 111 | } 112 | 113 | .actions { 114 | line-height: 44px; 115 | float: right; 116 | padding-right: 15px; 117 | vertical-align: middle; 118 | 119 | a { 120 | line-height: 45px; 121 | font-size: 12px; 122 | margin-right: 8px; 123 | } 124 | 125 | .btn-prev { 126 | i { 127 | margin-right: 5px; 128 | } 129 | } 130 | 131 | .btn-next { 132 | i { 133 | margin-left: 5px; 134 | } 135 | } 136 | } 137 | } 138 | 139 | .step-content { 140 | .step-pane { 141 | display: none; 142 | } 143 | 144 | .active { 145 | display: block; 146 | } 147 | } -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-tab.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-tabs") 4 | 5 | test("should provide no conflict", function () { 6 | var tab = $.fn.tab.noConflict() 7 | ok(!$.fn.tab, 'tab was set back to undefined (org value)') 8 | $.fn.tab = tab 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).tab, 'tabs method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).tab()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should activate element by tab id", function () { 20 | var tabsHTML = 21 | '' 25 | 26 | $('').appendTo("#qunit-fixture") 27 | 28 | $(tabsHTML).find('li:last a').tab('show') 29 | equals($("#qunit-fixture").find('.active').attr('id'), "profile") 30 | 31 | $(tabsHTML).find('li:first a').tab('show') 32 | equals($("#qunit-fixture").find('.active').attr('id'), "home") 33 | }) 34 | 35 | test("should activate element by tab id", function () { 36 | var pillsHTML = 37 | '' 41 | 42 | $('').appendTo("#qunit-fixture") 43 | 44 | $(pillsHTML).find('li:last a').tab('show') 45 | equals($("#qunit-fixture").find('.active').attr('id'), "profile") 46 | 47 | $(pillsHTML).find('li:first a').tab('show') 48 | equals($("#qunit-fixture").find('.active').attr('id'), "home") 49 | }) 50 | 51 | 52 | test("should not fire closed when close is prevented", function () { 53 | $.support.transition = false 54 | stop(); 55 | $('
      ') 56 | .bind('show', function (e) { 57 | e.preventDefault(); 58 | ok(true); 59 | start(); 60 | }) 61 | .bind('shown', function () { 62 | ok(false); 63 | }) 64 | .tab('show') 65 | }) 66 | 67 | test("show and shown events should reference correct relatedTarget", function () { 68 | var dropHTML = 69 | '' 77 | 78 | $(dropHTML).find('ul>li:first a').tab('show').end() 79 | .find('ul>li:last a').on('show', function(event){ 80 | equals(event.relatedTarget.hash, "#1-1") 81 | }).on('shown', function(event){ 82 | equals(event.relatedTarget.hash, "#1-1") 83 | }).tab('show') 84 | }) 85 | 86 | }) -------------------------------------------------------------------------------- /test/checkbox-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/checkbox'], function ($) { 6 | 7 | var html = '
      ' + 8 | '' + 9 | '' + 10 | '' + 11 | '' + 12 | '
      '; 13 | 14 | module("Fuel UX checkbox"); 15 | 16 | test("should be defined on jquery object", function () { 17 | ok($(document.body).checkbox, 'checkbox method is defined'); 18 | }); 19 | 20 | test("should return element", function () { 21 | ok($(document.body).checkbox()[0] === document.body, 'document.body returned'); 22 | }); 23 | 24 | test("should set initial state", function () { 25 | var $list = $(html); 26 | var $chks = $list.find('input').checkbox(); 27 | 28 | // checked/enabled 29 | var i1 = $list.find('#lbl1 i'); 30 | equal(i1.hasClass('checked'), true, 'chk1 has checked class'); 31 | equal(i1.hasClass('disabled'), false, 'chk1 does not have disabled class'); 32 | 33 | // unchecked/enabled 34 | var i2 = $list.find('#lbl2 i'); 35 | equal(i2.hasClass('checked'), false, 'chk2 does not have checked class'); 36 | equal(i2.hasClass('disabled'), false, 'chk2 does not have disabled class'); 37 | 38 | // checked/disabled 39 | var i3 = $list.find('#lbl3 i'); 40 | equal(i3.hasClass('checked'), true, 'chk3 has checked class'); 41 | equal(i3.hasClass('disabled'), true, 'chk3 has disabled class'); 42 | 43 | // unchecked/disabled 44 | var i4 = $list.find('#lbl4 i'); 45 | equal(i4.hasClass('checked'), false, 'chk4 does not have checked class'); 46 | equal(i4.hasClass('disabled'), true, 'chk4 has disabled class'); 47 | }); 48 | 49 | test("should disable/enable checkbox", function () { 50 | var $chk1 = $(html).find('#chk1'); 51 | 52 | equal($chk1.is(':disabled'), false, 'enabled - default state'); 53 | $chk1.checkbox('disable'); 54 | equal($chk1.is(':disabled'), true, 'disabled'); 55 | $chk1.checkbox('enable'); 56 | equal($chk1.is(':disabled'), false, 're-enabled'); 57 | }); 58 | 59 | test("should check/uncheck checkbox", function () { 60 | var $fixture = $(html).appendTo('#qunit-fixture'); 61 | var $chk1 = $fixture.find('#chk1'); 62 | 63 | equal($chk1.is(':checked'), true, 'checked'); 64 | $chk1.checkbox('toggle'); 65 | equal($chk1.is(':checked'), false, 'unchecked'); 66 | $chk1.checkbox('toggle'); 67 | equal($chk1.is(':checked'), true, 'checked'); 68 | 69 | $fixture.remove(); 70 | }); 71 | 72 | }); -------------------------------------------------------------------------------- /lib/bootstrap/js/bootstrap-alert.js: -------------------------------------------------------------------------------- 1 | //Wrapped in an outer function to preserve global this 2 | (function (root) { var amdExports; define(['bootstrap/bootstrap-transition'], function () { (function () { 3 | 4 | /* ========================================================== 5 | * bootstrap-alert.js v2.3.2 6 | * http://twitter.github.com/bootstrap/javascript.html#alerts 7 | * ========================================================== 8 | * Copyright 2012 Twitter, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * ========================================================== */ 22 | 23 | 24 | !function ($) { 25 | 26 | "use strict"; // jshint ;_; 27 | 28 | 29 | /* ALERT CLASS DEFINITION 30 | * ====================== */ 31 | 32 | var dismiss = '[data-dismiss="alert"]' 33 | , Alert = function (el) { 34 | $(el).on('click', dismiss, this.close) 35 | } 36 | 37 | Alert.prototype.close = function (e) { 38 | var $this = $(this) 39 | , selector = $this.attr('data-target') 40 | , $parent 41 | 42 | if (!selector) { 43 | selector = $this.attr('href') 44 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 45 | } 46 | 47 | $parent = $(selector) 48 | 49 | e && e.preventDefault() 50 | 51 | $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) 52 | 53 | $parent.trigger(e = $.Event('close')) 54 | 55 | if (e.isDefaultPrevented()) return 56 | 57 | $parent.removeClass('in') 58 | 59 | function removeElement() { 60 | $parent 61 | .trigger('closed') 62 | .remove() 63 | } 64 | 65 | $.support.transition && $parent.hasClass('fade') ? 66 | $parent.on($.support.transition.end, removeElement) : 67 | removeElement() 68 | } 69 | 70 | 71 | /* ALERT PLUGIN DEFINITION 72 | * ======================= */ 73 | 74 | var old = $.fn.alert 75 | 76 | $.fn.alert = function (option) { 77 | return this.each(function () { 78 | var $this = $(this) 79 | , data = $this.data('alert') 80 | if (!data) $this.data('alert', (data = new Alert(this))) 81 | if (typeof option == 'string') data[option].call($this) 82 | }) 83 | } 84 | 85 | $.fn.alert.Constructor = Alert 86 | 87 | 88 | /* ALERT NO CONFLICT 89 | * ================= */ 90 | 91 | $.fn.alert.noConflict = function () { 92 | $.fn.alert = old 93 | return this 94 | } 95 | 96 | 97 | /* ALERT DATA-API 98 | * ============== */ 99 | 100 | $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) 101 | 102 | }(window.jQuery); 103 | 104 | 105 | }.call(root)); 106 | return amdExports; 107 | }); }(this)); 108 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-collapse.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-collapse") 4 | 5 | test("should provide no conflict", function () { 6 | var collapse = $.fn.collapse.noConflict() 7 | ok(!$.fn.collapse, 'collapse was set back to undefined (org value)') 8 | $.fn.collapse = collapse 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).collapse, 'collapse method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).collapse()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should show a collapsed element", function () { 20 | var el = $('
      ').collapse('show') 21 | ok(el.hasClass('in'), 'has class in') 22 | ok(/height/.test(el.attr('style')), 'has height set') 23 | }) 24 | 25 | test("should hide a collapsed element", function () { 26 | var el = $('
      ').collapse('hide') 27 | ok(!el.hasClass('in'), 'does not have class in') 28 | ok(/height/.test(el.attr('style')), 'has height set') 29 | }) 30 | 31 | test("should not fire shown when show is prevented", function () { 32 | $.support.transition = false 33 | stop() 34 | $('
      ') 35 | .bind('show', function (e) { 36 | e.preventDefault(); 37 | ok(true); 38 | start(); 39 | }) 40 | .bind('shown', function () { 41 | ok(false); 42 | }) 43 | .collapse('show') 44 | }) 45 | 46 | test("should reset style to auto after finishing opening collapse", function () { 47 | $.support.transition = false 48 | stop() 49 | $('
      ') 50 | .bind('show', function () { 51 | ok(this.style.height == '0px') 52 | }) 53 | .bind('shown', function () { 54 | ok(this.style.height == 'auto') 55 | start() 56 | }) 57 | .collapse('show') 58 | }) 59 | 60 | test("should add active class to target when collapse shown", function () { 61 | $.support.transition = false 62 | stop() 63 | 64 | var target = $('') 65 | .appendTo($('#qunit-fixture')) 66 | 67 | var collapsible = $('
      ') 68 | .appendTo($('#qunit-fixture')) 69 | .on('show', function () { 70 | ok(!target.hasClass('collapsed')) 71 | start() 72 | }) 73 | 74 | target.click() 75 | }) 76 | 77 | test("should remove active class to target when collapse hidden", function () { 78 | $.support.transition = false 79 | stop() 80 | 81 | var target = $('') 82 | .appendTo($('#qunit-fixture')) 83 | 84 | var collapsible = $('
      ') 85 | .appendTo($('#qunit-fixture')) 86 | .on('hide', function () { 87 | ok(target.hasClass('collapsed')) 88 | start() 89 | }) 90 | 91 | target.click() 92 | }) 93 | 94 | }) -------------------------------------------------------------------------------- /lib/bootstrap/less/pagination.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pagination (multiple pages) 3 | // -------------------------------------------------- 4 | 5 | // Space out pagination from surrounding content 6 | .pagination { 7 | margin: @baseLineHeight 0; 8 | } 9 | 10 | .pagination ul { 11 | // Allow for text-based alignment 12 | display: inline-block; 13 | .ie7-inline-block(); 14 | // Reset default ul styles 15 | margin-left: 0; 16 | margin-bottom: 0; 17 | // Visuals 18 | .border-radius(@baseBorderRadius); 19 | .box-shadow(0 1px 2px rgba(0,0,0,.05)); 20 | } 21 | .pagination ul > li { 22 | display: inline; // Remove list-style and block-level defaults 23 | } 24 | .pagination ul > li > a, 25 | .pagination ul > li > span { 26 | float: left; // Collapse white-space 27 | padding: 4px 12px; 28 | line-height: @baseLineHeight; 29 | text-decoration: none; 30 | background-color: @paginationBackground; 31 | border: 1px solid @paginationBorder; 32 | border-left-width: 0; 33 | } 34 | .pagination ul > li > a:hover, 35 | .pagination ul > li > a:focus, 36 | .pagination ul > .active > a, 37 | .pagination ul > .active > span { 38 | background-color: @paginationActiveBackground; 39 | } 40 | .pagination ul > .active > a, 41 | .pagination ul > .active > span { 42 | color: @grayLight; 43 | cursor: default; 44 | } 45 | .pagination ul > .disabled > span, 46 | .pagination ul > .disabled > a, 47 | .pagination ul > .disabled > a:hover, 48 | .pagination ul > .disabled > a:focus { 49 | color: @grayLight; 50 | background-color: transparent; 51 | cursor: default; 52 | } 53 | .pagination ul > li:first-child > a, 54 | .pagination ul > li:first-child > span { 55 | border-left-width: 1px; 56 | .border-left-radius(@baseBorderRadius); 57 | } 58 | .pagination ul > li:last-child > a, 59 | .pagination ul > li:last-child > span { 60 | .border-right-radius(@baseBorderRadius); 61 | } 62 | 63 | 64 | // Alignment 65 | // -------------------------------------------------- 66 | 67 | .pagination-centered { 68 | text-align: center; 69 | } 70 | .pagination-right { 71 | text-align: right; 72 | } 73 | 74 | 75 | // Sizing 76 | // -------------------------------------------------- 77 | 78 | // Large 79 | .pagination-large { 80 | ul > li > a, 81 | ul > li > span { 82 | padding: @paddingLarge; 83 | font-size: @fontSizeLarge; 84 | } 85 | ul > li:first-child > a, 86 | ul > li:first-child > span { 87 | .border-left-radius(@borderRadiusLarge); 88 | } 89 | ul > li:last-child > a, 90 | ul > li:last-child > span { 91 | .border-right-radius(@borderRadiusLarge); 92 | } 93 | } 94 | 95 | // Small and mini 96 | .pagination-mini, 97 | .pagination-small { 98 | ul > li:first-child > a, 99 | ul > li:first-child > span { 100 | .border-left-radius(@borderRadiusSmall); 101 | } 102 | ul > li:last-child > a, 103 | ul > li:last-child > span { 104 | .border-right-radius(@borderRadiusSmall); 105 | } 106 | } 107 | 108 | // Small 109 | .pagination-small { 110 | ul > li > a, 111 | ul > li > span { 112 | padding: @paddingSmall; 113 | font-size: @fontSizeSmall; 114 | } 115 | } 116 | // Mini 117 | .pagination-mini { 118 | ul > li > a, 119 | ul > li > span { 120 | padding: @paddingMini; 121 | font-size: @fontSizeMini; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /lib/bootstrap/less/carousel.less: -------------------------------------------------------------------------------- 1 | // 2 | // Carousel 3 | // -------------------------------------------------- 4 | 5 | 6 | .carousel { 7 | position: relative; 8 | margin-bottom: @baseLineHeight; 9 | line-height: 1; 10 | } 11 | 12 | .carousel-inner { 13 | overflow: hidden; 14 | width: 100%; 15 | position: relative; 16 | } 17 | 18 | .carousel-inner { 19 | 20 | > .item { 21 | display: none; 22 | position: relative; 23 | .transition(.6s ease-in-out left); 24 | 25 | // Account for jankitude on images 26 | > img, 27 | > a > img { 28 | display: block; 29 | line-height: 1; 30 | } 31 | } 32 | 33 | > .active, 34 | > .next, 35 | > .prev { display: block; } 36 | 37 | > .active { 38 | left: 0; 39 | } 40 | 41 | > .next, 42 | > .prev { 43 | position: absolute; 44 | top: 0; 45 | width: 100%; 46 | } 47 | 48 | > .next { 49 | left: 100%; 50 | } 51 | > .prev { 52 | left: -100%; 53 | } 54 | > .next.left, 55 | > .prev.right { 56 | left: 0; 57 | } 58 | 59 | > .active.left { 60 | left: -100%; 61 | } 62 | > .active.right { 63 | left: 100%; 64 | } 65 | 66 | } 67 | 68 | // Left/right controls for nav 69 | // --------------------------- 70 | 71 | .carousel-control { 72 | position: absolute; 73 | top: 40%; 74 | left: 15px; 75 | width: 40px; 76 | height: 40px; 77 | margin-top: -20px; 78 | font-size: 60px; 79 | font-weight: 100; 80 | line-height: 30px; 81 | color: @white; 82 | text-align: center; 83 | background: @grayDarker; 84 | border: 3px solid @white; 85 | .border-radius(23px); 86 | .opacity(50); 87 | 88 | // we can't have this transition here 89 | // because webkit cancels the carousel 90 | // animation if you trip this while 91 | // in the middle of another animation 92 | // ;_; 93 | // .transition(opacity .2s linear); 94 | 95 | // Reposition the right one 96 | &.right { 97 | left: auto; 98 | right: 15px; 99 | } 100 | 101 | // Hover/focus state 102 | &:hover, 103 | &:focus { 104 | color: @white; 105 | text-decoration: none; 106 | .opacity(90); 107 | } 108 | } 109 | 110 | // Carousel indicator pips 111 | // ----------------------------- 112 | .carousel-indicators { 113 | position: absolute; 114 | top: 15px; 115 | right: 15px; 116 | z-index: 5; 117 | margin: 0; 118 | list-style: none; 119 | 120 | li { 121 | display: block; 122 | float: left; 123 | width: 10px; 124 | height: 10px; 125 | margin-left: 5px; 126 | text-indent: -999px; 127 | background-color: #ccc; 128 | background-color: rgba(255,255,255,.25); 129 | border-radius: 5px; 130 | } 131 | .active { 132 | background-color: #fff; 133 | } 134 | } 135 | 136 | // Caption for text below images 137 | // ----------------------------- 138 | 139 | .carousel-caption { 140 | position: absolute; 141 | left: 0; 142 | right: 0; 143 | bottom: 0; 144 | padding: 15px; 145 | background: @grayDark; 146 | background: rgba(0,0,0,.75); 147 | } 148 | .carousel-caption h4, 149 | .carousel-caption p { 150 | color: @white; 151 | line-height: @baseLineHeight; 152 | } 153 | .carousel-caption h4 { 154 | margin: 0 0 5px; 155 | } 156 | .carousel-caption p { 157 | margin-bottom: 0; 158 | } 159 | -------------------------------------------------------------------------------- /src/search.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Search 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function(require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // SEARCH CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Search = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.search.defaults, options); 19 | 20 | this.$button = this.$element.find('button') 21 | .on('click', $.proxy(this.buttonclicked, this)); 22 | 23 | this.$input = this.$element.find('input') 24 | .on('keydown', $.proxy(this.keypress, this)) 25 | .on('keyup', $.proxy(this.keypressed, this)); 26 | 27 | this.$icon = this.$element.find('i'); 28 | this.activeSearch = ''; 29 | }; 30 | 31 | Search.prototype = { 32 | 33 | constructor: Search, 34 | 35 | search: function (searchText) { 36 | this.$icon.attr('class', 'icon-remove'); 37 | this.activeSearch = searchText; 38 | this.$element.trigger('searched', searchText); 39 | }, 40 | 41 | clear: function () { 42 | this.$icon.attr('class', 'icon-search'); 43 | this.activeSearch = ''; 44 | this.$input.val(''); 45 | this.$element.trigger('cleared'); 46 | }, 47 | 48 | action: function () { 49 | var val = this.$input.val(); 50 | var inputEmptyOrUnchanged = val === '' || val === this.activeSearch; 51 | 52 | if (this.activeSearch && inputEmptyOrUnchanged) { 53 | this.clear(); 54 | } else if (val) { 55 | this.search(val); 56 | } 57 | }, 58 | 59 | buttonclicked: function (e) { 60 | e.preventDefault(); 61 | if ($(e.currentTarget).is('.disabled, :disabled')) return; 62 | this.action(); 63 | }, 64 | 65 | keypress: function (e) { 66 | if (e.which === 13) { 67 | e.preventDefault(); 68 | } 69 | }, 70 | 71 | keypressed: function (e) { 72 | var val, inputPresentAndUnchanged; 73 | 74 | if (e.which === 13) { 75 | e.preventDefault(); 76 | this.action(); 77 | } else { 78 | val = this.$input.val(); 79 | inputPresentAndUnchanged = val && (val === this.activeSearch); 80 | this.$icon.attr('class', inputPresentAndUnchanged ? 'icon-remove' : 'icon-search'); 81 | } 82 | }, 83 | 84 | disable: function () { 85 | this.$input.attr('disabled', 'disabled'); 86 | this.$button.addClass('disabled'); 87 | }, 88 | 89 | enable: function () { 90 | this.$input.removeAttr('disabled'); 91 | this.$button.removeClass('disabled'); 92 | } 93 | 94 | }; 95 | 96 | 97 | // SEARCH PLUGIN DEFINITION 98 | 99 | $.fn.search = function (option) { 100 | return this.each(function () { 101 | var $this = $(this); 102 | var data = $this.data('search'); 103 | var options = typeof option === 'object' && option; 104 | 105 | if (!data) $this.data('search', (data = new Search(this, options))); 106 | if (typeof option === 'string') data[option](); 107 | }); 108 | }; 109 | 110 | $.fn.search.defaults = {}; 111 | 112 | $.fn.search.Constructor = Search; 113 | 114 | 115 | // SEARCH DATA-API 116 | 117 | $(function () { 118 | $('body').on('mousedown.search.data-api', '.search', function () { 119 | var $this = $(this); 120 | if ($this.data('search')) return; 121 | $this.search($this.data()); 122 | }); 123 | }); 124 | 125 | }); 126 | -------------------------------------------------------------------------------- /dist/search.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Search 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(['require','jquery'],function(require) { 10 | 11 | var $ = require('jquery'); 12 | 13 | 14 | // SEARCH CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Search = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.search.defaults, options); 19 | 20 | this.$button = this.$element.find('button') 21 | .on('click', $.proxy(this.buttonclicked, this)); 22 | 23 | this.$input = this.$element.find('input') 24 | .on('keydown', $.proxy(this.keypress, this)) 25 | .on('keyup', $.proxy(this.keypressed, this)); 26 | 27 | this.$icon = this.$element.find('i'); 28 | this.activeSearch = ''; 29 | }; 30 | 31 | Search.prototype = { 32 | 33 | constructor: Search, 34 | 35 | search: function (searchText) { 36 | this.$icon.attr('class', 'icon-remove'); 37 | this.activeSearch = searchText; 38 | this.$element.trigger('searched', searchText); 39 | }, 40 | 41 | clear: function () { 42 | this.$icon.attr('class', 'icon-search'); 43 | this.activeSearch = ''; 44 | this.$input.val(''); 45 | this.$element.trigger('cleared'); 46 | }, 47 | 48 | action: function () { 49 | var val = this.$input.val(); 50 | var inputEmptyOrUnchanged = val === '' || val === this.activeSearch; 51 | 52 | if (this.activeSearch && inputEmptyOrUnchanged) { 53 | this.clear(); 54 | } else if (val) { 55 | this.search(val); 56 | } 57 | }, 58 | 59 | buttonclicked: function (e) { 60 | e.preventDefault(); 61 | if ($(e.currentTarget).is('.disabled, :disabled')) return; 62 | this.action(); 63 | }, 64 | 65 | keypress: function (e) { 66 | if (e.which === 13) { 67 | e.preventDefault(); 68 | } 69 | }, 70 | 71 | keypressed: function (e) { 72 | var val, inputPresentAndUnchanged; 73 | 74 | if (e.which === 13) { 75 | e.preventDefault(); 76 | this.action(); 77 | } else { 78 | val = this.$input.val(); 79 | inputPresentAndUnchanged = val && (val === this.activeSearch); 80 | this.$icon.attr('class', inputPresentAndUnchanged ? 'icon-remove' : 'icon-search'); 81 | } 82 | }, 83 | 84 | disable: function () { 85 | this.$input.attr('disabled', 'disabled'); 86 | this.$button.addClass('disabled'); 87 | }, 88 | 89 | enable: function () { 90 | this.$input.removeAttr('disabled'); 91 | this.$button.removeClass('disabled'); 92 | } 93 | 94 | }; 95 | 96 | 97 | // SEARCH PLUGIN DEFINITION 98 | 99 | $.fn.search = function (option) { 100 | return this.each(function () { 101 | var $this = $(this); 102 | var data = $this.data('search'); 103 | var options = typeof option === 'object' && option; 104 | 105 | if (!data) $this.data('search', (data = new Search(this, options))); 106 | if (typeof option === 'string') data[option](); 107 | }); 108 | }; 109 | 110 | $.fn.search.defaults = {}; 111 | 112 | $.fn.search.Constructor = Search; 113 | 114 | 115 | // SEARCH DATA-API 116 | 117 | $(function () { 118 | $('body').on('mousedown.search.data-api', '.search', function () { 119 | var $this = $(this); 120 | if ($this.data('search')) return; 121 | $this.search($this.data()); 122 | }); 123 | }); 124 | 125 | }); 126 | -------------------------------------------------------------------------------- /dist/less/datagrid.less: -------------------------------------------------------------------------------- 1 | @tableBackgroundAccentDark: darken(@tableBackgroundAccent, 8%); 2 | 3 | .datagrid { 4 | 5 | thead { 6 | 7 | background-color: @tableBackgroundAccent; 8 | 9 | .datagrid-header-title { 10 | float: left; 11 | line-height: 28px; 12 | font-weight: normal; 13 | font-size: 14px; 14 | margin-right: 10px; 15 | } 16 | 17 | .datagrid-header-left { 18 | float: left; 19 | } 20 | 21 | .datagrid-header-right { 22 | float: right; 23 | } 24 | 25 | .datagrid-header-right, .datagrid-header-left { 26 | .search, .filter { 27 | margin-left: 8px; 28 | margin-bottom: 0; 29 | 30 | .dropdown-menu { 31 | top: auto; 32 | left: auto; 33 | } 34 | } 35 | } 36 | 37 | // When changing this section verify stretchHeight column sizes when sorting 38 | // and update SORTED_HEADER_OFFSET in datagrid.js as needed 39 | .sorted { 40 | .gradientBar(@tableBackgroundAccent, @tableBackgroundAccentDark, @textColor, 'none'); 41 | 42 | padding-right: 30px; 43 | 44 | i { 45 | float: right; 46 | margin-top: 2px; 47 | margin-right: -22px; 48 | } 49 | } 50 | 51 | .sortable { 52 | cursor: pointer; 53 | 54 | &:hover { 55 | .gradientBar(@tableBackgroundAccent, @tableBackgroundAccentDark, @textColor, 'none'); 56 | } 57 | } 58 | 59 | } 60 | 61 | tfoot { 62 | 63 | background-color: @tableBackgroundAccent; 64 | 65 | .datagrid-footer-left { 66 | 67 | float: left; 68 | 69 | .grid-controls { 70 | margin-top: 7px; 71 | 72 | select { 73 | margin: 0 5px 1px; 74 | width: 60px; 75 | } 76 | 77 | .grid-pagesize { 78 | display: inline-block; 79 | margin-bottom: 5px; 80 | vertical-align: middle; 81 | 82 | .dropdown-menu { 83 | top: auto; 84 | left: auto; 85 | } 86 | } 87 | 88 | span { 89 | font-weight: normal; 90 | } 91 | } 92 | 93 | } 94 | 95 | .datagrid-footer-right { 96 | 97 | float: right; 98 | 99 | .grid-pager { 100 | > span { 101 | font-weight: normal; 102 | position: relative; 103 | top: 8px; 104 | } 105 | 106 | .dropdown-menu { 107 | min-width: 50px; 108 | } 109 | 110 | .combobox { 111 | display: inline-block; 112 | position: relative; 113 | top: -2px; 114 | vertical-align: baseline; 115 | margin-bottom: 4px; 116 | } 117 | 118 | > button { 119 | position: relative; 120 | top: 7px; 121 | } 122 | } 123 | 124 | } 125 | 126 | } 127 | 128 | } 129 | 130 | .datagrid-stretch-header { 131 | border-bottom: 0; 132 | .border-bottom-radius(0); 133 | 134 | margin-bottom: 0; 135 | 136 | thead:last-child tr:last-child > th:first-child, 137 | thead:last-child tr:last-child > th:last-child { 138 | .border-bottom-radius(0); 139 | } 140 | } 141 | 142 | .datagrid-stretch-wrapper { 143 | border: 1px solid @tableBorder; 144 | overflow: auto; 145 | 146 | .datagrid { 147 | border: none; 148 | border-collapse: collapse; 149 | .border-radius(0); 150 | 151 | margin-bottom: 0; 152 | 153 | td, th { 154 | border-bottom: 1px solid @tableBorder; 155 | 156 | &:first-child { 157 | border-left: none; 158 | .border-radius(0); 159 | } 160 | } 161 | } 162 | } 163 | 164 | .datagrid-stretch-footer { 165 | border-top: 0; 166 | .border-top-radius(0); 167 | 168 | th { 169 | border-top: 0; 170 | } 171 | } 172 | 173 | -------------------------------------------------------------------------------- /src/less/datagrid.less: -------------------------------------------------------------------------------- 1 | @tableBackgroundAccentDark: darken(@tableBackgroundAccent, 8%); 2 | 3 | .datagrid { 4 | 5 | thead { 6 | 7 | background-color: @tableBackgroundAccent; 8 | 9 | .datagrid-header-title { 10 | float: left; 11 | line-height: 28px; 12 | font-weight: normal; 13 | font-size: 14px; 14 | margin-right: 10px; 15 | } 16 | 17 | .datagrid-header-left { 18 | float: left; 19 | } 20 | 21 | .datagrid-header-right { 22 | float: right; 23 | } 24 | 25 | .datagrid-header-right, .datagrid-header-left { 26 | .search, .filter { 27 | margin-left: 8px; 28 | margin-bottom: 0; 29 | 30 | .dropdown-menu { 31 | top: auto; 32 | left: auto; 33 | } 34 | } 35 | } 36 | 37 | // When changing this section verify stretchHeight column sizes when sorting 38 | // and update SORTED_HEADER_OFFSET in datagrid.js as needed 39 | .sorted { 40 | .gradientBar(@tableBackgroundAccent, @tableBackgroundAccentDark, @textColor, 'none'); 41 | 42 | padding-right: 30px; 43 | 44 | i { 45 | float: right; 46 | margin-top: 2px; 47 | margin-right: -22px; 48 | } 49 | } 50 | 51 | .sortable { 52 | cursor: pointer; 53 | 54 | &:hover { 55 | .gradientBar(@tableBackgroundAccent, @tableBackgroundAccentDark, @textColor, 'none'); 56 | } 57 | } 58 | 59 | } 60 | 61 | tfoot { 62 | 63 | background-color: @tableBackgroundAccent; 64 | 65 | .datagrid-footer-left { 66 | 67 | float: left; 68 | 69 | .grid-controls { 70 | margin-top: 7px; 71 | 72 | select { 73 | margin: 0 5px 1px; 74 | width: 60px; 75 | } 76 | 77 | .grid-pagesize { 78 | display: inline-block; 79 | margin-bottom: 5px; 80 | vertical-align: middle; 81 | 82 | .dropdown-menu { 83 | top: auto; 84 | left: auto; 85 | } 86 | } 87 | 88 | span { 89 | font-weight: normal; 90 | } 91 | } 92 | 93 | } 94 | 95 | .datagrid-footer-right { 96 | 97 | float: right; 98 | 99 | .grid-pager { 100 | > span { 101 | font-weight: normal; 102 | position: relative; 103 | top: 8px; 104 | } 105 | 106 | .dropdown-menu { 107 | min-width: 50px; 108 | } 109 | 110 | .combobox { 111 | display: inline-block; 112 | position: relative; 113 | top: -2px; 114 | vertical-align: baseline; 115 | margin-bottom: 4px; 116 | } 117 | 118 | > button { 119 | position: relative; 120 | top: 7px; 121 | } 122 | } 123 | 124 | } 125 | 126 | } 127 | 128 | } 129 | 130 | .datagrid-stretch-header { 131 | border-bottom: 0; 132 | .border-bottom-radius(0); 133 | 134 | margin-bottom: 0; 135 | 136 | thead:last-child tr:last-child > th:first-child, 137 | thead:last-child tr:last-child > th:last-child { 138 | .border-bottom-radius(0); 139 | } 140 | } 141 | 142 | .datagrid-stretch-wrapper { 143 | border: 1px solid @tableBorder; 144 | overflow: auto; 145 | 146 | .datagrid { 147 | border: none; 148 | border-collapse: collapse; 149 | .border-radius(0); 150 | 151 | margin-bottom: 0; 152 | 153 | td, th { 154 | border-bottom: 1px solid @tableBorder; 155 | 156 | &:first-child { 157 | border-left: none; 158 | .border-radius(0); 159 | } 160 | } 161 | } 162 | } 163 | 164 | .datagrid-stretch-footer { 165 | border-top: 0; 166 | .border-top-radius(0); 167 | 168 | th { 169 | border-top: 0; 170 | } 171 | } 172 | 173 | -------------------------------------------------------------------------------- /lib/bootstrap/less/progress-bars.less: -------------------------------------------------------------------------------- 1 | // 2 | // Progress bars 3 | // -------------------------------------------------- 4 | 5 | 6 | // ANIMATIONS 7 | // ---------- 8 | 9 | // Webkit 10 | @-webkit-keyframes progress-bar-stripes { 11 | from { background-position: 40px 0; } 12 | to { background-position: 0 0; } 13 | } 14 | 15 | // Firefox 16 | @-moz-keyframes progress-bar-stripes { 17 | from { background-position: 40px 0; } 18 | to { background-position: 0 0; } 19 | } 20 | 21 | // IE9 22 | @-ms-keyframes progress-bar-stripes { 23 | from { background-position: 40px 0; } 24 | to { background-position: 0 0; } 25 | } 26 | 27 | // Opera 28 | @-o-keyframes progress-bar-stripes { 29 | from { background-position: 0 0; } 30 | to { background-position: 40px 0; } 31 | } 32 | 33 | // Spec 34 | @keyframes progress-bar-stripes { 35 | from { background-position: 40px 0; } 36 | to { background-position: 0 0; } 37 | } 38 | 39 | 40 | 41 | // THE BARS 42 | // -------- 43 | 44 | // Outer container 45 | .progress { 46 | overflow: hidden; 47 | height: @baseLineHeight; 48 | margin-bottom: @baseLineHeight; 49 | #gradient > .vertical(#f5f5f5, #f9f9f9); 50 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); 51 | .border-radius(@baseBorderRadius); 52 | } 53 | 54 | // Bar of progress 55 | .progress .bar { 56 | width: 0%; 57 | height: 100%; 58 | color: @white; 59 | float: left; 60 | font-size: 12px; 61 | text-align: center; 62 | text-shadow: 0 -1px 0 rgba(0,0,0,.25); 63 | #gradient > .vertical(#149bdf, #0480be); 64 | .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); 65 | .box-sizing(border-box); 66 | .transition(width .6s ease); 67 | } 68 | .progress .bar + .bar { 69 | .box-shadow(~"inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15)"); 70 | } 71 | 72 | // Striped bars 73 | .progress-striped .bar { 74 | #gradient > .striped(#149bdf); 75 | .background-size(40px 40px); 76 | } 77 | 78 | // Call animation for the active one 79 | .progress.active .bar { 80 | -webkit-animation: progress-bar-stripes 2s linear infinite; 81 | -moz-animation: progress-bar-stripes 2s linear infinite; 82 | -ms-animation: progress-bar-stripes 2s linear infinite; 83 | -o-animation: progress-bar-stripes 2s linear infinite; 84 | animation: progress-bar-stripes 2s linear infinite; 85 | } 86 | 87 | 88 | 89 | // COLORS 90 | // ------ 91 | 92 | // Danger (red) 93 | .progress-danger .bar, .progress .bar-danger { 94 | #gradient > .vertical(#ee5f5b, #c43c35); 95 | } 96 | .progress-danger.progress-striped .bar, .progress-striped .bar-danger { 97 | #gradient > .striped(#ee5f5b); 98 | } 99 | 100 | // Success (green) 101 | .progress-success .bar, .progress .bar-success { 102 | #gradient > .vertical(#62c462, #57a957); 103 | } 104 | .progress-success.progress-striped .bar, .progress-striped .bar-success { 105 | #gradient > .striped(#62c462); 106 | } 107 | 108 | // Info (teal) 109 | .progress-info .bar, .progress .bar-info { 110 | #gradient > .vertical(#5bc0de, #339bb9); 111 | } 112 | .progress-info.progress-striped .bar, .progress-striped .bar-info { 113 | #gradient > .striped(#5bc0de); 114 | } 115 | 116 | // Warning (orange) 117 | .progress-warning .bar, .progress .bar-warning { 118 | #gradient > .vertical(lighten(@orange, 15%), @orange); 119 | } 120 | .progress-warning.progress-striped .bar, .progress-striped .bar-warning { 121 | #gradient > .striped(lighten(@orange, 15%)); 122 | } 123 | -------------------------------------------------------------------------------- /lib/bootstrap/js/bootstrap-button.js: -------------------------------------------------------------------------------- 1 | //Wrapped in an outer function to preserve global this 2 | (function (root) { var amdExports; define(['bootstrap/bootstrap-transition'], function () { (function () { 3 | 4 | /* ============================================================ 5 | * bootstrap-button.js v2.3.2 6 | * http://twitter.github.com/bootstrap/javascript.html#buttons 7 | * ============================================================ 8 | * Copyright 2012 Twitter, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * ============================================================ */ 22 | 23 | 24 | !function ($) { 25 | 26 | "use strict"; // jshint ;_; 27 | 28 | 29 | /* BUTTON PUBLIC CLASS DEFINITION 30 | * ============================== */ 31 | 32 | var Button = function (element, options) { 33 | this.$element = $(element) 34 | this.options = $.extend({}, $.fn.button.defaults, options) 35 | } 36 | 37 | Button.prototype.setState = function (state) { 38 | var d = 'disabled' 39 | , $el = this.$element 40 | , data = $el.data() 41 | , val = $el.is('input') ? 'val' : 'html' 42 | 43 | state = state + 'Text' 44 | data.resetText || $el.data('resetText', $el[val]()) 45 | 46 | $el[val](data[state] || this.options[state]) 47 | 48 | // push to event loop to allow forms to submit 49 | setTimeout(function () { 50 | state == 'loadingText' ? 51 | $el.addClass(d).attr(d, d) : 52 | $el.removeClass(d).removeAttr(d) 53 | }, 0) 54 | } 55 | 56 | Button.prototype.toggle = function () { 57 | var $parent = this.$element.closest('[data-toggle="buttons-radio"]') 58 | 59 | $parent && $parent 60 | .find('.active') 61 | .removeClass('active') 62 | 63 | this.$element.toggleClass('active') 64 | } 65 | 66 | 67 | /* BUTTON PLUGIN DEFINITION 68 | * ======================== */ 69 | 70 | var old = $.fn.button 71 | 72 | $.fn.button = function (option) { 73 | return this.each(function () { 74 | var $this = $(this) 75 | , data = $this.data('button') 76 | , options = typeof option == 'object' && option 77 | if (!data) $this.data('button', (data = new Button(this, options))) 78 | if (option == 'toggle') data.toggle() 79 | else if (option) data.setState(option) 80 | }) 81 | } 82 | 83 | $.fn.button.defaults = { 84 | loadingText: 'loading...' 85 | } 86 | 87 | $.fn.button.Constructor = Button 88 | 89 | 90 | /* BUTTON NO CONFLICT 91 | * ================== */ 92 | 93 | $.fn.button.noConflict = function () { 94 | $.fn.button = old 95 | return this 96 | } 97 | 98 | 99 | /* BUTTON DATA-API 100 | * =============== */ 101 | 102 | $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { 103 | var $btn = $(e.target) 104 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 105 | $btn.button('toggle') 106 | }) 107 | 108 | }(window.jQuery); 109 | 110 | 111 | }.call(root)); 112 | return amdExports; 113 | }); }(this)); 114 | -------------------------------------------------------------------------------- /lib/bootstrap/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Bootstrap 2 | 3 | Looking to contribute something to Bootstrap? **Here's how you can help.** 4 | 5 | 6 | 7 | ## Reporting issues 8 | 9 | We only accept issues that are bug reports or feature requests. Bugs must be isolated and reproducible problems that we can fix within the Bootstrap core. Please read the following guidelines before opening any issue. 10 | 11 | 1. **Search for existing issues.** We get a lot of duplicate issues, and you'd help us out a lot by first checking if someone else has reported the same issue. Moreover, the issue may have already been resolved with a fix available. 12 | 2. **Create an isolated and reproducible test case.** Be sure the problem exists in Bootstrap's code with a [reduced test case](http://css-tricks.com/reduced-test-cases/) that should be included in each bug report. 13 | 3. **Include a live example.** Make use of jsFiddle or jsBin to share your isolated test cases. 14 | 4. **Share as much information as possible.** Include operating system and version, browser and version, version of Bootstrap, customized or vanilla build, etc. where appropriate. Also include steps to reproduce the bug. 15 | 16 | 17 | 18 | ## Key branches 19 | 20 | - `master` is the latest, deployed version. 21 | - `gh-pages` is the hosted docs (not to be used for pull requests). 22 | - `*-wip` is the official work in progress branch for the next release. 23 | 24 | 25 | 26 | ## Notes on the repo 27 | 28 | As of v2.0.0, Bootstrap's documentation is powered by Mustache templates and built via `make` before each commit and release. This was done to enable internationalization (translation) in a future release by uploading our strings to the [Twitter Translation Center](http://translate.twttr.com/). Any edits to the docs should be first done in the Mustache files and then recompiled into the HTML. 29 | 30 | 31 | 32 | ## Pull requests 33 | 34 | - Try to submit pull requests against the latest `*-wip` branch for easier merging 35 | - Any changes to the docs must be made to the Mustache templates, not just the compiled HTML pages 36 | - CSS changes must be done in .less files first, never just the compiled files 37 | - If modifying the .less files, always recompile and commit the compiled files bootstrap.css and bootstrap.min.css 38 | - Try not to pollute your pull request with unintended changes--keep them simple and small 39 | - Try to share which browsers your code has been tested in before submitting a pull request 40 | 41 | 42 | 43 | ## Coding standards: HTML 44 | 45 | - Two spaces for indentation, never tabs 46 | - Double quotes only, never single quotes 47 | - Always use proper indentation 48 | - Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags) 49 | 50 | 51 | 52 | ## Coding standards: CSS 53 | 54 | - Adhere to the [Recess CSS property order](http://markdotto.com/2011/11/29/css-property-order/) 55 | - Multiple-line approach (one property and value per line) 56 | - Always a space after a property's colon (.e.g, `display: block;` and not `display:block;`) 57 | - End all lines with a semi-colon 58 | - For multiple, comma-separated selectors, place each selector on it's own line 59 | - 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). 60 | 61 | 62 | 63 | ## Coding standards: JS 64 | 65 | - No semicolons 66 | - Comma first 67 | - 2 spaces (no tabs) 68 | - strict mode 69 | - "Attractive" 70 | 71 | 72 | 73 | ## License 74 | 75 | By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/twitter/bootstrap/blob/master/LICENSE 76 | -------------------------------------------------------------------------------- /lib/bootstrap/less/popovers.less: -------------------------------------------------------------------------------- 1 | // 2 | // Popovers 3 | // -------------------------------------------------- 4 | 5 | 6 | .popover { 7 | position: absolute; 8 | top: 0; 9 | left: 0; 10 | z-index: @zindexPopover; 11 | display: none; 12 | max-width: 276px; 13 | padding: 1px; 14 | text-align: left; // Reset given new insertion method 15 | background-color: @popoverBackground; 16 | -webkit-background-clip: padding-box; 17 | -moz-background-clip: padding; 18 | background-clip: padding-box; 19 | border: 1px solid #ccc; 20 | border: 1px solid rgba(0,0,0,.2); 21 | .border-radius(6px); 22 | .box-shadow(0 5px 10px rgba(0,0,0,.2)); 23 | 24 | // Overrides for proper insertion 25 | white-space: normal; 26 | 27 | // Offset the popover to account for the popover arrow 28 | &.top { margin-top: -10px; } 29 | &.right { margin-left: 10px; } 30 | &.bottom { margin-top: 10px; } 31 | &.left { margin-left: -10px; } 32 | } 33 | 34 | .popover-title { 35 | margin: 0; // reset heading margin 36 | padding: 8px 14px; 37 | font-size: 14px; 38 | font-weight: normal; 39 | line-height: 18px; 40 | background-color: @popoverTitleBackground; 41 | border-bottom: 1px solid darken(@popoverTitleBackground, 5%); 42 | .border-radius(5px 5px 0 0); 43 | 44 | &:empty { 45 | display: none; 46 | } 47 | } 48 | 49 | .popover-content { 50 | padding: 9px 14px; 51 | } 52 | 53 | // Arrows 54 | // 55 | // .arrow is outer, .arrow:after is inner 56 | 57 | .popover .arrow, 58 | .popover .arrow:after { 59 | position: absolute; 60 | display: block; 61 | width: 0; 62 | height: 0; 63 | border-color: transparent; 64 | border-style: solid; 65 | } 66 | .popover .arrow { 67 | border-width: @popoverArrowOuterWidth; 68 | } 69 | .popover .arrow:after { 70 | border-width: @popoverArrowWidth; 71 | content: ""; 72 | } 73 | 74 | .popover { 75 | &.top .arrow { 76 | left: 50%; 77 | margin-left: -@popoverArrowOuterWidth; 78 | border-bottom-width: 0; 79 | border-top-color: #999; // IE8 fallback 80 | border-top-color: @popoverArrowOuterColor; 81 | bottom: -@popoverArrowOuterWidth; 82 | &:after { 83 | bottom: 1px; 84 | margin-left: -@popoverArrowWidth; 85 | border-bottom-width: 0; 86 | border-top-color: @popoverArrowColor; 87 | } 88 | } 89 | &.right .arrow { 90 | top: 50%; 91 | left: -@popoverArrowOuterWidth; 92 | margin-top: -@popoverArrowOuterWidth; 93 | border-left-width: 0; 94 | border-right-color: #999; // IE8 fallback 95 | border-right-color: @popoverArrowOuterColor; 96 | &:after { 97 | left: 1px; 98 | bottom: -@popoverArrowWidth; 99 | border-left-width: 0; 100 | border-right-color: @popoverArrowColor; 101 | } 102 | } 103 | &.bottom .arrow { 104 | left: 50%; 105 | margin-left: -@popoverArrowOuterWidth; 106 | border-top-width: 0; 107 | border-bottom-color: #999; // IE8 fallback 108 | border-bottom-color: @popoverArrowOuterColor; 109 | top: -@popoverArrowOuterWidth; 110 | &:after { 111 | top: 1px; 112 | margin-left: -@popoverArrowWidth; 113 | border-top-width: 0; 114 | border-bottom-color: @popoverArrowColor; 115 | } 116 | } 117 | 118 | &.left .arrow { 119 | top: 50%; 120 | right: -@popoverArrowOuterWidth; 121 | margin-top: -@popoverArrowOuterWidth; 122 | border-right-width: 0; 123 | border-left-color: #999; // IE8 fallback 124 | border-left-color: @popoverArrowOuterColor; 125 | &:after { 126 | right: 1px; 127 | border-right-width: 0; 128 | border-left-color: @popoverArrowColor; 129 | bottom: -@popoverArrowWidth; 130 | } 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /lib/bootstrap/js/bootstrap-popover.js: -------------------------------------------------------------------------------- 1 | //Wrapped in an outer function to preserve global this 2 | (function (root) { var amdExports; define(['bootstrap/bootstrap-transition','bootstrap/bootstrap-tooltip'], function () { (function () { 3 | 4 | /* =========================================================== 5 | * bootstrap-popover.js v2.3.2 6 | * http://twitter.github.com/bootstrap/javascript.html#popovers 7 | * =========================================================== 8 | * Copyright 2012 Twitter, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * =========================================================== */ 22 | 23 | 24 | !function ($) { 25 | 26 | "use strict"; // jshint ;_; 27 | 28 | 29 | /* POPOVER PUBLIC CLASS DEFINITION 30 | * =============================== */ 31 | 32 | var Popover = function (element, options) { 33 | this.init('popover', element, options) 34 | } 35 | 36 | 37 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js 38 | ========================================== */ 39 | 40 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { 41 | 42 | constructor: Popover 43 | 44 | , setContent: function () { 45 | var $tip = this.tip() 46 | , title = this.getTitle() 47 | , content = this.getContent() 48 | 49 | $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) 50 | $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content) 51 | 52 | $tip.removeClass('fade top bottom left right in') 53 | } 54 | 55 | , hasContent: function () { 56 | return this.getTitle() || this.getContent() 57 | } 58 | 59 | , getContent: function () { 60 | var content 61 | , $e = this.$element 62 | , o = this.options 63 | 64 | content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) 65 | || $e.attr('data-content') 66 | 67 | return content 68 | } 69 | 70 | , tip: function () { 71 | if (!this.$tip) { 72 | this.$tip = $(this.options.template) 73 | } 74 | return this.$tip 75 | } 76 | 77 | , destroy: function () { 78 | this.hide().$element.off('.' + this.type).removeData(this.type) 79 | } 80 | 81 | }) 82 | 83 | 84 | /* POPOVER PLUGIN DEFINITION 85 | * ======================= */ 86 | 87 | var old = $.fn.popover 88 | 89 | $.fn.popover = function (option) { 90 | return this.each(function () { 91 | var $this = $(this) 92 | , data = $this.data('popover') 93 | , options = typeof option == 'object' && option 94 | if (!data) $this.data('popover', (data = new Popover(this, options))) 95 | if (typeof option == 'string') data[option]() 96 | }) 97 | } 98 | 99 | $.fn.popover.Constructor = Popover 100 | 101 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { 102 | placement: 'right' 103 | , trigger: 'click' 104 | , content: '' 105 | , template: '

      ' 106 | }) 107 | 108 | 109 | /* POPOVER NO CONFLICT 110 | * =================== */ 111 | 112 | $.fn.popover.noConflict = function () { 113 | $.fn.popover = old 114 | return this 115 | } 116 | 117 | }(window.jQuery); 118 | 119 | 120 | 121 | }.call(root)); 122 | return amdExports; 123 | }); }(this)); 124 | -------------------------------------------------------------------------------- /grunt.js: -------------------------------------------------------------------------------- 1 | /*global module:false*/ 2 | module.exports = function(grunt) { 3 | 4 | grunt.loadNpmTasks('grunt-contrib'); 5 | grunt.loadNpmTasks('grunt-recess'); 6 | 7 | // Project configuration. 8 | grunt.initConfig({ 9 | pkg: '', 10 | meta: { 11 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 12 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 13 | '<%= pkg.homepage ? "* " + pkg.homepage + "\n" : "" %>' + 14 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 15 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */' 16 | }, 17 | min: { 18 | all: { 19 | src: ['', 'dist/all.js'], 20 | dest: 'dist/all.min.js' 21 | }, 22 | loader: { 23 | src: ['', 'dist/loader.js'], 24 | dest: 'dist/loader.min.js' 25 | } 26 | }, 27 | qunit: { 28 | tests: ['test/**/*.html'] 29 | }, 30 | lint: { 31 | files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'] 32 | }, 33 | watch: { 34 | files: ['grunt.js', 'lib/**', 'src/**', 'test/**'], 35 | tasks: 'lint qunit recess' 36 | }, 37 | jshint: { 38 | options: { 39 | curly: false, 40 | eqeqeq: true, 41 | immed: true, 42 | latedef: true, 43 | newcap: true, 44 | noarg: true, 45 | sub: true, 46 | undef: true, 47 | unused: true, 48 | boss: true, 49 | eqnull: true, 50 | browser: true 51 | }, 52 | globals: { 53 | jQuery: true, 54 | define: true, 55 | require: true 56 | } 57 | }, 58 | uglify: {}, 59 | requirejs: { 60 | combine: { 61 | options: { 62 | appDir: 'src', 63 | baseUrl: '.', 64 | dir: 'dist', 65 | optimize: 'none', 66 | optimizeCss: 'none', 67 | wrap: true, 68 | paths: { 69 | almond: '../lib/almond', 70 | bootstrap: '../lib/bootstrap/js', 71 | jquery: '../lib/jquery', 72 | fuelux: '../dist' 73 | }, 74 | modules: [ 75 | { 76 | name: 'fuelux/all', 77 | exclude: ['jquery'] 78 | }, 79 | { 80 | name: 'fuelux/loader', 81 | include: ['almond', 'fuelux/all'], 82 | exclude: ['jquery'] 83 | } 84 | ] 85 | } 86 | } 87 | }, 88 | recess: { 89 | compile: { 90 | src: ['src/less/fuelux.less'], 91 | dest: 'dist/css/fuelux.css', 92 | options: { 93 | compile: true 94 | } 95 | }, 96 | compile_responsive: { 97 | src: ['src/less/fuelux-responsive.less'], 98 | dest: 'dist/css/fuelux-responsive.css', 99 | options: { 100 | compile: true 101 | } 102 | }, 103 | compress: { 104 | src: ['src/less/fuelux.less'], 105 | dest: 'dist/css/fuelux.min.css', 106 | options: { 107 | compile: true, 108 | compress: true 109 | } 110 | }, 111 | compress_responsive: { 112 | src: ['src/less/fuelux-responsive.less'], 113 | dest: 'dist/css/fuelux-responsive.min.css', 114 | options: { 115 | compile: true, 116 | compress: true 117 | } 118 | } 119 | }, 120 | clean: { 121 | dist: ['dist/build.txt', 'dist/fuelux.zip'], 122 | zipsrc: ['dist/fuelux'] 123 | }, 124 | copy: { 125 | images: { 126 | options: { 127 | basePath: 'lib/bootstrap/img' 128 | }, 129 | files: { 130 | 'dist/img': 'lib/bootstrap/img/**' 131 | } 132 | }, 133 | zipsrc: { 134 | options: { 135 | basePath: 'dist' 136 | }, 137 | files: { 138 | 'dist/fuelux': 'dist/**' 139 | } 140 | } 141 | }, 142 | compress: { 143 | zip: { 144 | files: { 145 | 'dist/fuelux.zip': 'dist/fuelux/**' 146 | }, 147 | options: { 148 | mode: 'zip', 149 | basePath: 'dist/' 150 | } 151 | } 152 | } 153 | }); 154 | 155 | // Default task. 156 | grunt.registerTask('default', 'lint qunit requirejs recess copy:images clean:dist min copy:zipsrc compress clean:zipsrc'); 157 | grunt.registerTask('devserver', 'lint qunit recess server watch'); // development server 158 | 159 | }; 160 | -------------------------------------------------------------------------------- /test/search-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/search'], function($) { 6 | 7 | module("Fuel UX search"); 8 | 9 | test("should be defined on jquery object", function () { 10 | ok($(document.body).search, 'search method is defined'); 11 | }); 12 | 13 | test("should return element", function () { 14 | ok($(document.body).search()[0] === document.body, 'document.body returned'); 15 | }); 16 | 17 | test("should ignore empty search", function () { 18 | var searchHTML = '
      '; 19 | 20 | var $search = $(searchHTML).search(); 21 | 22 | $search.find('button').click(); 23 | 24 | equal($search.find('i').attr('class'), 'icon-search', 'search icon has not changed'); 25 | }); 26 | 27 | test("should ignore disabled button click", function () { 28 | var searchHTML = '
      '; 29 | 30 | var $search = $(searchHTML).search(); 31 | 32 | $search.find('input').val('search text'); 33 | $search.find('button').click(); 34 | 35 | equal($search.find('i').attr('class'), 'icon-search', 'search icon has not changed'); 36 | }); 37 | 38 | test("should process valid search", function () { 39 | var searchHTML = '
      '; 40 | var searchText = ''; 41 | 42 | var $search = $(searchHTML).search().on('searched', function (e, text) { searchText = text; }); 43 | 44 | $search.find('input').val('search text'); 45 | $search.find('button').click(); 46 | 47 | equal($search.find('i').attr('class'), 'icon-remove', 'search icon has changed'); 48 | equal(searchText, 'search text', 'search text was provided in event'); 49 | }); 50 | 51 | test("should allow search to be cleared", function () { 52 | var searchHTML = '
      '; 53 | var clearedEventFired = false; 54 | 55 | var $search = $(searchHTML).search().on('cleared', function (e, text) { clearedEventFired = true; }); 56 | 57 | $search.find('input').val('search text'); 58 | $search.find('button').click(); 59 | $search.find('button').click(); 60 | 61 | equal($search.find('i').attr('class'), 'icon-search', 'search icon has returned'); 62 | equal($search.find('input').val(), '', 'search text has been cleared'); 63 | equal(clearedEventFired, true, 'cleared event was fired'); 64 | }); 65 | 66 | test("should process sequential searches", function () { 67 | var searchHTML = '
      '; 68 | var searchText = ''; 69 | 70 | var $search = $(searchHTML).search().on('searched', function (e, text) { searchText = text; }); 71 | 72 | $search.find('input').val('search text'); 73 | $search.find('button').click(); 74 | 75 | equal($search.find('i').attr('class'), 'icon-remove', 'search icon has changed'); 76 | equal(searchText, 'search text', 'search text was provided in event'); 77 | 78 | $search.find('input').val('search text 2').keyup(); 79 | equal($search.find('i').attr('class'), 'icon-search', 'search icon has returned'); 80 | 81 | $search.find('button').click(); 82 | 83 | equal($search.find('i').attr('class'), 'icon-remove', 'search icon has changed'); 84 | equal(searchText, 'search text 2', 'search text was provided in event'); 85 | }); 86 | 87 | test("should correctly respond to disable and enable methods", function () { 88 | var searchHTML = '
      '; 89 | 90 | var $search = $(searchHTML).search('disable'); 91 | 92 | equal($search.find('input').attr('disabled'), 'disabled', 'input was disabled'); 93 | equal($search.find('button').hasClass('disabled'), true, 'button was disabled'); 94 | 95 | $search.search('enable'); 96 | 97 | equal($search.find('input').attr('disabled'), undefined, 'input was enabled'); 98 | equal($search.find('button').hasClass('disabled'), false, 'button was enabled'); 99 | }); 100 | 101 | }); -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-button.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-buttons") 4 | 5 | test("should provide no conflict", function () { 6 | var button = $.fn.button.noConflict() 7 | ok(!$.fn.button, 'button was set back to undefined (org value)') 8 | $.fn.button = button 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | ok($(document.body).button, 'button method is defined') 13 | }) 14 | 15 | test("should return element", function () { 16 | ok($(document.body).button()[0] == document.body, 'document.body returned') 17 | }) 18 | 19 | test("should return set state to loading", function () { 20 | var btn = $('') 21 | equals(btn.html(), 'mdo', 'btn text equals mdo') 22 | btn.button('loading') 23 | equals(btn.html(), 'fat', 'btn text equals fat') 24 | stop() 25 | setTimeout(function () { 26 | ok(btn.attr('disabled'), 'btn is disabled') 27 | ok(btn.hasClass('disabled'), 'btn has disabled class') 28 | start() 29 | }, 0) 30 | }) 31 | 32 | test("should return reset state", function () { 33 | var btn = $('') 34 | equals(btn.html(), 'mdo', 'btn text equals mdo') 35 | btn.button('loading') 36 | equals(btn.html(), 'fat', 'btn text equals fat') 37 | stop() 38 | setTimeout(function () { 39 | ok(btn.attr('disabled'), 'btn is disabled') 40 | ok(btn.hasClass('disabled'), 'btn has disabled class') 41 | start() 42 | stop() 43 | }, 0) 44 | btn.button('reset') 45 | equals(btn.html(), 'mdo', 'btn text equals mdo') 46 | setTimeout(function () { 47 | ok(!btn.attr('disabled'), 'btn is not disabled') 48 | ok(!btn.hasClass('disabled'), 'btn does not have disabled class') 49 | start() 50 | }, 0) 51 | }) 52 | 53 | test("should toggle active", function () { 54 | var btn = $('') 55 | ok(!btn.hasClass('active'), 'btn does not have active class') 56 | btn.button('toggle') 57 | ok(btn.hasClass('active'), 'btn has class active') 58 | }) 59 | 60 | test("should toggle active when btn children are clicked", function () { 61 | var btn = $('') 62 | , inner = $('') 63 | btn 64 | .append(inner) 65 | .appendTo($('#qunit-fixture')) 66 | ok(!btn.hasClass('active'), 'btn does not have active class') 67 | inner.click() 68 | ok(btn.hasClass('active'), 'btn has class active') 69 | }) 70 | 71 | test("should toggle active when btn children are clicked within btn-group", function () { 72 | var btngroup = $('
      ') 73 | , btn = $('') 74 | , inner = $('') 75 | btngroup 76 | .append(btn.append(inner)) 77 | .appendTo($('#qunit-fixture')) 78 | ok(!btn.hasClass('active'), 'btn does not have active class') 79 | inner.click() 80 | ok(btn.hasClass('active'), 'btn has class active') 81 | }) 82 | 83 | test("should check for closest matching toggle", function () { 84 | var group = $("
      ") 85 | , btn1 = $("") 86 | , btn2 = $("") 87 | , wrap = $("
      ") 88 | 89 | wrap.append(btn1, btn2) 90 | 91 | group 92 | .append(wrap) 93 | .appendTo($('#qunit-fixture')) 94 | 95 | ok(btn1.hasClass('active'), 'btn1 has active class') 96 | ok(!btn2.hasClass('active'), 'btn2 does not have active class') 97 | btn2.click() 98 | ok(!btn1.hasClass('active'), 'btn1 does not have active class') 99 | ok(btn2.hasClass('active'), 'btn2 has active class') 100 | }) 101 | 102 | }) -------------------------------------------------------------------------------- /lib/bootstrap/js/bootstrap-affix.js: -------------------------------------------------------------------------------- 1 | //Wrapped in an outer function to preserve global this 2 | (function (root) { var amdExports; define(['bootstrap/bootstrap-transition'], function () { (function () { 3 | 4 | /* ========================================================== 5 | * bootstrap-affix.js v2.3.2 6 | * http://twitter.github.com/bootstrap/javascript.html#affix 7 | * ========================================================== 8 | * Copyright 2012 Twitter, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * ========================================================== */ 22 | 23 | 24 | !function ($) { 25 | 26 | "use strict"; // jshint ;_; 27 | 28 | 29 | /* AFFIX CLASS DEFINITION 30 | * ====================== */ 31 | 32 | var Affix = function (element, options) { 33 | this.options = $.extend({}, $.fn.affix.defaults, options) 34 | this.$window = $(window) 35 | .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) 36 | .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) 37 | this.$element = $(element) 38 | this.checkPosition() 39 | } 40 | 41 | Affix.prototype.checkPosition = function () { 42 | if (!this.$element.is(':visible')) return 43 | 44 | var scrollHeight = $(document).height() 45 | , scrollTop = this.$window.scrollTop() 46 | , position = this.$element.offset() 47 | , offset = this.options.offset 48 | , offsetBottom = offset.bottom 49 | , offsetTop = offset.top 50 | , reset = 'affix affix-top affix-bottom' 51 | , affix 52 | 53 | if (typeof offset != 'object') offsetBottom = offsetTop = offset 54 | if (typeof offsetTop == 'function') offsetTop = offset.top() 55 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() 56 | 57 | affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? 58 | false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 59 | 'bottom' : offsetTop != null && scrollTop <= offsetTop ? 60 | 'top' : false 61 | 62 | if (this.affixed === affix) return 63 | 64 | this.affixed = affix 65 | this.unpin = affix == 'bottom' ? position.top - scrollTop : null 66 | 67 | this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) 68 | } 69 | 70 | 71 | /* AFFIX PLUGIN DEFINITION 72 | * ======================= */ 73 | 74 | var old = $.fn.affix 75 | 76 | $.fn.affix = function (option) { 77 | return this.each(function () { 78 | var $this = $(this) 79 | , data = $this.data('affix') 80 | , options = typeof option == 'object' && option 81 | if (!data) $this.data('affix', (data = new Affix(this, options))) 82 | if (typeof option == 'string') data[option]() 83 | }) 84 | } 85 | 86 | $.fn.affix.Constructor = Affix 87 | 88 | $.fn.affix.defaults = { 89 | offset: 0 90 | } 91 | 92 | 93 | /* AFFIX NO CONFLICT 94 | * ================= */ 95 | 96 | $.fn.affix.noConflict = function () { 97 | $.fn.affix = old 98 | return this 99 | } 100 | 101 | 102 | /* AFFIX DATA-API 103 | * ============== */ 104 | 105 | $(window).on('load', function () { 106 | $('[data-spy="affix"]').each(function () { 107 | var $spy = $(this) 108 | , data = $spy.data() 109 | 110 | data.offset = data.offset || {} 111 | 112 | data.offsetBottom && (data.offset.bottom = data.offsetBottom) 113 | data.offsetTop && (data.offset.top = data.offsetTop) 114 | 115 | $spy.affix(data) 116 | }) 117 | }) 118 | 119 | 120 | }(window.jQuery); 121 | 122 | 123 | }.call(root)); 124 | return amdExports; 125 | }); }(this)); 126 | -------------------------------------------------------------------------------- /lib/bootstrap/js/bootstrap-tab.js: -------------------------------------------------------------------------------- 1 | //Wrapped in an outer function to preserve global this 2 | (function (root) { var amdExports; define(['bootstrap/bootstrap-transition'], function () { (function () { 3 | 4 | /* ======================================================== 5 | * bootstrap-tab.js v2.3.2 6 | * http://twitter.github.com/bootstrap/javascript.html#tabs 7 | * ======================================================== 8 | * Copyright 2012 Twitter, Inc. 9 | * 10 | * Licensed under the Apache License, Version 2.0 (the "License"); 11 | * you may not use this file except in compliance with the License. 12 | * You may obtain a copy of the License at 13 | * 14 | * http://www.apache.org/licenses/LICENSE-2.0 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | * ======================================================== */ 22 | 23 | 24 | !function ($) { 25 | 26 | "use strict"; // jshint ;_; 27 | 28 | 29 | /* TAB CLASS DEFINITION 30 | * ==================== */ 31 | 32 | var Tab = function (element) { 33 | this.element = $(element) 34 | } 35 | 36 | Tab.prototype = { 37 | 38 | constructor: Tab 39 | 40 | , show: function () { 41 | var $this = this.element 42 | , $ul = $this.closest('ul:not(.dropdown-menu)') 43 | , selector = $this.attr('data-target') 44 | , previous 45 | , $target 46 | , e 47 | 48 | if (!selector) { 49 | selector = $this.attr('href') 50 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 51 | } 52 | 53 | if ( $this.parent('li').hasClass('active') ) return 54 | 55 | previous = $ul.find('.active:last a')[0] 56 | 57 | e = $.Event('show', { 58 | relatedTarget: previous 59 | }) 60 | 61 | $this.trigger(e) 62 | 63 | if (e.isDefaultPrevented()) return 64 | 65 | $target = $(selector) 66 | 67 | this.activate($this.parent('li'), $ul) 68 | this.activate($target, $target.parent(), function () { 69 | $this.trigger({ 70 | type: 'shown' 71 | , relatedTarget: previous 72 | }) 73 | }) 74 | } 75 | 76 | , activate: function ( element, container, callback) { 77 | var $active = container.find('> .active') 78 | , transition = callback 79 | && $.support.transition 80 | && $active.hasClass('fade') 81 | 82 | function next() { 83 | $active 84 | .removeClass('active') 85 | .find('> .dropdown-menu > .active') 86 | .removeClass('active') 87 | 88 | element.addClass('active') 89 | 90 | if (transition) { 91 | element[0].offsetWidth // reflow for transition 92 | element.addClass('in') 93 | } else { 94 | element.removeClass('fade') 95 | } 96 | 97 | if ( element.parent('.dropdown-menu') ) { 98 | element.closest('li.dropdown').addClass('active') 99 | } 100 | 101 | callback && callback() 102 | } 103 | 104 | transition ? 105 | $active.one($.support.transition.end, next) : 106 | next() 107 | 108 | $active.removeClass('in') 109 | } 110 | } 111 | 112 | 113 | /* TAB PLUGIN DEFINITION 114 | * ===================== */ 115 | 116 | var old = $.fn.tab 117 | 118 | $.fn.tab = function ( option ) { 119 | return this.each(function () { 120 | var $this = $(this) 121 | , data = $this.data('tab') 122 | if (!data) $this.data('tab', (data = new Tab(this))) 123 | if (typeof option == 'string') data[option]() 124 | }) 125 | } 126 | 127 | $.fn.tab.Constructor = Tab 128 | 129 | 130 | /* TAB NO CONFLICT 131 | * =============== */ 132 | 133 | $.fn.tab.noConflict = function () { 134 | $.fn.tab = old 135 | return this 136 | } 137 | 138 | 139 | /* TAB DATA-API 140 | * ============ */ 141 | 142 | $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 143 | e.preventDefault() 144 | $(this).tab('show') 145 | }) 146 | 147 | }(window.jQuery); 148 | 149 | 150 | }.call(root)); 151 | return amdExports; 152 | }); }(this)); 153 | -------------------------------------------------------------------------------- /test/select-test.js: -------------------------------------------------------------------------------- 1 | /*global QUnit:false, module:false, test:false, asyncTest:false, expect:false*/ 2 | /*global start:false, stop:false ok:false, equal:false, notEqual:false, deepEqual:false*/ 3 | /*global notDeepEqual:false, strictEqual:false, notStrictEqual:false, raises:false*/ 4 | 5 | require(['jquery', 'fuelux/select'], function ($) { 6 | 7 | var html = '
      ' + 8 | '' + 9 | '' + 16 | '
      '; 17 | 18 | 19 | module("Fuel UX select"); 20 | 21 | test("should be defined on jquery object", function () { 22 | ok($(document.body).select, 'select method is defined'); 23 | }); 24 | 25 | test("should return element", function () { 26 | ok($(document.body).select()[0] === document.body, 'document.body returned'); 27 | }); 28 | 29 | test("should set disabled state", function () { 30 | var $select = $(html).select(); 31 | $select.select('disable'); 32 | equal($select.find('.btn').hasClass('disabled'), true, 'element disabled'); 33 | }); 34 | 35 | test("should set enabled state", function () { 36 | var $select = $(html).select(); 37 | $select.select('disable'); 38 | $select.select('enable'); 39 | equal($select.find('.btn').hasClass('disabled'), false, 'element enabled'); 40 | }); 41 | 42 | test("should set default selection", function () { 43 | // should be "Three" based on the data-selected attribute 44 | var $select = $(html).select(); 45 | var item = $select.select('selectedItem'); 46 | var expectedItem = { text: 'Three', value: 3 }; 47 | deepEqual(item, expectedItem, 'default item selected'); 48 | }); 49 | 50 | test("should select by index", function () { 51 | var $select = $(html).select(); 52 | $select.select('selectByIndex', 0); 53 | 54 | var item = $select.select('selectedItem'); 55 | var expectedItem = { text: 'One', value: 1 }; 56 | deepEqual(item, expectedItem, 'item selected'); 57 | }); 58 | 59 | test("should select by value", function () { 60 | var $select = $(html).select(); 61 | $select.select('selectByValue', 2); 62 | 63 | var item = $select.select('selectedItem'); 64 | var expectedItem = { text: 'Two', value: 2 }; 65 | deepEqual(item, expectedItem, 'item selected'); 66 | }); 67 | 68 | test("should select by value with whitespace", function () { 69 | var $select = $(html).select(); 70 | $select.select('selectByValue', 'Item Five'); 71 | 72 | var item = $select.select('selectedItem'); 73 | var expectedItem = { text: 'Item Five', value: 'Item Five' }; 74 | deepEqual(item, expectedItem, 'item selected'); 75 | }); 76 | 77 | test("should select by text", function () { 78 | var $select = $(html).select(); 79 | $select.select('selectByText', 'THREE'); 80 | 81 | var item = $select.select('selectedItem'); 82 | var expectedItem = { text: 'Three' }; 83 | deepEqual(item, expectedItem, 'item selected'); 84 | }); 85 | 86 | test("should select by text with whitespace", function () { 87 | var $select = $(html).select(); 88 | $select.select('selectByText', 'Item Five'); 89 | 90 | var item = $select.select('selectedItem'); 91 | var expectedItem = { text: 'Item Five' }; 92 | deepEqual(item, expectedItem, 'item selected'); 93 | }); 94 | 95 | test("should select by selector", function () { 96 | var $select = $(html).select(); 97 | $select.select('selectBySelector', 'li[data-fizz=buzz]'); 98 | 99 | var item = $select.select('selectedItem'); 100 | var expectedItem = { text: 'Four', value: 4, foo: 'bar', fizz: 'buzz' }; 101 | deepEqual(item, expectedItem, 'item selected'); 102 | }); 103 | 104 | test("should fire changed event", function () { 105 | var eventFired = false; 106 | var selectedText = ''; 107 | var selectedValue = ''; 108 | 109 | var $select = $(html).select().on('changed', function (evt, data) { 110 | eventFired = true; 111 | selectedText = data.text; 112 | selectedValue = data.value; 113 | }); 114 | 115 | // simulate changed event 116 | $select.find('a:first').click(); 117 | 118 | equal(eventFired, true, 'changed event fired'); 119 | equal(selectedText, 'One', 'text passed in from changed event'); 120 | equal(selectedValue, 1, 'value passed in from changed event'); 121 | }); 122 | }); -------------------------------------------------------------------------------- /lib/bootstrap/less/responsive-767px-max.less: -------------------------------------------------------------------------------- 1 | // 2 | // Responsive: Landscape phone to desktop/tablet 3 | // -------------------------------------------------- 4 | 5 | 6 | @media (max-width: 767px) { 7 | 8 | // Padding to set content in a bit 9 | body { 10 | padding-left: 20px; 11 | padding-right: 20px; 12 | } 13 | // Negative indent the now static "fixed" navbar 14 | .navbar-fixed-top, 15 | .navbar-fixed-bottom, 16 | .navbar-static-top { 17 | margin-left: -20px; 18 | margin-right: -20px; 19 | } 20 | // Remove padding on container given explicit padding set on body 21 | .container-fluid { 22 | padding: 0; 23 | } 24 | 25 | // TYPOGRAPHY 26 | // ---------- 27 | // Reset horizontal dl 28 | .dl-horizontal { 29 | dt { 30 | float: none; 31 | clear: none; 32 | width: auto; 33 | text-align: left; 34 | } 35 | dd { 36 | margin-left: 0; 37 | } 38 | } 39 | 40 | // GRID & CONTAINERS 41 | // ----------------- 42 | // Remove width from containers 43 | .container { 44 | width: auto; 45 | } 46 | // Fluid rows 47 | .row-fluid { 48 | width: 100%; 49 | } 50 | // Undo negative margin on rows and thumbnails 51 | .row, 52 | .thumbnails { 53 | margin-left: 0; 54 | } 55 | .thumbnails > li { 56 | float: none; 57 | margin-left: 0; // Reset the default margin for all li elements when no .span* classes are present 58 | } 59 | // Make all grid-sized elements block level again 60 | [class*="span"], 61 | .uneditable-input[class*="span"], // Makes uneditable inputs full-width when using grid sizing 62 | .row-fluid [class*="span"] { 63 | float: none; 64 | display: block; 65 | width: 100%; 66 | margin-left: 0; 67 | .box-sizing(border-box); 68 | } 69 | .span12, 70 | .row-fluid .span12 { 71 | width: 100%; 72 | .box-sizing(border-box); 73 | } 74 | .row-fluid [class*="offset"]:first-child { 75 | margin-left: 0; 76 | } 77 | 78 | // FORM FIELDS 79 | // ----------- 80 | // Make span* classes full width 81 | .input-large, 82 | .input-xlarge, 83 | .input-xxlarge, 84 | input[class*="span"], 85 | select[class*="span"], 86 | textarea[class*="span"], 87 | .uneditable-input { 88 | .input-block-level(); 89 | } 90 | // But don't let it screw up prepend/append inputs 91 | .input-prepend input, 92 | .input-append input, 93 | .input-prepend input[class*="span"], 94 | .input-append input[class*="span"] { 95 | display: inline-block; // redeclare so they don't wrap to new lines 96 | width: auto; 97 | } 98 | .controls-row [class*="span"] + [class*="span"] { 99 | margin-left: 0; 100 | } 101 | 102 | // Modals 103 | .modal { 104 | position: fixed; 105 | top: 20px; 106 | left: 20px; 107 | right: 20px; 108 | width: auto; 109 | margin: 0; 110 | &.fade { top: -100px; } 111 | &.fade.in { top: 20px; } 112 | } 113 | 114 | } 115 | 116 | 117 | 118 | // UP TO LANDSCAPE PHONE 119 | // --------------------- 120 | 121 | @media (max-width: 480px) { 122 | 123 | // Smooth out the collapsing/expanding nav 124 | .nav-collapse { 125 | -webkit-transform: translate3d(0, 0, 0); // activate the GPU 126 | } 127 | 128 | // Block level the page header small tag for readability 129 | .page-header h1 small { 130 | display: block; 131 | line-height: @baseLineHeight; 132 | } 133 | 134 | // Update checkboxes for iOS 135 | input[type="checkbox"], 136 | input[type="radio"] { 137 | border: 1px solid #ccc; 138 | } 139 | 140 | // Remove the horizontal form styles 141 | .form-horizontal { 142 | .control-label { 143 | float: none; 144 | width: auto; 145 | padding-top: 0; 146 | text-align: left; 147 | } 148 | // Move over all input controls and content 149 | .controls { 150 | margin-left: 0; 151 | } 152 | // Move the options list down to align with labels 153 | .control-list { 154 | padding-top: 0; // has to be padding because margin collaspes 155 | } 156 | // Move over buttons in .form-actions to align with .controls 157 | .form-actions { 158 | padding-left: 10px; 159 | padding-right: 10px; 160 | } 161 | } 162 | 163 | // Medias 164 | // Reset float and spacing to stack 165 | .media .pull-left, 166 | .media .pull-right { 167 | float: none; 168 | display: block; 169 | margin-bottom: 10px; 170 | } 171 | // Remove side margins since we stack instead of indent 172 | .media-object { 173 | margin-right: 0; 174 | margin-left: 0; 175 | } 176 | 177 | // Modals 178 | .modal { 179 | top: 10px; 180 | left: 10px; 181 | right: 10px; 182 | } 183 | .modal-header .close { 184 | padding: 10px; 185 | margin: -10px; 186 | } 187 | 188 | // Carousel 189 | .carousel-caption { 190 | position: static; 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-popover.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-popover") 4 | 5 | test("should provide no conflict", function () { 6 | var popover = $.fn.popover.noConflict() 7 | ok(!$.fn.popover, 'popover was set back to undefined (org value)') 8 | $.fn.popover = popover 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | var div = $('
      ') 13 | ok(div.popover, 'popover method is defined') 14 | }) 15 | 16 | test("should return element", function () { 17 | var div = $('
      ') 18 | ok(div.popover() == div, 'document.body returned') 19 | }) 20 | 21 | test("should render popover element", function () { 22 | $.support.transition = false 23 | var popover = $('@mdo') 24 | .appendTo('#qunit-fixture') 25 | .popover('show') 26 | 27 | ok($('.popover').length, 'popover was inserted') 28 | popover.popover('hide') 29 | ok(!$(".popover").length, 'popover removed') 30 | }) 31 | 32 | test("should store popover instance in popover data object", function () { 33 | $.support.transition = false 34 | var popover = $('@mdo') 35 | .popover() 36 | 37 | ok(!!popover.data('popover'), 'popover instance exists') 38 | }) 39 | 40 | test("should get title and content from options", function () { 41 | $.support.transition = false 42 | var popover = $('@fat') 43 | .appendTo('#qunit-fixture') 44 | .popover({ 45 | title: function () { 46 | return '@fat' 47 | } 48 | , content: function () { 49 | return 'loves writing tests (╯°□°)╯︵ ┻━┻' 50 | } 51 | }) 52 | 53 | popover.popover('show') 54 | 55 | ok($('.popover').length, 'popover was inserted') 56 | equals($('.popover .popover-title').text(), '@fat', 'title correctly inserted') 57 | equals($('.popover .popover-content').text(), 'loves writing tests (╯°□°)╯︵ ┻━┻', 'content correctly inserted') 58 | 59 | popover.popover('hide') 60 | ok(!$('.popover').length, 'popover was removed') 61 | $('#qunit-fixture').empty() 62 | }) 63 | 64 | test("should get title and content from attributes", function () { 65 | $.support.transition = false 66 | var popover = $('@mdo') 67 | .appendTo('#qunit-fixture') 68 | .popover() 69 | .popover('show') 70 | 71 | ok($('.popover').length, 'popover was inserted') 72 | equals($('.popover .popover-title').text(), '@mdo', 'title correctly inserted') 73 | equals($('.popover .popover-content').text(), "loves data attributes (づ。◕‿‿◕。)づ ︵ ┻━┻", 'content correctly inserted') 74 | 75 | popover.popover('hide') 76 | ok(!$('.popover').length, 'popover was removed') 77 | $('#qunit-fixture').empty() 78 | }) 79 | 80 | test("should respect custom classes", function() { 81 | $.support.transition = false 82 | var popover = $('@fat') 83 | .appendTo('#qunit-fixture') 84 | .popover({ 85 | title: 'Test' 86 | , content: 'Test' 87 | , template: '

      ' 88 | }) 89 | 90 | popover.popover('show') 91 | 92 | ok($('.popover').length, 'popover was inserted') 93 | ok($('.popover').hasClass('foobar'), 'custom class is present') 94 | 95 | popover.popover('hide') 96 | ok(!$('.popover').length, 'popover was removed') 97 | $('#qunit-fixture').empty() 98 | }) 99 | 100 | test("should destroy popover", function () { 101 | var popover = $('
      ').popover({trigger: 'hover'}).on('click.foo', function(){}) 102 | ok(popover.data('popover'), 'popover has data') 103 | ok($._data(popover[0], 'events').mouseover && $._data(popover[0], 'events').mouseout, 'popover has hover event') 104 | ok($._data(popover[0], 'events').click[0].namespace == 'foo', 'popover has extra click.foo event') 105 | popover.popover('show') 106 | popover.popover('destroy') 107 | ok(!popover.hasClass('in'), 'popover is hidden') 108 | ok(!popover.data('popover'), 'popover does not have data') 109 | ok($._data(popover[0],'events').click[0].namespace == 'foo', 'popover still has click.foo') 110 | ok(!$._data(popover[0], 'events').mouseover && !$._data(popover[0], 'events').mouseout, 'popover does not have any events') 111 | }) 112 | 113 | }) -------------------------------------------------------------------------------- /lib/bootstrap/less/tests/forms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Bootstrap, from Twitter 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
      36 | 37 | 40 | 41 |
      42 |
      43 | 44 | 45 | 50 | 51 |
      52 | 53 | 54 | 55 | 56 |
      57 | 58 | 59 | 60 | 61 |
      62 | 63 | 64 | 65 | 66 |
      67 | 68 | 69 | 70 | 71 |
      72 | 73 | 74 | 75 | 76 |
      77 | 78 | 79 | 80 | 81 |
      82 | 83 | 84 | 85 | 86 |
      87 | 88 | 89 | 90 | 91 |
      92 |
      93 | 94 | 95 | 96 | 97 |
      98 | 99 | 100 | 101 | 102 |
      103 | 104 | 105 | 106 | 107 |
      108 | 109 | 110 | 111 | 112 |
      113 | 114 | 115 | 116 | 117 |
      118 | 119 | 120 | 121 | 122 |
      123 | 124 | 125 | 126 | 127 |
      128 | 129 | 130 | 131 | 132 |
      133 | 134 | 135 | 136 | 137 |
      138 |
      139 | 140 | 141 | 142 | 143 |
      144 | 145 | 146 | 147 | 148 |
      149 | 150 | 151 | 152 | 153 |
      154 | 155 | 156 | 157 | 158 |
      159 | 160 | 161 | 162 | 163 |
      164 | 165 | 166 | 167 | 168 |
      169 | 170 | 171 | 172 | 173 |
      174 |
      175 | 176 |
      177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /src/combobox.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Combobox 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(function (require) { 10 | 11 | var $ = require('jquery'); 12 | require('./util'); 13 | 14 | // COMBOBOX CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Combobox = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.combobox.defaults, options); 19 | this.$element.on('click', 'a', $.proxy(this.itemclicked, this)); 20 | this.$element.on('change', 'input', $.proxy(this.inputchanged, this)); 21 | this.$input = this.$element.find('input'); 22 | this.$button = this.$element.find('.btn'); 23 | 24 | // set default selection 25 | this.setDefaultSelection(); 26 | }; 27 | 28 | Combobox.prototype = { 29 | 30 | constructor: Combobox, 31 | 32 | selectedItem: function () { 33 | var item = this.$selectedItem; 34 | var data = {}; 35 | 36 | if (item) { 37 | var txt = this.$selectedItem.text(); 38 | data = $.extend({ text: txt }, this.$selectedItem.data()); 39 | } 40 | else { 41 | data = { text: this.$input.val()}; 42 | } 43 | 44 | return data; 45 | }, 46 | 47 | selectByText: function (text) { 48 | var selector = 'li:fuelTextExactCI(' + text + ')'; 49 | this.selectBySelector(selector); 50 | }, 51 | 52 | selectByValue: function (value) { 53 | var selector = 'li[data-value="' + value + '"]'; 54 | this.selectBySelector(selector); 55 | }, 56 | 57 | selectByIndex: function (index) { 58 | // zero-based index 59 | var selector = 'li:eq(' + index + ')'; 60 | this.selectBySelector(selector); 61 | }, 62 | 63 | selectBySelector: function (selector) { 64 | var $item = this.$element.find(selector); 65 | 66 | if (typeof $item[0] !== 'undefined') { 67 | this.$selectedItem = $item; 68 | this.$input.val(this.$selectedItem.text()); 69 | } 70 | else { 71 | this.$selectedItem = null; 72 | } 73 | }, 74 | 75 | setDefaultSelection: function () { 76 | var selector = 'li[data-selected=true]:first'; 77 | var item = this.$element.find(selector); 78 | 79 | if (item.length > 0) { 80 | // select by data-attribute 81 | this.selectBySelector(selector); 82 | item.removeData('selected'); 83 | item.removeAttr('data-selected'); 84 | } 85 | }, 86 | 87 | enable: function () { 88 | this.$input.removeAttr('disabled'); 89 | this.$button.removeClass('disabled'); 90 | }, 91 | 92 | disable: function () { 93 | this.$input.attr('disabled', true); 94 | this.$button.addClass('disabled'); 95 | }, 96 | 97 | itemclicked: function (e) { 98 | this.$selectedItem = $(e.target).parent(); 99 | 100 | // set input text and trigger input change event marked as synthetic 101 | this.$input.val(this.$selectedItem.text()).trigger('change', { synthetic: true }); 102 | 103 | // pass object including text and any data-attributes 104 | // to onchange event 105 | var data = this.selectedItem(); 106 | 107 | // trigger changed event 108 | this.$element.trigger('changed', data); 109 | 110 | e.preventDefault(); 111 | }, 112 | 113 | inputchanged: function (e, extra) { 114 | 115 | // skip processing for internally-generated synthetic event 116 | // to avoid double processing 117 | if (extra && extra.synthetic) return; 118 | 119 | var val = $(e.target).val(); 120 | this.selectByText(val); 121 | 122 | // find match based on input 123 | // if no match, pass the input value 124 | var data = this.selectedItem(); 125 | if (data.text.length === 0) { 126 | data = { text: val }; 127 | } 128 | 129 | // trigger changed event 130 | this.$element.trigger('changed', data); 131 | 132 | } 133 | 134 | }; 135 | 136 | 137 | // COMBOBOX PLUGIN DEFINITION 138 | 139 | $.fn.combobox = function (option, value) { 140 | var methodReturn; 141 | 142 | var $set = this.each(function () { 143 | var $this = $(this); 144 | var data = $this.data('combobox'); 145 | var options = typeof option === 'object' && option; 146 | 147 | if (!data) $this.data('combobox', (data = new Combobox(this, options))); 148 | if (typeof option === 'string') methodReturn = data[option](value); 149 | }); 150 | 151 | return (methodReturn === undefined) ? $set : methodReturn; 152 | }; 153 | 154 | $.fn.combobox.defaults = {}; 155 | 156 | $.fn.combobox.Constructor = Combobox; 157 | 158 | 159 | // COMBOBOX DATA-API 160 | 161 | $(function () { 162 | 163 | $(window).on('load', function () { 164 | $('.combobox').each(function () { 165 | var $this = $(this); 166 | if ($this.data('combobox')) return; 167 | $this.combobox($this.data()); 168 | }); 169 | }); 170 | 171 | $('body').on('mousedown.combobox.data-api', '.combobox', function (e) { 172 | var $this = $(this); 173 | if ($this.data('combobox')) return; 174 | $this.combobox($this.data()); 175 | }); 176 | }); 177 | 178 | }); 179 | -------------------------------------------------------------------------------- /lib/bootstrap/js/tests/unit/bootstrap-modal.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 3 | module("bootstrap-modal") 4 | 5 | test("should provide no conflict", function () { 6 | var modal = $.fn.modal.noConflict() 7 | ok(!$.fn.modal, 'modal was set back to undefined (org value)') 8 | $.fn.modal = modal 9 | }) 10 | 11 | test("should be defined on jquery object", function () { 12 | var div = $("") 13 | ok(div.modal, 'modal method is defined') 14 | }) 15 | 16 | test("should return element", function () { 17 | var div = $("") 18 | ok(div.modal() == div, 'document.body returned') 19 | $('#modal-test').remove() 20 | }) 21 | 22 | test("should expose defaults var for settings", function () { 23 | ok($.fn.modal.defaults, 'default object exposed') 24 | }) 25 | 26 | test("should insert into dom when show method is called", function () { 27 | stop() 28 | $.support.transition = false 29 | $("") 30 | .bind("shown", function () { 31 | ok($('#modal-test').length, 'modal insterted into dom') 32 | $(this).remove() 33 | start() 34 | }) 35 | .modal("show") 36 | }) 37 | 38 | test("should fire show event", function () { 39 | stop() 40 | $.support.transition = false 41 | $("") 42 | .bind("show", function () { 43 | ok(true, "show was called") 44 | }) 45 | .bind("shown", function () { 46 | $(this).remove() 47 | start() 48 | }) 49 | .modal("show") 50 | }) 51 | 52 | test("should not fire shown when default prevented", function () { 53 | stop() 54 | $.support.transition = false 55 | $("") 56 | .bind("show", function (e) { 57 | e.preventDefault() 58 | ok(true, "show was called") 59 | start() 60 | }) 61 | .bind("shown", function () { 62 | ok(false, "shown was called") 63 | }) 64 | .modal("show") 65 | }) 66 | 67 | test("should hide modal when hide is called", function () { 68 | stop() 69 | $.support.transition = false 70 | 71 | $("") 72 | .bind("shown", function () { 73 | ok($('#modal-test').is(":visible"), 'modal visible') 74 | ok($('#modal-test').length, 'modal insterted into dom') 75 | $(this).modal("hide") 76 | }) 77 | .bind("hidden", function() { 78 | ok(!$('#modal-test').is(":visible"), 'modal hidden') 79 | $('#modal-test').remove() 80 | start() 81 | }) 82 | .modal("show") 83 | }) 84 | 85 | test("should toggle when toggle is called", function () { 86 | stop() 87 | $.support.transition = false 88 | var div = $("") 89 | div 90 | .bind("shown", function () { 91 | ok($('#modal-test').is(":visible"), 'modal visible') 92 | ok($('#modal-test').length, 'modal insterted into dom') 93 | div.modal("toggle") 94 | }) 95 | .bind("hidden", function() { 96 | ok(!$('#modal-test').is(":visible"), 'modal hidden') 97 | div.remove() 98 | start() 99 | }) 100 | .modal("toggle") 101 | }) 102 | 103 | test("should remove from dom when click [data-dismiss=modal]", function () { 104 | stop() 105 | $.support.transition = false 106 | var div = $("") 107 | div 108 | .bind("shown", function () { 109 | ok($('#modal-test').is(":visible"), 'modal visible') 110 | ok($('#modal-test').length, 'modal insterted into dom') 111 | div.find('.close').click() 112 | }) 113 | .bind("hidden", function() { 114 | ok(!$('#modal-test').is(":visible"), 'modal hidden') 115 | div.remove() 116 | start() 117 | }) 118 | .modal("toggle") 119 | }) 120 | 121 | test("should allow modal close with 'backdrop:false'", function () { 122 | stop() 123 | $.support.transition = false 124 | var div = $("
      ", { id: 'modal-test', "data-backdrop": false }) 125 | div 126 | .bind("shown", function () { 127 | ok($('#modal-test').is(":visible"), 'modal visible') 128 | div.modal("hide") 129 | }) 130 | .bind("hidden", function() { 131 | ok(!$('#modal-test').is(":visible"), 'modal hidden') 132 | div.remove() 133 | start() 134 | }) 135 | .modal("show") 136 | }) 137 | }) -------------------------------------------------------------------------------- /dist/combobox.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Fuel UX Combobox 3 | * https://github.com/ExactTarget/fuelux 4 | * 5 | * Copyright (c) 2012 ExactTarget 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | define(['require','jquery','./util'],function (require) { 10 | 11 | var $ = require('jquery'); 12 | require('./util'); 13 | 14 | // COMBOBOX CONSTRUCTOR AND PROTOTYPE 15 | 16 | var Combobox = function (element, options) { 17 | this.$element = $(element); 18 | this.options = $.extend({}, $.fn.combobox.defaults, options); 19 | this.$element.on('click', 'a', $.proxy(this.itemclicked, this)); 20 | this.$element.on('change', 'input', $.proxy(this.inputchanged, this)); 21 | this.$input = this.$element.find('input'); 22 | this.$button = this.$element.find('.btn'); 23 | 24 | // set default selection 25 | this.setDefaultSelection(); 26 | }; 27 | 28 | Combobox.prototype = { 29 | 30 | constructor: Combobox, 31 | 32 | selectedItem: function () { 33 | var item = this.$selectedItem; 34 | var data = {}; 35 | 36 | if (item) { 37 | var txt = this.$selectedItem.text(); 38 | data = $.extend({ text: txt }, this.$selectedItem.data()); 39 | } 40 | else { 41 | data = { text: this.$input.val()}; 42 | } 43 | 44 | return data; 45 | }, 46 | 47 | selectByText: function (text) { 48 | var selector = 'li:fuelTextExactCI(' + text + ')'; 49 | this.selectBySelector(selector); 50 | }, 51 | 52 | selectByValue: function (value) { 53 | var selector = 'li[data-value="' + value + '"]'; 54 | this.selectBySelector(selector); 55 | }, 56 | 57 | selectByIndex: function (index) { 58 | // zero-based index 59 | var selector = 'li:eq(' + index + ')'; 60 | this.selectBySelector(selector); 61 | }, 62 | 63 | selectBySelector: function (selector) { 64 | var $item = this.$element.find(selector); 65 | 66 | if (typeof $item[0] !== 'undefined') { 67 | this.$selectedItem = $item; 68 | this.$input.val(this.$selectedItem.text()); 69 | } 70 | else { 71 | this.$selectedItem = null; 72 | } 73 | }, 74 | 75 | setDefaultSelection: function () { 76 | var selector = 'li[data-selected=true]:first'; 77 | var item = this.$element.find(selector); 78 | 79 | if (item.length > 0) { 80 | // select by data-attribute 81 | this.selectBySelector(selector); 82 | item.removeData('selected'); 83 | item.removeAttr('data-selected'); 84 | } 85 | }, 86 | 87 | enable: function () { 88 | this.$input.removeAttr('disabled'); 89 | this.$button.removeClass('disabled'); 90 | }, 91 | 92 | disable: function () { 93 | this.$input.attr('disabled', true); 94 | this.$button.addClass('disabled'); 95 | }, 96 | 97 | itemclicked: function (e) { 98 | this.$selectedItem = $(e.target).parent(); 99 | 100 | // set input text and trigger input change event marked as synthetic 101 | this.$input.val(this.$selectedItem.text()).trigger('change', { synthetic: true }); 102 | 103 | // pass object including text and any data-attributes 104 | // to onchange event 105 | var data = this.selectedItem(); 106 | 107 | // trigger changed event 108 | this.$element.trigger('changed', data); 109 | 110 | e.preventDefault(); 111 | }, 112 | 113 | inputchanged: function (e, extra) { 114 | 115 | // skip processing for internally-generated synthetic event 116 | // to avoid double processing 117 | if (extra && extra.synthetic) return; 118 | 119 | var val = $(e.target).val(); 120 | this.selectByText(val); 121 | 122 | // find match based on input 123 | // if no match, pass the input value 124 | var data = this.selectedItem(); 125 | if (data.text.length === 0) { 126 | data = { text: val }; 127 | } 128 | 129 | // trigger changed event 130 | this.$element.trigger('changed', data); 131 | 132 | } 133 | 134 | }; 135 | 136 | 137 | // COMBOBOX PLUGIN DEFINITION 138 | 139 | $.fn.combobox = function (option, value) { 140 | var methodReturn; 141 | 142 | var $set = this.each(function () { 143 | var $this = $(this); 144 | var data = $this.data('combobox'); 145 | var options = typeof option === 'object' && option; 146 | 147 | if (!data) $this.data('combobox', (data = new Combobox(this, options))); 148 | if (typeof option === 'string') methodReturn = data[option](value); 149 | }); 150 | 151 | return (methodReturn === undefined) ? $set : methodReturn; 152 | }; 153 | 154 | $.fn.combobox.defaults = {}; 155 | 156 | $.fn.combobox.Constructor = Combobox; 157 | 158 | 159 | // COMBOBOX DATA-API 160 | 161 | $(function () { 162 | 163 | $(window).on('load', function () { 164 | $('.combobox').each(function () { 165 | var $this = $(this); 166 | if ($this.data('combobox')) return; 167 | $this.combobox($this.data()); 168 | }); 169 | }); 170 | 171 | $('body').on('mousedown.combobox.data-api', '.combobox', function (e) { 172 | var $this = $(this); 173 | if ($this.data('combobox')) return; 174 | $this.combobox($this.data()); 175 | }); 176 | }); 177 | 178 | }); 179 | --------------------------------------------------------------------------------