Initial Commit

This commit is contained in:
Dobie Wollert
2012-11-12 00:44:22 -08:00
parent f1c502e4f8
commit 07762668f2
1282 changed files with 29158 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
war/WEB-INF/classes
war/WEB-INF/build
war/WEB-INF/deploy
war/WEB-INF/lib/biomed.jar
war/biomed
war/*.log
*.class
biomed.war
gwt-unitCache/

37
bootstrap/.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.zip
*.vi
*~
*.sass-cache
# OS or Editor folders
.DS_Store
._*
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
# Komodo
*.komodoproject
.komodotools
# Folders to ignore
.hg
.svn
.CVS
.idea
node_modules
dist

View File

@ -0,0 +1,85 @@
/* ==========================================================
* issue-guidelines.js
* http://twitter.github.com/bootstrap/javascript.html#alerts
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
var assert = require('assert')
module.exports = {
'pull-requests': {
'should always be made against -wip branches': function (pull) {
assert.ok(/\-wip$/.test(pull.base.ref))
},
'should always be made from feature branches': function (pull) {
assert.notEqual(pull.head.ref, 'master')
},
'should always include a unit test if changing js files': function (pull) {
var hasJS = false
var hasTests = false
pull.files.forEach(function (file) {
if (/^js\/[^./]+.js/.test(file.filename)) hasJS = true
if (/^js\/tests\/unit\/[^.]+.js/.test(file.filename)) hasTests = true
})
assert.ok(!hasJS || hasJS && hasTests)
},
'after': function (pull) {
if (pull.reporter.stats.failures) {
pull.reportFailures(pull.close.bind(pull))
}
}
},
'issues': {
'before': function (issue) {
var plus = {}
var labels = issue.labels.map(function (label) { return label.name });
if (~labels.indexOf('popular')) return
issue.comments.forEach(function (comment) {
if (/\+1/.test(comment.body)) plus[comment.user.login] = true
})
if (Object.keys(plus).length > 5) {
issue.tag('popular')
issue.comment('Tagging this issue as popular, please stop commenting on this issue with +1. thanks!')
}
},
'should include a jsfiddle/jsbin illustrating the problem if tagged with js but not a feature': function (issue) {
var labels = issue.labels.map(function (label) { return label.name });
if (~labels.indexOf('js') && !~labels.indexOf('feature')) assert.ok(/(jsfiddle|jsbin)/.test(issue.body))
},
'after': function (issue) {
if (issue.reporter.stats.failures) {
issue.reportFailures(issue.close.bind(issue))
}
}
}
}

3
bootstrap/.travis.yml Normal file
View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- 0.6

176
bootstrap/LICENSE Normal file
View File

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

77
bootstrap/Makefile Normal file
View File

@ -0,0 +1,77 @@
BOOTSTRAP = ../css/bootstrap.css
BOOTSTRAP_LESS = ./less/bootstrap.less
BOOTSTRAP_RESPONSIVE = ../css/bootstrap-responsive.css
BOOTSTRAP_RESPONSIVE_LESS = ./less/responsive.less
DATE=$(shell date +%I:%M%p)
CHECK=\033[32m✔\033[39m
HR=\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
#
# BUILD DOCS
#
build:
recess --compress less/bootstrap.less > ../src/com/biomed/resources/css/bootstrap.min.css
recess --compress less/bootstrap-responsive.less > ../src/com/biomed/resources/css/bootstrap-responsive.min.css
mkdir -p tmp
cat js/bootstrap-transition.js js/bootstrap-alert.js js/bootstrap-button.js js/bootstrap-carousel.js js/bootstrap-collapse.js js/bootstrap-dropdown.js js/bootstrap-modal.js js/bootstrap-tooltip.js js/bootstrap-popover.js js/bootstrap-scrollspy.js js/bootstrap-tab.js js/bootstrap-typeahead.js js/bootstrap-affix.js > tmp/bootstrap.js
uglifyjs -nc tmp/bootstrap.js > tmp/bootstrap.min.js
echo "/*!\n* Bootstrap.js by @fat & @mdo\n* Copyright 2012 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/" > tmp/copyright.js
cat tmp/copyright.js tmp/bootstrap.min.js > ../src/com/biomed/resources/js/bootstrap.min.js
#
# CLEANS THE ROOT DIRECTORY OF PRIOR BUILDS
#
clean:
rm -r bootstrap
#
# BUILD SIMPLE BOOTSTRAP DIRECTORY
# recess & uglifyjs are required
#
bootstrap:
mkdir -p bootstrap/img
mkdir -p bootstrap/css
mkdir -p bootstrap/js
cp img/* bootstrap/img/
recess --compile ${BOOTSTRAP_LESS} > bootstrap/css/bootstrap.css
recess --compress ${BOOTSTRAP_LESS} > bootstrap/css/bootstrap.min.css
recess --compile ${BOOTSTRAP_RESPONSIVE_LESS} > bootstrap/css/bootstrap-responsive.css
recess --compress ${BOOTSTRAP_RESPONSIVE_LESS} > bootstrap/css/bootstrap-responsive.min.css
uglifyjs -nc bootstrap/js/bootstrap.js > bootstrap/js/bootstrap.min.tmp.js
rm bootstrap/js/copyright.js bootstrap/js/bootstrap.min.tmp.js
#
# MAKE FOR GH-PAGES 4 FAT & MDO ONLY (O_O )
#
gh-pages: bootstrap docs
rm -f docs/assets/bootstrap.zip
zip -r docs/assets/bootstrap.zip bootstrap
rm -r bootstrap
rm -f ../bootstrap-gh-pages/assets/bootstrap.zip
node docs/build production
cp -r docs/* ../bootstrap-gh-pages
#
# WATCH LESS FILES
#
watch:
echo "Watching less files..."; \
watchr -e "watch('less/.*\.less') { system 'make' }"
#
# HAUNT GITHUB ISSUES 4 FAT & MDO ONLY (O_O )
#
haunt:
@haunt .issue-guidelines.js https://github.com/twitter/bootstrap
.PHONY: docs watch gh-pages

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

12
bootstrap/js/.jshintrc Normal file
View File

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

104
bootstrap/js/bootstrap-affix.js vendored Normal file
View File

@ -0,0 +1,104 @@
/* ==========================================================
* bootstrap-affix.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#affix
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* AFFIX CLASS DEFINITION
* ====================== */
var Affix = function (element, options) {
this.options = $.extend({}, $.fn.affix.defaults, options)
this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
this.$element = $(element)
this.checkPosition()
}
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
, scrollTop = this.$window.scrollTop()
, position = this.$element.offset()
, offset = this.options.offset
, offsetBottom = offset.bottom
, offsetTop = offset.top
, reset = 'affix affix-top affix-bottom'
, affix
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top()
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
'bottom' : offsetTop != null && scrollTop <= offsetTop ?
'top' : false
if (this.affixed === affix) return
this.affixed = affix
this.unpin = affix == 'bottom' ? position.top - scrollTop : null
this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
}
/* AFFIX PLUGIN DEFINITION
* ======================= */
$.fn.affix = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('affix')
, options = typeof option == 'object' && option
if (!data) $this.data('affix', (data = new Affix(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.affix.Constructor = Affix
$.fn.affix.defaults = {
offset: 0
}
/* AFFIX DATA-API
* ============== */
$(window).on('load', function () {
$('[data-spy="affix"]').each(function () {
var $spy = $(this)
, data = $spy.data()
data.offset = data.offset || {}
data.offsetBottom && (data.offset.bottom = data.offsetBottom)
data.offsetTop && (data.offset.top = data.offsetTop)
$spy.affix(data)
})
})
}(window.jQuery);

90
bootstrap/js/bootstrap-alert.js vendored Normal file
View File

@ -0,0 +1,90 @@
/* ==========================================================
* bootstrap-alert.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#alerts
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* ALERT CLASS DEFINITION
* ====================== */
var dismiss = '[data-dismiss="alert"]'
, Alert = function (el) {
$(el).on('click', dismiss, this.close)
}
Alert.prototype.close = function (e) {
var $this = $(this)
, selector = $this.attr('data-target')
, $parent
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
$parent = $(selector)
e && e.preventDefault()
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
$parent.trigger(e = $.Event('close'))
if (e.isDefaultPrevented()) return
$parent.removeClass('in')
function removeElement() {
$parent
.trigger('closed')
.remove()
}
$.support.transition && $parent.hasClass('fade') ?
$parent.on($.support.transition.end, removeElement) :
removeElement()
}
/* ALERT PLUGIN DEFINITION
* ======================= */
$.fn.alert = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('alert')
if (!data) $this.data('alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.alert.Constructor = Alert
/* ALERT DATA-API
* ============== */
$(function () {
$('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
})
}(window.jQuery);

96
bootstrap/js/bootstrap-button.js vendored Normal file
View File

@ -0,0 +1,96 @@
/* ============================================================
* bootstrap-button.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#buttons
* ============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function ($) {
"use strict"; // jshint ;_;
/* BUTTON PUBLIC CLASS DEFINITION
* ============================== */
var Button = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, $.fn.button.defaults, options)
}
Button.prototype.setState = function (state) {
var d = 'disabled'
, $el = this.$element
, data = $el.data()
, val = $el.is('input') ? 'val' : 'html'
state = state + 'Text'
data.resetText || $el.data('resetText', $el[val]())
$el[val](data[state] || this.options[state])
// push to event loop to allow forms to submit
setTimeout(function () {
state == 'loadingText' ?
$el.addClass(d).attr(d, d) :
$el.removeClass(d).removeAttr(d)
}, 0)
}
Button.prototype.toggle = function () {
var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
$parent && $parent
.find('.active')
.removeClass('active')
this.$element.toggleClass('active')
}
/* BUTTON PLUGIN DEFINITION
* ======================== */
$.fn.button = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('button')
, options = typeof option == 'object' && option
if (!data) $this.data('button', (data = new Button(this, options)))
if (option == 'toggle') data.toggle()
else if (option) data.setState(option)
})
}
$.fn.button.defaults = {
loadingText: 'loading...'
}
$.fn.button.Constructor = Button
/* BUTTON DATA-API
* =============== */
$(function () {
$('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
$btn.button('toggle')
})
})
}(window.jQuery);

176
bootstrap/js/bootstrap-carousel.js vendored Normal file
View File

@ -0,0 +1,176 @@
/* ==========================================================
* bootstrap-carousel.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#carousel
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* CAROUSEL CLASS DEFINITION
* ========================= */
var Carousel = function (element, options) {
this.$element = $(element)
this.options = options
this.options.slide && this.slide(this.options.slide)
this.options.pause == 'hover' && this.$element
.on('mouseenter', $.proxy(this.pause, this))
.on('mouseleave', $.proxy(this.cycle, this))
}
Carousel.prototype = {
cycle: function (e) {
if (!e) this.paused = false
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
}
, to: function (pos) {
var $active = this.$element.find('.item.active')
, children = $active.parent().children()
, activePos = children.index($active)
, that = this
if (pos > (children.length - 1) || pos < 0) return
if (this.sliding) {
return this.$element.one('slid', function () {
that.to(pos)
})
}
if (activePos == pos) {
return this.pause().cycle()
}
return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
}
, pause: function (e) {
if (!e) this.paused = true
if (this.$element.find('.next, .prev').length && $.support.transition.end) {
this.$element.trigger($.support.transition.end)
this.cycle()
}
clearInterval(this.interval)
this.interval = null
return this
}
, next: function () {
if (this.sliding) return
return this.slide('next')
}
, prev: function () {
if (this.sliding) return
return this.slide('prev')
}
, slide: function (type, next) {
var $active = this.$element.find('.item.active')
, $next = next || $active[type]()
, isCycling = this.interval
, direction = type == 'next' ? 'left' : 'right'
, fallback = type == 'next' ? 'first' : 'last'
, that = this
, e = $.Event('slide', {
relatedTarget: $next[0]
})
this.sliding = true
isCycling && this.pause()
$next = $next.length ? $next : this.$element.find('.item')[fallback]()
if ($next.hasClass('active')) return
if ($.support.transition && this.$element.hasClass('slide')) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
this.$element.one($.support.transition.end, function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () { that.$element.trigger('slid') }, 0)
})
} else {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger('slid')
}
isCycling && this.cycle()
return this
}
}
/* CAROUSEL PLUGIN DEFINITION
* ========================== */
$.fn.carousel = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('carousel')
, options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
, action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.cycle()
})
}
$.fn.carousel.defaults = {
interval: 5000
, pause: 'hover'
}
$.fn.carousel.Constructor = Carousel
/* CAROUSEL DATA-API
* ================= */
$(function () {
$('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
var $this = $(this), href
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
, options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
$target.carousel(options)
e.preventDefault()
})
})
}(window.jQuery);

158
bootstrap/js/bootstrap-collapse.js vendored Normal file
View File

@ -0,0 +1,158 @@
/* =============================================================
* bootstrap-collapse.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#collapse
* =============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function ($) {
"use strict"; // jshint ;_;
/* COLLAPSE PUBLIC CLASS DEFINITION
* ================================ */
var Collapse = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, $.fn.collapse.defaults, options)
if (this.options.parent) {
this.$parent = $(this.options.parent)
}
this.options.toggle && this.toggle()
}
Collapse.prototype = {
constructor: Collapse
, dimension: function () {
var hasWidth = this.$element.hasClass('width')
return hasWidth ? 'width' : 'height'
}
, show: function () {
var dimension
, scroll
, actives
, hasData
if (this.transitioning) return
dimension = this.dimension()
scroll = $.camelCase(['scroll', dimension].join('-'))
actives = this.$parent && this.$parent.find('> .accordion-group > .in')
if (actives && actives.length) {
hasData = actives.data('collapse')
if (hasData && hasData.transitioning) return
actives.collapse('hide')
hasData || actives.data('collapse', null)
}
this.$element[dimension](0)
this.transition('addClass', $.Event('show'), 'shown')
$.support.transition && this.$element[dimension](this.$element[0][scroll])
}
, hide: function () {
var dimension
if (this.transitioning) return
dimension = this.dimension()
this.reset(this.$element[dimension]())
this.transition('removeClass', $.Event('hide'), 'hidden')
this.$element[dimension](0)
}
, reset: function (size) {
var dimension = this.dimension()
this.$element
.removeClass('collapse')
[dimension](size || 'auto')
[0].offsetWidth
this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
return this
}
, transition: function (method, startEvent, completeEvent) {
var that = this
, complete = function () {
if (startEvent.type == 'show') that.reset()
that.transitioning = 0
that.$element.trigger(completeEvent)
}
this.$element.trigger(startEvent)
if (startEvent.isDefaultPrevented()) return
this.transitioning = 1
this.$element[method]('in')
$.support.transition && this.$element.hasClass('collapse') ?
this.$element.one($.support.transition.end, complete) :
complete()
}
, toggle: function () {
this[this.$element.hasClass('in') ? 'hide' : 'show']()
}
}
/* COLLAPSIBLE PLUGIN DEFINITION
* ============================== */
$.fn.collapse = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('collapse')
, options = typeof option == 'object' && option
if (!data) $this.data('collapse', (data = new Collapse(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.collapse.defaults = {
toggle: true
}
$.fn.collapse.Constructor = Collapse
/* COLLAPSIBLE DATA-API
* ==================== */
$(function () {
$('body').on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
var $this = $(this), href
, target = $this.attr('data-target')
|| e.preventDefault()
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
, option = $(target).data('collapse') ? 'toggle' : $this.data()
$this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
$(target).collapse(option)
})
})
}(window.jQuery);

150
bootstrap/js/bootstrap-dropdown.js vendored Normal file
View File

@ -0,0 +1,150 @@
/* ============================================================
* bootstrap-dropdown.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#dropdowns
* ============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function ($) {
"use strict"; // jshint ;_;
/* DROPDOWN CLASS DEFINITION
* ========================= */
var toggle = '[data-toggle=dropdown]'
, Dropdown = function (element) {
var $el = $(element).on('click.dropdown.data-api', this.toggle)
$('html').on('click.dropdown.data-api', function () {
$el.parent().removeClass('open')
})
}
Dropdown.prototype = {
constructor: Dropdown
, toggle: function (e) {
var $this = $(this)
, $parent
, isActive
if ($this.is('.disabled, :disabled')) return
$parent = getParent($this)
isActive = $parent.hasClass('open')
clearMenus()
if (!isActive) {
$parent.toggleClass('open')
$this.focus()
}
return false
}
, keydown: function (e) {
var $this
, $items
, $active
, $parent
, isActive
, index
if (!/(38|40|27)/.test(e.keyCode)) return
$this = $(this)
e.preventDefault()
e.stopPropagation()
if ($this.is('.disabled, :disabled')) return
$parent = getParent($this)
isActive = $parent.hasClass('open')
if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
$items = $('[role=menu] li:not(.divider) a', $parent)
if (!$items.length) return
index = $items.index($items.filter(':focus'))
if (e.keyCode == 38 && index > 0) index-- // up
if (e.keyCode == 40 && index < $items.length - 1) index++ // down
if (!~index) index = 0
$items
.eq(index)
.focus()
}
}
function clearMenus() {
getParent($(toggle))
.removeClass('open')
}
function getParent($this) {
var selector = $this.attr('data-target')
, $parent
if (!selector) {
selector = $this.attr('href')
selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
$parent = $(selector)
$parent.length || ($parent = $this.parent())
return $parent
}
/* DROPDOWN PLUGIN DEFINITION
* ========================== */
$.fn.dropdown = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('dropdown')
if (!data) $this.data('dropdown', (data = new Dropdown(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.dropdown.Constructor = Dropdown
/* APPLY TO STANDARD DROPDOWN ELEMENTS
* =================================== */
$(function () {
$('html')
.on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
$('body')
.on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
.on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
})
}(window.jQuery);

239
bootstrap/js/bootstrap-modal.js vendored Normal file
View File

@ -0,0 +1,239 @@
/* =========================================================
* bootstrap-modal.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#modals
* =========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================= */
!function ($) {
"use strict"; // jshint ;_;
/* MODAL CLASS DEFINITION
* ====================== */
var Modal = function (element, options) {
this.options = options
this.$element = $(element)
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
}
Modal.prototype = {
constructor: Modal
, toggle: function () {
return this[!this.isShown ? 'show' : 'hide']()
}
, show: function () {
var that = this
, e = $.Event('show')
this.$element.trigger(e)
if (this.isShown || e.isDefaultPrevented()) return
$('body').addClass('modal-open')
this.isShown = true
this.escape()
this.backdrop(function () {
var transition = $.support.transition && that.$element.hasClass('fade')
if (!that.$element.parent().length) {
that.$element.appendTo(document.body) //don't move modals dom position
}
that.$element
.show()
if (transition) {
that.$element[0].offsetWidth // force reflow
}
that.$element
.addClass('in')
.attr('aria-hidden', false)
.focus()
that.enforceFocus()
transition ?
that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
that.$element.trigger('shown')
})
}
, hide: function (e) {
e && e.preventDefault()
var that = this
e = $.Event('hide')
this.$element.trigger(e)
if (!this.isShown || e.isDefaultPrevented()) return
this.isShown = false
$('body').removeClass('modal-open')
this.escape()
$(document).off('focusin.modal')
this.$element
.removeClass('in')
.attr('aria-hidden', true)
$.support.transition && this.$element.hasClass('fade') ?
this.hideWithTransition() :
this.hideModal()
}
, enforceFocus: function () {
var that = this
$(document).on('focusin.modal', function (e) {
if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
that.$element.focus()
}
})
}
, escape: function () {
var that = this
if (this.isShown && this.options.keyboard) {
this.$element.on('keyup.dismiss.modal', function ( e ) {
e.which == 27 && that.hide()
})
} else if (!this.isShown) {
this.$element.off('keyup.dismiss.modal')
}
}
, hideWithTransition: function () {
var that = this
, timeout = setTimeout(function () {
that.$element.off($.support.transition.end)
that.hideModal()
}, 500)
this.$element.one($.support.transition.end, function () {
clearTimeout(timeout)
that.hideModal()
})
}
, hideModal: function (that) {
this.$element
.hide()
.trigger('hidden')
this.backdrop()
}
, removeBackdrop: function () {
this.$backdrop.remove()
this.$backdrop = null
}
, backdrop: function (callback) {
var that = this
, animate = this.$element.hasClass('fade') ? 'fade' : ''
if (this.isShown && this.options.backdrop) {
var doAnimate = $.support.transition && animate
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
.appendTo(document.body)
if (this.options.backdrop != 'static') {
this.$backdrop.click($.proxy(this.hide, this))
}
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
this.$backdrop.addClass('in')
doAnimate ?
this.$backdrop.one($.support.transition.end, callback) :
callback()
} else if (!this.isShown && this.$backdrop) {
this.$backdrop.removeClass('in')
$.support.transition && this.$element.hasClass('fade')?
this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
this.removeBackdrop()
} else if (callback) {
callback()
}
}
}
/* MODAL PLUGIN DEFINITION
* ======================= */
$.fn.modal = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('modal')
, options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('modal', (data = new Modal(this, options)))
if (typeof option == 'string') data[option]()
else if (options.show) data.show()
})
}
$.fn.modal.defaults = {
backdrop: true
, keyboard: true
, show: true
}
$.fn.modal.Constructor = Modal
/* MODAL DATA-API
* ============== */
$(function () {
$('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
var $this = $(this)
, href = $this.attr('href')
, $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
, option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
e.preventDefault()
$target
.modal(option)
.one('hide', function () {
$this.focus()
})
})
})
}(window.jQuery);

103
bootstrap/js/bootstrap-popover.js vendored Normal file
View File

@ -0,0 +1,103 @@
/* ===========================================================
* bootstrap-popover.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#popovers
* ===========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* POPOVER PUBLIC CLASS DEFINITION
* =============================== */
var Popover = function (element, options) {
this.init('popover', element, options)
}
/* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
========================================== */
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
constructor: Popover
, setContent: function () {
var $tip = this.tip()
, title = this.getTitle()
, content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
$tip.removeClass('fade top bottom left right in')
}
, hasContent: function () {
return this.getTitle() || this.getContent()
}
, getContent: function () {
var content
, $e = this.$element
, o = this.options
content = $e.attr('data-content')
|| (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
return content
}
, tip: function () {
if (!this.$tip) {
this.$tip = $(this.options.template)
}
return this.$tip
}
, destroy: function () {
this.hide().$element.off('.' + this.type).removeData(this.type)
}
})
/* POPOVER PLUGIN DEFINITION
* ======================= */
$.fn.popover = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('popover')
, options = typeof option == 'object' && option
if (!data) $this.data('popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.popover.Constructor = Popover
$.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
placement: 'right'
, trigger: 'click'
, content: ''
, template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
})
}(window.jQuery);

151
bootstrap/js/bootstrap-scrollspy.js vendored Normal file
View File

@ -0,0 +1,151 @@
/* =============================================================
* bootstrap-scrollspy.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#scrollspy
* =============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* SCROLLSPY CLASS DEFINITION
* ========================== */
function ScrollSpy(element, options) {
var process = $.proxy(this.process, this)
, $element = $(element).is('body') ? $(window) : $(element)
, href
this.options = $.extend({}, $.fn.scrollspy.defaults, options)
this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
this.selector = (this.options.target
|| ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
|| '') + ' .nav li > a'
this.$body = $('body')
this.refresh()
this.process()
}
ScrollSpy.prototype = {
constructor: ScrollSpy
, refresh: function () {
var self = this
, $targets
this.offsets = $([])
this.targets = $([])
$targets = this.$body
.find(this.selector)
.map(function () {
var $el = $(this)
, href = $el.data('target') || $el.attr('href')
, $href = /^#\w/.test(href) && $(href)
return ( $href
&& $href.length
&& [[ $href.position().top, href ]] ) || null
})
.sort(function (a, b) { return a[0] - b[0] })
.each(function () {
self.offsets.push(this[0])
self.targets.push(this[1])
})
}
, process: function () {
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
, scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
, maxScroll = scrollHeight - this.$scrollElement.height()
, offsets = this.offsets
, targets = this.targets
, activeTarget = this.activeTarget
, i
if (scrollTop >= maxScroll) {
return activeTarget != (i = targets.last()[0])
&& this.activate ( i )
}
for (i = offsets.length; i--;) {
activeTarget != targets[i]
&& scrollTop >= offsets[i]
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
&& this.activate( targets[i] )
}
}
, activate: function (target) {
var active
, selector
this.activeTarget = target
$(this.selector)
.parent('.active')
.removeClass('active')
selector = this.selector
+ '[data-target="' + target + '"],'
+ this.selector + '[href="' + target + '"]'
active = $(selector)
.parent('li')
.addClass('active')
if (active.parent('.dropdown-menu').length) {
active = active.closest('li.dropdown').addClass('active')
}
active.trigger('activate')
}
}
/* SCROLLSPY PLUGIN DEFINITION
* =========================== */
$.fn.scrollspy = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('scrollspy')
, options = typeof option == 'object' && option
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
$.fn.scrollspy.defaults = {
offset: 10
}
/* SCROLLSPY DATA-API
* ================== */
$(window).on('load', function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);

135
bootstrap/js/bootstrap-tab.js vendored Normal file
View File

@ -0,0 +1,135 @@
/* ========================================================
* bootstrap-tab.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#tabs
* ========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ======================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* TAB CLASS DEFINITION
* ==================== */
var Tab = function (element) {
this.element = $(element)
}
Tab.prototype = {
constructor: Tab
, show: function () {
var $this = this.element
, $ul = $this.closest('ul:not(.dropdown-menu)')
, selector = $this.attr('data-target')
, previous
, $target
, e
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
if ( $this.parent('li').hasClass('active') ) return
previous = $ul.find('.active a').last()[0]
e = $.Event('show', {
relatedTarget: previous
})
$this.trigger(e)
if (e.isDefaultPrevented()) return
$target = $(selector)
this.activate($this.parent('li'), $ul)
this.activate($target, $target.parent(), function () {
$this.trigger({
type: 'shown'
, relatedTarget: previous
})
})
}
, activate: function ( element, container, callback) {
var $active = container.find('> .active')
, transition = callback
&& $.support.transition
&& $active.hasClass('fade')
function next() {
$active
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
element.addClass('active')
if (transition) {
element[0].offsetWidth // reflow for transition
element.addClass('in')
} else {
element.removeClass('fade')
}
if ( element.parent('.dropdown-menu') ) {
element.closest('li.dropdown').addClass('active')
}
callback && callback()
}
transition ?
$active.one($.support.transition.end, next) :
next()
$active.removeClass('in')
}
}
/* TAB PLUGIN DEFINITION
* ===================== */
$.fn.tab = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('tab')
if (!data) $this.data('tab', (data = new Tab(this)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tab.Constructor = Tab
/* TAB DATA-API
* ============ */
$(function () {
$('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
e.preventDefault()
$(this).tab('show')
})
})
}(window.jQuery);

275
bootstrap/js/bootstrap-tooltip.js vendored Normal file
View File

@ -0,0 +1,275 @@
/* ===========================================================
* bootstrap-tooltip.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#tooltips
* Inspired by the original jQuery.tipsy by Jason Frame
* ===========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* TOOLTIP PUBLIC CLASS DEFINITION
* =============================== */
var Tooltip = function (element, options) {
this.init('tooltip', element, options)
}
Tooltip.prototype = {
constructor: Tooltip
, init: function (type, element, options) {
var eventIn
, eventOut
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.enabled = true
if (this.options.trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (this.options.trigger != 'manual') {
eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
, getOptions: function (options) {
options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
, enter: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
if (!self.options.delay || !self.options.delay.show) return self.show()
clearTimeout(this.timeout)
self.hoverState = 'in'
this.timeout = setTimeout(function() {
if (self.hoverState == 'in') self.show()
}, self.options.delay.show)
}
, leave: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
if (this.timeout) clearTimeout(this.timeout)
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.hoverState = 'out'
this.timeout = setTimeout(function() {
if (self.hoverState == 'out') self.hide()
}, self.options.delay.hide)
}
, show: function () {
var $tip
, inside
, pos
, actualWidth
, actualHeight
, placement
, tp
if (this.hasContent() && this.enabled) {
$tip = this.tip()
this.setContent()
if (this.options.animation) {
$tip.addClass('fade')
}
placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
inside = /in/.test(placement)
$tip
.remove()
.css({ top: 0, left: 0, display: 'block' })
.appendTo(inside ? this.$element : document.body)
pos = this.getPosition(inside)
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
switch (inside ? placement.split(' ')[1] : placement) {
case 'bottom':
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
break
case 'top':
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
break
case 'left':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
break
case 'right':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
break
}
$tip
.css(tp)
.addClass(placement)
.addClass('in')
}
}
, setContent: function () {
var $tip = this.tip()
, title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
}
, hide: function () {
var that = this
, $tip = this.tip()
$tip.removeClass('in')
function removeWithAnimation() {
var timeout = setTimeout(function () {
$tip.off($.support.transition.end).remove()
}, 500)
$tip.one($.support.transition.end, function () {
clearTimeout(timeout)
$tip.remove()
})
}
$.support.transition && this.$tip.hasClass('fade') ?
removeWithAnimation() :
$tip.remove()
return this
}
, fixTitle: function () {
var $e = this.$element
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
}
}
, hasContent: function () {
return this.getTitle()
}
, getPosition: function (inside) {
return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
width: this.$element[0].offsetWidth
, height: this.$element[0].offsetHeight
})
}
, getTitle: function () {
var title
, $e = this.$element
, o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
, tip: function () {
return this.$tip = this.$tip || $(this.options.template)
}
, validate: function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
, enable: function () {
this.enabled = true
}
, disable: function () {
this.enabled = false
}
, toggleEnabled: function () {
this.enabled = !this.enabled
}
, toggle: function () {
this[this.tip().hasClass('in') ? 'hide' : 'show']()
}
, destroy: function () {
this.hide().$element.off('.' + this.type).removeData(this.type)
}
}
/* TOOLTIP PLUGIN DEFINITION
* ========================= */
$.fn.tooltip = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('tooltip')
, options = typeof option == 'object' && option
if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tooltip.Constructor = Tooltip
$.fn.tooltip.defaults = {
animation: true
, placement: 'top'
, selector: false
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
, trigger: 'hover'
, title: ''
, delay: 0
, html: true
}
}(window.jQuery);

60
bootstrap/js/bootstrap-transition.js vendored Normal file
View File

@ -0,0 +1,60 @@
/* ===================================================
* bootstrap-transition.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#transitions
* ===================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
$(function () {
"use strict"; // jshint ;_;
/* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
* ======================================================= */
$.support.transition = (function () {
var transitionEnd = (function () {
var el = document.createElement('bootstrap')
, transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd'
, 'MozTransition' : 'transitionend'
, 'OTransition' : 'oTransitionEnd otransitionend'
, 'transition' : 'transitionend'
}
, name
for (name in transEndEventNames){
if (el.style[name] !== undefined) {
return transEndEventNames[name]
}
}
}())
return transitionEnd && {
end: transitionEnd
}
})()
})
}(window.jQuery);

300
bootstrap/js/bootstrap-typeahead.js vendored Normal file
View File

@ -0,0 +1,300 @@
/* =============================================================
* bootstrap-typeahead.js v2.1.1
* http://twitter.github.com/bootstrap/javascript.html#typeahead
* =============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function($){
"use strict"; // jshint ;_;
/* TYPEAHEAD PUBLIC CLASS DEFINITION
* ================================= */
var Typeahead = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, $.fn.typeahead.defaults, options)
this.matcher = this.options.matcher || this.matcher
this.sorter = this.options.sorter || this.sorter
this.highlighter = this.options.highlighter || this.highlighter
this.updater = this.options.updater || this.updater
this.$menu = $(this.options.menu).appendTo('body')
this.source = this.options.source
this.shown = false
this.listen()
}
Typeahead.prototype = {
constructor: Typeahead
, select: function () {
var val = this.$menu.find('.active').attr('data-value')
this.$element
.val(this.updater(val))
.change()
return this.hide()
}
, updater: function (item) {
return item
}
, show: function () {
var pos = $.extend({}, this.$element.offset(), {
height: this.$element[0].offsetHeight
})
this.$menu.css({
top: pos.top + pos.height
, left: pos.left
})
this.$menu.show()
this.shown = true
return this
}
, hide: function () {
this.$menu.hide()
this.shown = false
return this
}
, lookup: function (event) {
var items
this.query = this.$element.val()
if (!this.query || this.query.length < this.options.minLength) {
return this.shown ? this.hide() : this
}
items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
return items ? this.process(items) : this
}
, process: function (items) {
var that = this
items = $.grep(items, function (item) {
return that.matcher(item)
})
items = this.sorter(items)
if (!items.length) {
return this.shown ? this.hide() : this
}
return this.render(items.slice(0, this.options.items)).show()
}
, matcher: function (item) {
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
}
, sorter: function (items) {
var beginswith = []
, caseSensitive = []
, caseInsensitive = []
, item
while (item = items.shift()) {
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
else if (~item.indexOf(this.query)) caseSensitive.push(item)
else caseInsensitive.push(item)
}
return beginswith.concat(caseSensitive, caseInsensitive)
}
, highlighter: function (item) {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>'
})
}
, render: function (items) {
var that = this
items = $(items).map(function (i, item) {
i = $(that.options.item).attr('data-value', item)
i.find('a').html(that.highlighter(item))
return i[0]
})
items.first().addClass('active')
this.$menu.html(items)
return this
}
, next: function (event) {
var active = this.$menu.find('.active').removeClass('active')
, next = active.next()
if (!next.length) {
next = $(this.$menu.find('li')[0])
}
next.addClass('active')
}
, prev: function (event) {
var active = this.$menu.find('.active').removeClass('active')
, prev = active.prev()
if (!prev.length) {
prev = this.$menu.find('li').last()
}
prev.addClass('active')
}
, listen: function () {
this.$element
.on('blur', $.proxy(this.blur, this))
.on('keypress', $.proxy(this.keypress, this))
.on('keyup', $.proxy(this.keyup, this))
if ($.browser.chrome || $.browser.webkit || $.browser.msie) {
this.$element.on('keydown', $.proxy(this.keydown, this))
}
this.$menu
.on('click', $.proxy(this.click, this))
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
}
, move: function (e) {
if (!this.shown) return
switch(e.keyCode) {
case 9: // tab
case 13: // enter
case 27: // escape
e.preventDefault()
break
case 38: // up arrow
e.preventDefault()
this.prev()
break
case 40: // down arrow
e.preventDefault()
this.next()
break
}
e.stopPropagation()
}
, keydown: function (e) {
this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27])
this.move(e)
}
, keypress: function (e) {
if (this.suppressKeyPressRepeat) return
this.move(e)
}
, keyup: function (e) {
switch(e.keyCode) {
case 40: // down arrow
case 38: // up arrow
break
case 9: // tab
case 13: // enter
if (!this.shown) return
this.select()
break
case 27: // escape
if (!this.shown) return
this.hide()
break
default:
this.lookup()
}
e.stopPropagation()
e.preventDefault()
}
, blur: function (e) {
var that = this
setTimeout(function () { that.hide() }, 150)
}
, click: function (e) {
e.stopPropagation()
e.preventDefault()
this.select()
}
, mouseenter: function (e) {
this.$menu.find('.active').removeClass('active')
$(e.currentTarget).addClass('active')
}
}
/* TYPEAHEAD PLUGIN DEFINITION
* =========================== */
$.fn.typeahead = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('typeahead')
, options = typeof option == 'object' && option
if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.typeahead.defaults = {
source: []
, items: 8
, menu: '<ul class="typeahead dropdown-menu"></ul>'
, item: '<li><a href="#"></a></li>'
, minLength: 1
}
$.fn.typeahead.Constructor = Typeahead
/* TYPEAHEAD DATA-API
* ================== */
$(function () {
$('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
var $this = $(this)
if ($this.data('typeahead')) return
e.preventDefault()
$this.typeahead($this.data())
})
})
}(window.jQuery);

View File

@ -0,0 +1,34 @@
//
// Accordion
// --------------------------------------------------
// Parent container
.accordion {
margin-bottom: @baseLineHeight;
}
// Group == heading + body
.accordion-group {
margin-bottom: 2px;
border: 1px solid #e5e5e5;
.border-radius(4px);
}
.accordion-heading {
border-bottom: 0;
}
.accordion-heading .accordion-toggle {
display: block;
padding: 8px 15px;
}
// General toggle styles
.accordion-toggle {
cursor: pointer;
}
// Inner needs the styles because you can't animate properly with any styles on the element
.accordion-inner {
padding: 9px 15px;
border-top: 1px solid #e5e5e5;
}

View File

@ -0,0 +1,65 @@
//
// Alerts
// --------------------------------------------------
// Base styles
// -------------------------
.alert {
padding: 8px 35px 8px 14px;
margin-bottom: @baseLineHeight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
background-color: @warningBackground;
border: 1px solid @warningBorder;
.border-radius(4px);
color: @warningText;
}
.alert h4 {
margin: 0;
}
// Adjust close link position
.alert .close {
position: relative;
top: -2px;
right: -21px;
line-height: @baseLineHeight;
}
// Alternate styles
// -------------------------
.alert-success {
background-color: @successBackground;
border-color: @successBorder;
color: @successText;
}
.alert-danger,
.alert-error {
background-color: @errorBackground;
border-color: @errorBorder;
color: @errorText;
}
.alert-info {
background-color: @infoBackground;
border-color: @infoBorder;
color: @infoText;
}
// Block alerts
// -------------------------
.alert-block {
padding-top: 14px;
padding-bottom: 14px;
}
.alert-block > p,
.alert-block > ul {
margin-bottom: 0;
}
.alert-block p + p {
margin-top: 5px;
}

65
bootstrap/less/bootstrap.less vendored Normal file
View File

@ -0,0 +1,65 @@
/*!
* Bootstrap v2.1.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
// CSS Reset
@import "reset.less";
// Core variables and mixins
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
@import "mixins.less";
// Grid system and page structure
@import "scaffolding.less";
@import "grid.less";
@import "layouts.less";
// Base CSS
@import "type.less";
@import "code.less";
@import "forms.less";
@import "tables.less";
// Components: common
@import "sprites.less";
@import "dropdowns.less";
@import "wells.less";
@import "component-animations.less";
@import "close.less";
// Components: Buttons & Alerts
@import "buttons.less";
@import "button-groups.less";
@import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
// Components: Nav
@import "navs.less";
@import "navbar.less";
@import "breadcrumbs.less";
@import "pagination.less";
@import "pager.less";
// Components: Popovers
@import "modals.less";
@import "tooltip.less";
@import "popovers.less";
// Components: Misc
@import "thumbnails.less";
@import "labels-badges.less";
@import "progress-bars.less";
@import "accordion.less";
@import "carousel.less";
@import "hero-unit.less";
// Custom
@import "custom.less";
// Utility classes
@import "utilities.less"; // Has to be last to override when necessary

View File

@ -0,0 +1,24 @@
//
// Breadcrumbs
// --------------------------------------------------
.breadcrumb {
padding: 8px 15px;
margin: 0 0 @baseLineHeight;
list-style: none;
background-color: #f5f5f5;
.border-radius(4px);
li {
display: inline-block;
.ie7-inline-block();
text-shadow: 0 1px 0 @white;
}
.divider {
padding: 0 5px;
color: #ccc;
}
.active {
color: @grayLight;
}
}

View File

@ -0,0 +1,245 @@
//
// Button groups
// --------------------------------------------------
// Make the div behave like a button
.btn-group {
position: relative;
font-size: 0; // remove as part 1 of font-size inline-block hack
vertical-align: middle; // match .btn alignment given font-size hack above
white-space: nowrap; // prevent buttons from wrapping when in tight spaces (e.g., the table on the tests page)
.ie7-restore-left-whitespace();
}
// Space out series of button groups
.btn-group + .btn-group {
margin-left: 5px;
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
font-size: 0; // Hack to remove whitespace that results from using inline-block
margin-top: @baseLineHeight / 2;
margin-bottom: @baseLineHeight / 2;
.btn-group {
display: inline-block;
.ie7-inline-block();
}
.btn + .btn,
.btn-group + .btn,
.btn + .btn-group {
margin-left: 5px;
}
}
// Float them, remove border radius, then re-add to first and last elements
.btn-group > .btn {
position: relative;
.border-radius(0);
}
.btn-group > .btn + .btn {
margin-left: -1px;
}
.btn-group > .btn,
.btn-group > .dropdown-menu {
font-size: @baseFontSize; // redeclare as part 2 of font-size inline-block hack
}
// Reset fonts for other sizes
.btn-group > .btn-mini {
font-size: 11px;
}
.btn-group > .btn-small {
font-size: 12px;
}
.btn-group > .btn-large {
font-size: 16px;
}
// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
.btn-group > .btn:first-child {
margin-left: 0;
-webkit-border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
border-bottom-left-radius: 4px;
}
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
.btn-group > .btn:last-child,
.btn-group > .dropdown-toggle {
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topright: 4px;
border-top-right-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-moz-border-radius-bottomright: 4px;
border-bottom-right-radius: 4px;
}
// Reset corners for large buttons
.btn-group > .btn.large:first-child {
margin-left: 0;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topleft: 6px;
border-top-left-radius: 6px;
-webkit-border-bottom-left-radius: 6px;
-moz-border-radius-bottomleft: 6px;
border-bottom-left-radius: 6px;
}
.btn-group > .btn.large:last-child,
.btn-group > .large.dropdown-toggle {
-webkit-border-top-right-radius: 6px;
-moz-border-radius-topright: 6px;
border-top-right-radius: 6px;
-webkit-border-bottom-right-radius: 6px;
-moz-border-radius-bottomright: 6px;
border-bottom-right-radius: 6px;
}
// On hover/focus/active, bring the proper btn to front
.btn-group > .btn:hover,
.btn-group > .btn:focus,
.btn-group > .btn:active,
.btn-group > .btn.active {
z-index: 2;
}
// On active and open, don't show outline
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
// Split button dropdowns
// ----------------------
// Give the line between buttons some depth
.btn-group > .btn + .dropdown-toggle {
padding-left: 8px;
padding-right: 8px;
.box-shadow(inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05));
*padding-top: 5px;
*padding-bottom: 5px;
}
.btn-group > .btn-mini + .dropdown-toggle {
padding-left: 5px;
padding-right: 5px;
*padding-top: 2px;
*padding-bottom: 2px;
}
.btn-group > .btn-small + .dropdown-toggle {
*padding-top: 5px;
*padding-bottom: 4px;
}
.btn-group > .btn-large + .dropdown-toggle {
padding-left: 12px;
padding-right: 12px;
*padding-top: 7px;
*padding-bottom: 7px;
}
.btn-group.open {
// The clickable button for toggling the menu
// Remove the gradient and set the same inset shadow as the :active state
.dropdown-toggle {
background-image: none;
.box-shadow(inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05));
}
// Keep the hover's background when dropdown is open
.btn.dropdown-toggle {
background-color: @btnBackgroundHighlight;
}
.btn-primary.dropdown-toggle {
background-color: @btnPrimaryBackgroundHighlight;
}
.btn-warning.dropdown-toggle {
background-color: @btnWarningBackgroundHighlight;
}
.btn-danger.dropdown-toggle {
background-color: @btnDangerBackgroundHighlight;
}
.btn-success.dropdown-toggle {
background-color: @btnSuccessBackgroundHighlight;
}
.btn-info.dropdown-toggle {
background-color: @btnInfoBackgroundHighlight;
}
.btn-inverse.dropdown-toggle {
background-color: @btnInverseBackgroundHighlight;
}
}
// Reposition the caret
.btn .caret {
margin-top: 8px;
margin-left: 0;
}
// Carets in other button sizes
.btn-mini .caret,
.btn-small .caret,
.btn-large .caret {
margin-top: 6px;
}
.btn-large .caret {
border-left-width: 5px;
border-right-width: 5px;
border-top-width: 5px;
}
// Upside down carets for .dropup
.dropup .btn-large .caret {
border-bottom: 5px solid @black;
border-top: 0;
}
// Account for other colors
.btn-primary,
.btn-warning,
.btn-danger,
.btn-info,
.btn-success,
.btn-inverse {
.caret {
border-top-color: @white;
border-bottom-color: @white;
}
}
// Vertical button groups
// ----------------------
.btn-group-vertical {
display: inline-block; // makes buttons only take up the width they need
.ie7-inline-block();
}
.btn-group-vertical .btn {
display: block;
float: none;
width: 100%;
.border-radius(0);
}
.btn-group-vertical .btn + .btn {
margin-left: 0;
margin-top: -1px;
}
.btn-group-vertical .btn:first-child {
.border-radius(4px 4px 0 0);
}
.btn-group-vertical .btn:last-child {
.border-radius(0 0 4px 4px);
}
.btn-group-vertical .btn-large:first-child {
.border-radius(6px 6px 0 0);
}
.btn-group-vertical .btn-large:last-child {
.border-radius(0 0 6px 6px);
}

231
bootstrap/less/buttons.less Normal file
View File

@ -0,0 +1,231 @@
//
// Buttons
// --------------------------------------------------
// Base styles
// --------------------------------------------------
// Core
.btn {
display: inline-block;
.ie7-inline-block();
padding: 4px 14px;
margin-bottom: 0; // For input.btn
font-size: @baseFontSize;
line-height: @baseLineHeight;
*line-height: @baseLineHeight;
text-align: center;
vertical-align: middle;
cursor: pointer;
.buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75));
border: 1px solid @btnBorder;
*border: 0; // Remove the border to prevent IE7's black border on input:focus
border-bottom-color: darken(@btnBorder, 10%);
.border-radius(4px);
.ie7-restore-left-whitespace(); // Give IE7 some love
.box-shadow(inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05));
// Hover state
&:hover {
color: @grayDark;
text-decoration: none;
background-color: darken(@white, 10%);
*background-color: darken(@white, 15%); /* Buttons in IE7 don't get borders, so darken on hover */
background-position: 0 -15px;
// transition is only when going to hover, otherwise the background
// behind the gradient (there for IE<=9 fallback) gets mismatched
.transition(background-position .1s linear);
}
// Focus state for keyboard and accessibility
&:focus {
.tab-focus();
}
// Active state
&.active,
&:active {
background-color: darken(@white, 10%);
background-color: darken(@white, 15%) e("\9");
background-image: none;
outline: 0;
.box-shadow(inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05));
}
// Disabled state
&.disabled,
&[disabled] {
cursor: default;
background-color: darken(@white, 10%);
background-image: none;
.opacity(65);
.box-shadow(none);
}
}
// Button Sizes
// --------------------------------------------------
// Large
.btn-large {
padding: 9px 14px;
font-size: @baseFontSize + 2px;
line-height: normal;
.border-radius(5px);
}
.btn-large [class^="icon-"] {
margin-top: 2px;
}
// Small
.btn-small {
padding: 3px 9px;
font-size: @baseFontSize - 2px;
line-height: @baseLineHeight - 2px;
}
.btn-small [class^="icon-"] {
margin-top: 0;
}
// Mini
.btn-mini {
padding: 2px 6px;
font-size: @baseFontSize - 3px;
line-height: @baseLineHeight - 3px;
}
// Block button
// -------------------------
.btn-block {
display: block;
width: 100%;
padding-left: 0;
padding-right: 0;
.box-sizing(border-box);
}
// Vertically space out multiple block buttons
.btn-block + .btn-block {
margin-top: 5px;
}
// Specificity overrides
input[type="submit"],
input[type="reset"],
input[type="button"] {
&.btn-block {
width: 100%;
}
}
// Alternate buttons
// --------------------------------------------------
// Provide *some* extra contrast for those who can get it
.btn-primary.active,
.btn-warning.active,
.btn-danger.active,
.btn-success.active,
.btn-info.active,
.btn-inverse.active {
color: rgba(255,255,255,.75);
}
// Set the backgrounds
// -------------------------
.btn {
// reset here as of 2.0.3 due to Recess property order
border-color: #c5c5c5;
border-color: rgba(0,0,0,.15) rgba(0,0,0,.15) rgba(0,0,0,.25);
}
.btn-primary {
.buttonBackground(@btnPrimaryBackground, @btnPrimaryBackgroundHighlight);
}
// Warning appears are orange
.btn-warning {
.buttonBackground(@btnWarningBackground, @btnWarningBackgroundHighlight);
}
// Danger and error appear as red
.btn-danger {
.buttonBackground(@btnDangerBackground, @btnDangerBackgroundHighlight);
}
// Success appears as green
.btn-success {
.buttonBackground(@btnSuccessBackground, @btnSuccessBackgroundHighlight);
}
// Info appears as a neutral blue
.btn-info {
.buttonBackground(@btnInfoBackground, @btnInfoBackgroundHighlight);
}
// Inverse appears as dark gray
.btn-inverse {
.buttonBackground(@btnInverseBackground, @btnInverseBackgroundHighlight);
}
// Cross-browser Jank
// --------------------------------------------------
button.btn,
input[type="submit"].btn {
// Firefox 3.6 only I believe
&::-moz-focus-inner {
padding: 0;
border: 0;
}
// IE7 has some default padding on button controls
*padding-top: 3px;
*padding-bottom: 3px;
&.btn-large {
*padding-top: 7px;
*padding-bottom: 7px;
}
&.btn-small {
*padding-top: 3px;
*padding-bottom: 3px;
}
&.btn-mini {
*padding-top: 1px;
*padding-bottom: 1px;
}
}
// Link buttons
// --------------------------------------------------
// Make a button look and behave like a link
.btn-link,
.btn-link:active,
.btn-link[disabled] {
background-color: transparent;
background-image: none;
.box-shadow(none);
}
.btn-link {
border-color: transparent;
cursor: pointer;
color: @linkColor;
.border-radius(0);
}
.btn-link:hover {
color: @linkColorHover;
text-decoration: underline;
background-color: transparent;
}
.btn-link[disabled]:hover {
color: @grayDark;
text-decoration: none;
}

View File

@ -0,0 +1,131 @@
//
// Carousel
// --------------------------------------------------
.carousel {
position: relative;
margin-bottom: @baseLineHeight;
line-height: 1;
}
.carousel-inner {
overflow: hidden;
width: 100%;
position: relative;
}
.carousel {
.item {
display: none;
position: relative;
.transition(.6s ease-in-out left);
}
// Account for jankitude on images
.item > img {
display: block;
line-height: 1;
}
.active,
.next,
.prev { display: block; }
.active {
left: 0;
}
.next,
.prev {
position: absolute;
top: 0;
width: 100%;
}
.next {
left: 100%;
}
.prev {
left: -100%;
}
.next.left,
.prev.right {
left: 0;
}
.active.left {
left: -100%;
}
.active.right {
left: 100%;
}
}
// Left/right controls for nav
// ---------------------------
.carousel-control {
position: absolute;
top: 40%;
left: 15px;
width: 40px;
height: 40px;
margin-top: -20px;
font-size: 60px;
font-weight: 100;
line-height: 30px;
color: @white;
text-align: center;
background: @grayDarker;
border: 3px solid @white;
.border-radius(23px);
.opacity(50);
// we can't have this transition here
// because webkit cancels the carousel
// animation if you trip this while
// in the middle of another animation
// ;_;
// .transition(opacity .2s linear);
// Reposition the right one
&.right {
left: auto;
right: 15px;
}
// Hover state
&:hover {
color: @white;
text-decoration: none;
.opacity(90);
}
}
// Caption for text below images
// -----------------------------
.carousel-caption {
position: absolute;
left: 0;
right: 0;
bottom: 0;
padding: 15px;
background: @grayDark;
background: rgba(0,0,0,.75);
}
.carousel-caption h4,
.carousel-caption p {
color: @white;
line-height: @baseLineHeight;
}
.carousel-caption h4 {
margin: 0 0 5px;
}
.carousel-caption p {
margin-bottom: 0;
}

31
bootstrap/less/close.less Normal file
View File

@ -0,0 +1,31 @@
//
// Close icons
// --------------------------------------------------
.close {
float: right;
font-size: 20px;
font-weight: bold;
line-height: @baseLineHeight;
color: @black;
text-shadow: 0 1px 0 rgba(255,255,255,1);
.opacity(20);
&:hover {
color: @black;
text-decoration: none;
cursor: pointer;
.opacity(40);
}
}
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
button.close {
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
-webkit-appearance: none;
}

58
bootstrap/less/code.less Normal file
View File

@ -0,0 +1,58 @@
//
// Code (inline and blocK)
// --------------------------------------------------
// Inline and block code styles
code,
pre {
padding: 0 3px 2px;
#font > #family > .monospace;
font-size: @baseFontSize - 2;
color: @grayDark;
.border-radius(3px);
}
// Inline code
code {
padding: 2px 4px;
color: #d14;
background-color: #f7f7f9;
border: 1px solid #e1e1e8;
}
// Blocks of code
pre {
display: block;
padding: (@baseLineHeight - 1) / 2;
margin: 0 0 @baseLineHeight / 2;
font-size: @baseFontSize - 1; // 14px to 13px
line-height: @baseLineHeight;
word-break: break-all;
word-wrap: break-word;
white-space: pre;
white-space: pre-wrap;
background-color: #f5f5f5;
border: 1px solid #ccc; // fallback for IE7-8
border: 1px solid rgba(0,0,0,.15);
.border-radius(4px);
// Make prettyprint styles more spaced out for readability
&.prettyprint {
margin-bottom: @baseLineHeight;
}
// Account for some code outputs that place code tags in pre tags
code {
padding: 0;
color: inherit;
background-color: transparent;
border: 0;
}
}
// Enable scrollable blocks of code
.pre-scrollable {
max-height: 340px;
overflow-y: scroll;
}

View File

@ -0,0 +1,22 @@
//
// Component animations
// --------------------------------------------------
.fade {
opacity: 0;
.transition(opacity .15s linear);
&.in {
opacity: 1;
}
}
.collapse {
position: relative;
height: 0;
overflow: hidden;
.transition(height .35s ease);
&.in {
height: auto;
}
}

736
bootstrap/less/custom.less Normal file
View File

@ -0,0 +1,736 @@
html.thin {
#content {
margin-left: 85px;
}
#sidebar {
width: 85px;
}
}
html.wide {
#sidebar {
width: 311px;
}
}
.widget form {
padding: 20px 0 0 0;
margin: 0;
.form-actions {
margin-bottom: 0;
}
legend {
padding-left: 20px;
}
}
body {
background: url(/resources/images/backgrounds/body.jpg);
}
.loadingPanel {
position: absolute;
top: -5px;
z-index: 1200;
background-color: #F7F7F7;
width: 100px;
box-shadow: 0 2px 2px -2px #CCC;
border: 1px solid #CDCDCD;
border-radius: 3px;
left: 50%;
padding: 10px 20px 5px 20px;
margin-left: -50px;
}
.errorPanel {
position: fixed;
z-index: 1200;
background: #BA6D6D;
width: 100%;
padding: 5px 10px;
color: white;
}
#top {
position: fixed;
background: url(/resources/images/backgrounds/top.jpg);
height: 48px;
width: 100%;
border-bottom: 1px solid #1C1C1C;
z-index: 1000;
.wrapper {
margin: 0 30px;
}
.logo {
position: absolute;
background-image: url(/resources/images/logo.svg);
background-repeat: no-repeat;
background-size: 100px 100px;
background-position: 0 -25px;
height: 48px;
width: 300px;
padding-left: 5px;
opacity: 0.3;
float: left;
}
.logoText {
float: left;
font-size: 18px;
margin-top: 12px;
color: #CCC;
}
.topNav {
float: right;
position: relative;
}
.userNav {
float: left;
margin: 10px 0 0 0;
li {
display: inline-block;
margin: 0 0 0 10px;
background: #262626;
.border-radius (50%);
.box-shadow (0 1px 0 #4E4E4E);
a {
display: block;
height: 28px;
width: 28px;
}
a.search {
background: url(/resources/images/icons/usernav/search.png) no-repeat 9px 9px;
}
a.settings {
background: url(/resources/images/icons/usernav/settings.png) no-repeat 9px 9px;
}
a.logout {
background: url(/resources/images/icons/usernav/logout.png) no-repeat 9px 9px;
}
}
}
}
#sidebar {
position: fixed;
background: url(/resources/images/backgrounds/side.jpg);
background-position: -15px;
height: 100%;
width: 311px;
top: 49px;
border-right: 1px solid #C3C3C3;
.mainNav {
float: left;
list-style: none;
margin-left: 0;
padding-top: 0;
text-align: center;
border-bottom: 1px solid #555;
width: 85px;
li {
border-top: 1px solid #555;
border-bottom: 1px solid #2E2E2E;
a {
display: block;
padding: 14px 0 8px 0;
color: #BABABA;
font-size: 11px;
width: 85px;
#gradient > .vertical (rgba(86, 86, 86, 0.2) , rgba(54, 54, 54, 0.2));
&:hover {
color: #F4F4F4;
text-decoration: none;
.transition (all 0.3s ease-in-out);
img {
opacity: 1;
.transition (all 0.3s ease-in-out);
}
}
&:active , &.active {
color: #F4F4F4;
#gradient > .vertical (rgba(128, 128, 128, 0.4) , rgba(115, 115, 115, 0.3));
}
span {
display: block;
padding-top: 4px;
text-shadow: 0 1px 0 #303030;
}
}
img {
opacity: 0.5;
}
}
}
.secNav {
padding-left: 85px;
}
.gwt-DatePicker {
margin: 20px auto;
}
}
.sub-nav {
border-top: 1px solid #C3C3C3;
margin: 10px 0 0 0;
padding: 0;
list-style: none;
a {
color: #6A6A6A;
padding: 4px 14px 8px 10px;
display: block;
border-top: 1px solid #FDFDFD;
border-bottom: 1px solid #CECECE;
font-weight: bold;
font-size: 11px;
#gradient > .vertical (#f7f7f7 , #e6e6e6);
&:hover {
text-decoration: none;
#gradient > .vertical (#fbfbfb , #e8e8e8);
}
i {
position: relative;
margin-right: 0;
font-size: 12px;
top: 4px;
}
}
li.active {
border-left: 4px solid #505050;
a {
background: url(/resources/images/backgrounds/body.jpg);
margin-right: -1px;
color: #A64949;
padding-left: 6px;
}
}
}
.subNav {
list-style: none;
margin: 10px 0 20px 0;
border-top: 1px solid #c3c3c3;
li {
font-size: 11px;
position: relative;
a > img {
display: block;
float: left;
padding: 5px 10px 0 0;
}
a {
color: #6a6a6a;
padding: 8px 14px 8px 14px;
display: block;
border-top: 1px solid #fdfdfd;
border-bottom: 1px solid #cecece;
font-weight: bold;
#gradient > .vertical (#f7f7f7 , #e6e6e6);
&:hover {
#gradient > .vertical (#fbfbfb , #e8e8e8);
}
&:active {
background: #f0f0f0;
}
}
}
}
#content {
.wrapper {
margin: 0 30px;
}
}
.scheduler {
margin: 0 -30px;
position: fixed;
top: 49px;
bottom: 0;
img {
max-width: none ! important;
}
}
.frequency {
margin: 20px 0 0 0;
width: auto;
.name {
text-align: right;
background: white;
}
th {
background: white;
}
td {
text-align: center;
}
.icon::before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
display: inline-block;
text-decoration: inherit;
}
.disabled {
width: 20px;
height: 20px;
background-color: #F9F9F9;
color: #CCC;
cursor: pointer;
.icon::before {
content: "\f00d";
}
}
.enabled {
width: 20px;
height: 20px;
background-color: #DFF0D8;
color: #468847;
cursor: pointer;
.icon::before {
content: "\f00c";
}
}
.controls {
text-align: right;
background: white;
}
}
.gwt-cal {
position: relative;
white-space: nowrap;
overflow: hidden;
.major-time-interval {
border-top: 1px solid #D5D5D5;
}
.minor-time-interval {
border-top: 1px dotted #D5D5D5;
}
.working-hours {
background: #FFF;
}
.hour-label {
width: 50px;
border-top: 1px solid #DDD;
background: #FFF;
}
.hour-layout {
text-align: right;
padding: 0 4px;
}
.hour-text {
display: inline;
text-transform: lowercase;
}
.hour-noon-text {
display: inline;
text-transform: lowercase;
}
.ampm-text {
display: inline;
text-transform: lowercase;
}
.scroll-area {
height: 500px;
overflow: scroll;
overflow-x: hidden;
}
.gwt-calendar-header {
width: 100%;
border-top: 1px solid #D5D5D5;
border-bottom: 1px solid #D5D5D5;
table-layout: fixed;
border-collapse: collapse;
#gradient > .vertical (#F8F8F8 , #E8E8E8);
.year-cell {
width: 50px;
text-align: center;
}
.splitter {
}
.day-cell-container {
border-right: 1px solid #D5D5D5;
}
.day-cell , .day-cell-weekend {
position: absolute;
top: 0;
padding-top: 2px;
text-align: center;
border-left: 1px solid #D5D5D5;
}
.day-cell-today {
padding-top: 2px;
font-weight: bold;
text-align: center;
border-left: 1px solid #D5D5D5;
}
}
.multiDayBody {
width: 100%;
background: white;
table-layout: fixed;
.splitter {
height: 2px;
background: white;
border-top: 1px solid #D5D5D5;
border-bottom: 1px solid #D5D5D5;
}
}
.leftEmptyCell {
width: 50px;
}
.rightEmptyCell {
border-left: 1px solid #D5D5D5;
}
.day-separator {
position: absolute;
top: 0;
width: 3px;
height: 100%;
border-right: 1px solid #DDD;
border-left: 1px solid #DDD;
}
}
.gwt-cal .gwt-appointment-panel {
position: relative;
height: 1200px;
}
.gwt-cal .gwt-appointment-cell {
width: 99%;
}
.gwt-cal .dv-appointment {
border-style: solid;
border-width: 1px;
border-color: #979797 ! important;
position: absolute;
font-size: 10px;
font-family: arial;
overflow: hidden;
filter: alpha(opacity=50);
opacity: .9;
-moz-opacity: .9;
}
.gwt-cal .dv-appointment-selected {
border-style: solid;
border-width: 1px;
border-color: #979797 ! important;
position: absolute;
font-size: 10px;
font-family: arial;
overflow: hidden;
-webkit-box-shadow: 3px 3px 5px #B7B7B7;
-moz-box-shadow: 3px 3px 5px #B7B7B7;
opacity: 1;
-moz-opacity: 1;
}
.gwt-cal .dv-appointment-multiday {
border-style: solid;
border-width: 1px;
position: absolute;
font-size: 10px;
font-family: arial;
overflow: hidden;
filter: alpha(opacity=50);
opacity: .5;
-moz-opacity: .5;
}
.gwt-cal .dv-appointment-multiday-selected {
border-style: solid;
border-width: 1px;
position: absolute;
font-size: 10px;
font-family: arial;
overflow: hidden;
-webkit-box-shadow: 0 2px 2px -2px #CCC;
-moz-box-shadow: 0 2px 2px -2px #CCC;
opacity: 1;
-moz-opacity: 1;
}
.gwt-cal .dv-appointment .header , .gwt-cal .dv-appointment-selected .header {
white-space: initial;
color: #1D1D1D ! important;
padding: 1px;
padding-left: 8px;
font-weight: bold;
border-bottom: 1px solid black;
}
.gwt-cal .dv-appointment-multiday .header , .gwt-cal .dv-appointment-multiday-selected .header {
background: transparent;
}
.gwt-cal .dv-appointment .body , .gwt-cal .dv-appointment-selected .body , .gwt-cal .dv-appointment-multiday .body , .gwt-cal .dv-appointment-multiday-selected .body {
padding-left: 8px;
padding-top: 1px;
white-space: initial;
color: #1D1D1D ! important;
}
.gwt-cal .dv-appointment .footer , .gwt-cal .dv-appointment-selected .footer {
border-bottom: 3px double #FFF;
position: absolute;
bottom: 2px;
left: 48%;
height: 4px;
width: 8px;
}
.gwt-cal .dv-appointment-multiday .footer , .gwt-cal .dv-appointment-multiday-selected .footer {
display: none;
}
.gwt-cal-ListView {
overflow-y: scroll;
font-family: Verdana, Sans-serif;
font-size: 11px;
font-weight: bold;
}
.gwt-cal-ListView .dateCell {
white-space: nowrap;
padding-right: 30px;
color: #112ABB;
color: #3366CC;
font-family: Verdana, Sans-serif;
font-size: 11px;
font-weight: bold;
}
.gwt-cal-ListView .timeCell {
white-space: nowrap;
padding-left: 30px;
padding-right: 30px;
color: #3366CC;
font-family: Verdana, Sans-serif;
font-size: 11px;
font-weight: bold;
}
.gwt-cal-ListView .titleCell {
width: 99%;
color: #3366CC;
font-family: Verdana, Sans-serif;
font-size: 11px;
font-weight: bold;
}
.gwt-cal-ListView .row {
background: #E8EEF7;
}
.gwt-cal-ListView .row-alt {
background: #FFF;
}
.gwt-cal-ListView .row-today , .gwt-cal-ListView .row-alt-today {
background: #FFFFCC;
}
.gwt-cal-ListView .row-today .dateCell , .gwt-cal-ListView .row-alt-today .dateCell {
background: #BBCCDD;
border-color: #8899AA #DDEEFF #DDEEFF #8899AA;
border-style: solid;
border-width: 1px 1px 0 0;
color: #112ABB;
}
.gwt-cal-ListView .descriptionLabel {
color: #333333;
font-weight: normal;
font-size: 11px;
}
.gwt-cal-ListView .detailDecorator {
border-left: 2px solid #BBCCDC;
margin: 3px 0 5px 20px;
padding: 0 8px 4px 10px;
}
.gwt-cal-ListView .detailContainer {
font-weight: normal;
color: #333;
}
.gwt-cal-ListView .detailHeader {
font-weight: bold;
}
.gwt-cal-ListView .moreDetailsButton {
border-top: 1px solid #2952A3;
padding-top: 0.25em;
margin-top: 0.5em;
font-weight: normal;
font-color: #112ABB;
text-decoration: underline;
}
.gwt-cal-MonthView {
position: relative;
height: 523px;
white-space: nowrap;
overflow: hidden;
width: 100%;
overflow: hidden;
}
.gwt-cal-MonthView .grid {
table-layout: fixed;
background: #FFF;
width: 100%;
height: 100%;
border-collapse: collapse;
}
.gwt-cal-MonthView .canvas {
white-space: nowrap;
overflow: hidden;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
font-family: arial;
font-size: 12px;
background: transparent;
}
.gwt-cal-MonthView .dayCell , .gwt-cal-MonthView .dayCell-today {
border-left: 1px solid rgb(195, 217, 255);
border-bottom: 1px solid rgb(195, 217, 255);
}
.gwt-cal-MonthView .weekDayLabel , .gwt-cal-MonthView .weekDayLabel-today {
height: 20px;
text-align: center;
background-color: rgb(195, 217, 255);
font-size: 13px;
color: rgb(17, 42, 187);
}
.gwt-Cal-MonthView .dayCellLabel , .gwt-Cal-MonthView .dayCellLabel-today {
background-color: rgb(232, 238, 247);
display: block;
height: 15px;
font-family: arial;
font-size: 11px;
text-align: right;
padding-right: 5px;
}
.gwt-Cal-MonthView .dayCellLabel-today-disabled , .gwt-Cal-MonthView .dayCellLabel-disabled {
background-color: rgb(238, 238, 238);
display: block;
height: 15px;
font-family: arial;
font-size: 11px;
text-align: right;
padding-right: 5px;
color: #999;
}
.gwt-Cal-MonthView .dayCellLabel-today , .gwt-Cal-MonthView .dayCellLabel-today-disabled {
background-color: rgb(187, 204, 221);
}
.gwt-cal-MonthView .dayCell-today {
background-color: rgb(255, 255, 204);
}
.gwt-cal-MonthView .moreAppointments {
position: absolute;
text-align: center;
text-decoration: underline;
}
.gwt-cal-MonthView .appointment {
position: absolute;
height: 20px;
overflow: hidden;
text-decoration: none;
}
.gwt-cal-MonthView .appointment-selected {
text-decoration: underline;
border: 0px;
overflow: hidden;
}
.gwt-cal-MonthView .appointment-multiday {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
position: absolute;
height: 20px;
color: #FFF;
overflow: hidden;
border-style: solid;
border-width: 1px;
}
.gwt-cal-MonthView .appointment-multiday-selected {
position: absolute;
height: 20px;
overflow: hidden;
border-style: solid;
border-width: 1px;
-webkit-box-shadow: 3px 3px 5px #B7B7B7;
-moz-box-shadow: 3px 3px 5px #B7B7B7;
text-decoration: none;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
position: absolute;
height: 20px;
color: #FFF;
overflow: hidden;
}

View File

@ -0,0 +1,210 @@
//
// Dropdown menus
// --------------------------------------------------
// Use the .menu class on any <li> element within the topbar or ul.tabs and you'll get some superfancy dropdowns
.dropup,
.dropdown {
position: relative;
}
.dropdown-toggle {
// The caret makes the toggle a bit too tall in IE7
*margin-bottom: -3px;
}
.dropdown-toggle:active,
.open .dropdown-toggle {
outline: 0;
}
// Dropdown arrow/caret
// --------------------
.caret {
display: inline-block;
width: 0;
height: 0;
vertical-align: top;
border-top: 4px solid @black;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
content: "";
}
// Place the caret
.dropdown .caret {
margin-top: 8px;
margin-left: 2px;
}
// The dropdown menu (ul)
// ----------------------
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: @zindexDropdown;
display: none; // none by default, but block on "open" of the menu
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0; // override default ul
list-style: none;
background-color: @dropdownBackground;
border: 1px solid #ccc; // Fallback for IE7-8
border: 1px solid @dropdownBorder;
*border-right-width: 2px;
*border-bottom-width: 2px;
.border-radius(6px);
.box-shadow(0 5px 10px rgba(0,0,0,.2));
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
// Aligns the dropdown menu to right
&.pull-right {
right: 0;
left: auto;
}
// Dividers (basically an hr) within the dropdown
.divider {
.nav-divider(@dropdownDividerTop, @dropdownDividerBottom);
}
// Links within the dropdown menu
a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: @baseLineHeight;
color: @dropdownLinkColor;
white-space: nowrap;
}
}
// Hover state
// -----------
.dropdown-menu li > a:hover,
.dropdown-menu li > a:focus,
.dropdown-submenu:hover > a {
text-decoration: none;
color: @dropdownLinkColorHover;
background-color: @dropdownLinkBackgroundHover;
#gradient > .vertical(@dropdownLinkBackgroundHover, darken(@dropdownLinkBackgroundHover, 5%));
}
// Active state
// ------------
.dropdown-menu .active > a,
.dropdown-menu .active > a:hover {
color: @dropdownLinkColorHover;
text-decoration: none;
outline: 0;
background-color: @dropdownLinkBackgroundActive;
#gradient > .vertical(@dropdownLinkBackgroundActive, darken(@dropdownLinkBackgroundActive, 5%));
}
// Disabled state
// --------------
// Gray out text and ensure the hover state remains gray
.dropdown-menu .disabled > a,
.dropdown-menu .disabled > a:hover {
color: @grayLight;
}
// Nuke hover effects
.dropdown-menu .disabled > a:hover {
text-decoration: none;
background-color: transparent;
cursor: default;
}
// Open state for the dropdown
// ---------------------------
.open {
// IE7's z-index only goes to the nearest positioned ancestor, which would
// make the menu appear below buttons that appeared later on the page
*z-index: @zindexDropdown;
& > .dropdown-menu {
display: block;
}
}
// Right aligned dropdowns
// ---------------------------
.pull-right > .dropdown-menu {
right: 0;
left: auto;
}
// Allow for dropdowns to go bottom up (aka, dropup-menu)
// ------------------------------------------------------
// Just add .dropup after the standard .dropdown class and you're set, bro.
// TODO: abstract this so that the navbar fixed styles are not placed here?
.dropup,
.navbar-fixed-bottom .dropdown {
// Reverse the caret
.caret {
border-top: 0;
border-bottom: 4px solid @black;
content: "";
}
// Different positioning for bottom up menu
.dropdown-menu {
top: auto;
bottom: 100%;
margin-bottom: 1px;
}
}
// Sub menus
// ---------------------------
.dropdown-submenu {
position: relative;
}
.dropdown-submenu > .dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.dropdown-submenu:hover > .dropdown-menu {
display: block;
}
.dropdown-submenu > a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: darken(@dropdownBackground, 20%);
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu:hover > a:after {
border-left-color: @dropdownLinkColorHover;
}
// Tweak nav headers
// -----------------
// Increase padding from 15px to 20px on sides
.dropdown .dropdown-menu .nav-header {
padding-left: 20px;
padding-right: 20px;
}
// Typeahead
// ---------
.typeahead {
margin-top: 2px; // give it some space to breathe
.border-radius(4px);
}

653
bootstrap/less/forms.less Normal file
View File

@ -0,0 +1,653 @@
//
// Forms
// --------------------------------------------------
// GENERAL STYLES
// --------------
// Make all forms have space below them
form {
margin: 0 0 @baseLineHeight;
}
fieldset {
padding: 0;
margin: 0;
border: 0;
}
// Groups of fields with labels on top (legends)
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: @baseLineHeight;
font-size: @baseFontSize * 1.5;
line-height: @baseLineHeight * 2;
color: @grayDark;
border: 0;
border-bottom: 1px solid #e5e5e5;
// Small
small {
font-size: @baseLineHeight * .75;
color: @grayLight;
}
}
// Set font for forms
label,
input,
button,
select,
textarea {
#font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here
}
input,
button,
select,
textarea {
font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element)
}
// Identify controls by their labels
label {
display: block;
margin-bottom: 5px;
}
// Form controls
// -------------------------
// Shared size and type resets
select,
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"],
.uneditable-input {
display: inline-block;
height: @baseLineHeight;
padding: 4px 6px;
margin-bottom: 9px;
font-size: @baseFontSize;
line-height: @baseLineHeight;
color: @gray;
}
// Reset appearance properties for textual inputs and textarea
// Declare width for legacy (can't be on input[type=*] selectors or it's too specific)
input,
textarea,
.uneditable-input {
width: 206px; // plus 12px padding and 2px border
}
// Reset height since textareas have rows
textarea {
height: auto;
}
// Everything else
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"],
.uneditable-input {
background-color: @inputBackground;
border: 1px solid @inputBorder;
.box-shadow(0 1px 0 @white);
.transition(~"border linear .2s, box-shadow linear .2s");
// Focus state
&:focus {
border-color: rgba(82,168,236,.8);
outline: 0;
outline: thin dotted \9; /* IE6-9 */
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6));
}
}
// Position radios and checkboxes better
input[type="radio"],
input[type="checkbox"] {
margin: 4px 0 0;
*margin-top: 0; /* IE7 */
margin-top: 1px \9; /* IE8-9 */
line-height: normal;
cursor: pointer;
}
// Reset width of input images, buttons, radios, checkboxes
input[type="file"],
input[type="image"],
input[type="submit"],
input[type="reset"],
input[type="button"],
input[type="radio"],
input[type="checkbox"] {
width: auto; // Override of generic input selector
}
// Set the height of select and file controls to match text inputs
select,
input[type="file"] {
height: 26px; /* In IE7, the height of the select element cannot be changed by height, only font-size */
*margin-top: 4px; /* For IE7, add top margin to align select with labels */
line-height: 26px;
}
// Make select elements obey height by applying a border
select {
width: 220px; // default input width + 10px of padding that doesn't get applied
border: 1px solid @inputBorder;
background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color
#gradient > .vertical(#FCFCFC, #F1F1F1);
color: gray;
border-radius: 2px;
}
// Make multiple select elements height not fixed
select[multiple],
select[size] {
height: auto;
}
// Focus for select, file, radio, and checkbox
select:focus,
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
.tab-focus();
}
// Uneditable inputs
// -------------------------
// Make uneditable inputs look inactive
.uneditable-input,
.uneditable-textarea {
color: @grayLight;
background-color: darken(@inputBackground, 1%);
border-color: @inputBorder;
.box-shadow(inset 0 1px 2px rgba(0,0,0,.025));
cursor: not-allowed;
}
// For text that needs to appear as an input but should not be an input
.uneditable-input {
overflow: hidden; // prevent text from wrapping, but still cut it off like an input does
white-space: nowrap;
}
// Make uneditable textareas behave like a textarea
.uneditable-textarea {
width: auto;
height: auto;
}
// Placeholder
// -------------------------
// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn<73><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t understand a selector
input,
textarea {
.placeholder();
}
// CHECKBOXES & RADIOS
// -------------------
// Indent the labels to position radios/checkboxes as hanging
.radio,
.checkbox {
min-height: 18px; // clear the floating input if there is no label text
padding-left: 18px;
}
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
float: left;
margin-left: -18px;
}
// Move the options list down to align with labels
.controls > .radio:first-child,
.controls > .checkbox:first-child {
padding-top: 5px; // has to be padding because margin collaspes
}
// Radios and checkboxes on same line
// TODO v3: Convert .inline to .control-inline
.radio.inline,
.checkbox.inline {
display: inline-block;
padding-top: 5px;
margin-bottom: 0;
vertical-align: middle;
}
.radio.inline + .radio.inline,
.checkbox.inline + .checkbox.inline {
margin-left: 10px; // space out consecutive inline controls
}
// INPUT SIZES
// -----------
// General classes for quick sizes
.input-mini { width: 60px; }
.input-small { width: 90px; }
.input-medium { width: 150px; }
.input-large { width: 210px; }
.input-xlarge { width: 270px; }
.input-xxlarge { width: 530px; }
// Grid style input sizes
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input[class*="span"],
// Redeclare since the fluid row class is more specific
.row-fluid input[class*="span"],
.row-fluid select[class*="span"],
.row-fluid textarea[class*="span"],
.row-fluid .uneditable-input[class*="span"] {
float: none;
margin-left: 0;
}
// Ensure input-prepend/append never wraps
.input-append input[class*="span"],
.input-append .uneditable-input[class*="span"],
.input-prepend input[class*="span"],
.input-prepend .uneditable-input[class*="span"],
.row-fluid input[class*="span"],
.row-fluid select[class*="span"],
.row-fluid textarea[class*="span"],
.row-fluid .uneditable-input[class*="span"],
.row-fluid .input-prepend [class*="span"],
.row-fluid .input-append [class*="span"] {
display: inline-block;
}
// GRID SIZING FOR INPUTS
// ----------------------
// Grid sizes
#grid > .input(@gridColumnWidth, @gridGutterWidth);
// Control row for multiple inputs per line
.controls-row {
.clearfix(); // Clear the float from controls
}
.controls-row [class*="span"] {
float: left; // Float to collapse white-space for proper grid alignment
}
// DISABLED STATE
// --------------
// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
input[readonly],
select[readonly],
textarea[readonly] {
cursor: not-allowed;
background-color: @inputDisabledBackground;
}
// Explicitly reset the colors here
input[type="radio"][disabled],
input[type="checkbox"][disabled],
input[type="radio"][readonly],
input[type="checkbox"][readonly] {
background-color: transparent;
}
// FORM FIELD FEEDBACK STATES
// --------------------------
// Warning
.control-group.warning {
.formFieldState(@warningText, @warningText, @warningBackground);
}
// Error
.control-group.error {
.formFieldState(@errorText, @errorText, @errorBackground);
}
// Success
.control-group.success {
.formFieldState(@successText, @successText, @successBackground);
}
// Success
.control-group.info {
.formFieldState(@infoText, @infoText, @infoBackground);
}
// HTML5 invalid states
// Shares styles with the .control-group.error above
input:focus:required:invalid,
textarea:focus:required:invalid,
select:focus:required:invalid {
color: #b94a48;
border-color: #ee5f5b;
&:focus {
border-color: darken(#ee5f5b, 10%);
.box-shadow(0 0 6px lighten(#ee5f5b, 20%));
}
}
// FORM ACTIONS
// ------------
.form-actions {
padding: (@baseLineHeight - 1) 20px @baseLineHeight;
margin-top: @baseLineHeight;
margin-bottom: @baseLineHeight;
background-color: @formActionsBackground;
border-top: 1px solid #e5e5e5;
.clearfix(); // Adding clearfix to allow for .pull-right button containers
}
// HELP TEXT
// ---------
.help-block,
.help-inline {
color: lighten(@textColor, 15%); // lighten the text some for contrast
}
.help-block {
display: block; // account for any element using help-block
margin-bottom: @baseLineHeight / 2;
}
.help-inline {
display: inline-block;
.ie7-inline-block();
vertical-align: middle;
padding-left: 5px;
}
// INPUT GROUPS
// ------------
// Allow us to put symbols and text within the input field for a cleaner look
.input-append,
.input-prepend {
margin-bottom: 5px;
font-size: 0;
white-space: nowrap; // Prevent span and input from separating
input,
select,
.uneditable-input {
position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness
margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms
*margin-left: 0;
font-size: @baseFontSize;
vertical-align: top;
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
// Make input on top when focused so blue border and shadow always show
&:focus {
z-index: 2;
}
}
.add-on {
display: inline-block;
width: auto;
height: @baseLineHeight;
min-width: 16px;
padding: 4px 5px;
font-size: @baseFontSize;
font-weight: normal;
line-height: @baseLineHeight;
text-align: center;
text-shadow: 0 1px 0 @white;
background-color: @grayLighter;
border: 1px solid #ccc;
}
.add-on,
.btn {
vertical-align: top;
.border-radius(0);
}
.active {
background-color: lighten(@green, 30);
border-color: @green;
}
}
.input-prepend {
.add-on,
.btn {
margin-right: -1px;
}
.add-on:first-child,
.btn:first-child {
.border-radius(@inputBorderRadius 0 0 @inputBorderRadius);
}
}
.input-append {
input,
select,
.uneditable-input {
.border-radius(@inputBorderRadius 0 0 @inputBorderRadius);
}
.add-on,
.btn {
margin-left: -1px;
}
.add-on:last-child,
.btn:last-child {
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
}
}
// Remove all border-radius for inputs with both prepend and append
.input-prepend.input-append {
input,
select,
.uneditable-input {
.border-radius(0);
}
.add-on:first-child,
.btn:first-child {
margin-right: -1px;
.border-radius(@inputBorderRadius 0 0 @inputBorderRadius);
}
.add-on:last-child,
.btn:last-child {
margin-left: -1px;
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
}
}
// SEARCH FORM
// -----------
input.search-query {
padding-right: 14px;
padding-right: 4px \9;
padding-left: 14px;
padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */
margin-bottom: 0; // Remove the default margin on all inputs
.border-radius(15px);
}
/* Allow for input prepend/append in search forms */
.form-search .input-append .search-query,
.form-search .input-prepend .search-query {
.border-radius(0); // Override due to specificity
}
.form-search .input-append .search-query {
.border-radius(14px 0 0 14px);
}
.form-search .input-append .btn {
.border-radius(0 14px 14px 0);
}
.form-search .input-prepend .search-query {
.border-radius(0 14px 14px 0);
}
.form-search .input-prepend .btn {
.border-radius(14px 0 0 14px);
}
// HORIZONTAL & VERTICAL FORMS
// ---------------------------
// Common properties
// -----------------
.form-search,
.form-inline,
.form-horizontal {
input,
textarea,
select,
.help-inline,
.uneditable-input,
.input-prepend,
.input-append {
display: inline-block;
.ie7-inline-block();
margin-bottom: 0;
vertical-align: middle;
}
// Re-hide hidden elements due to specifity
.hide {
display: none;
}
}
.form-search label,
.form-inline label,
.form-search .btn-group,
.form-inline .btn-group {
display: inline-block;
}
// Remove margin for input-prepend/-append
.form-search .input-append,
.form-inline .input-append,
.form-search .input-prepend,
.form-inline .input-prepend {
margin-bottom: 0;
}
// Inline checkbox/radio labels (remove padding on left)
.form-search .radio,
.form-search .checkbox,
.form-inline .radio,
.form-inline .checkbox {
padding-left: 0;
margin-bottom: 0;
vertical-align: middle;
}
// Remove float and margin, set to inline-block
.form-search .radio input[type="radio"],
.form-search .checkbox input[type="checkbox"],
.form-inline .radio input[type="radio"],
.form-inline .checkbox input[type="checkbox"] {
float: left;
margin-right: 3px;
margin-left: 0;
}
// Margin to space out fieldsets
.control-group {
margin-bottom: @baseLineHeight / 2;
}
// Legend collapses margin, so next element is responsible for spacing
legend + .control-group {
margin-top: @baseLineHeight;
-webkit-margin-top-collapse: separate;
}
// Horizontal-specific styles
// --------------------------
.form-horizontal {
// Increase spacing between groups
.control-group {
margin-bottom: @baseLineHeight;
.clearfix();
}
// Float the labels left
.control-label {
float: left;
width: @horizontalComponentOffset - 20;
padding-top: 5px;
text-align: right;
}
// Move over all input controls and content
.controls {
// Super jank IE7 fix to ensure the inputs in .input-append and input-prepend
// don't inherit the margin of the parent, in this case .controls
*display: inline-block;
*padding-left: 20px;
margin-left: @horizontalComponentOffset;
*margin-left: 0;
&:first-child {
*padding-left: @horizontalComponentOffset;
}
}
// Remove bottom margin on block level help text since that's accounted for on .control-group
.help-block {
margin-bottom: 0;
}
// And apply it only to .help-block instances that follow a form control
input,
select,
textarea {
+ .help-block {
margin-top: @baseLineHeight / 2;
}
}
// Move over buttons in .form-actions to align with .controls
.form-actions {
padding-left: @horizontalComponentOffset;
}
}

21
bootstrap/less/grid.less Normal file
View File

@ -0,0 +1,21 @@
//
// Grid system
// --------------------------------------------------
// Fixed (940px)
#grid > .core(@gridColumnWidth, @gridGutterWidth);
// Fluid (940px)
#grid > .fluid(@fluidGridColumnWidth, @fluidGridGutterWidth);
// Reset utility classes due to specificity
[class*="span"].hide,
.row-fluid [class*="span"].hide {
display: none;
}
[class*="span"].pull-right,
.row-fluid [class*="span"].pull-right {
float: right;
}

View File

@ -0,0 +1,24 @@
//
// Hero unit
// --------------------------------------------------
.hero-unit {
padding: 60px;
margin-bottom: 30px;
background-color: @heroUnitBackground;
.border-radius(6px);
h1 {
margin-bottom: 0;
font-size: 60px;
line-height: 1;
color: @heroUnitHeadingColor;
letter-spacing: -1px;
}
p {
font-size: 18px;
font-weight: 200;
line-height: @baseLineHeight * 1.5;
color: @heroUnitLeadColor;
}
}

View File

@ -0,0 +1,72 @@
//
// Labels and badges
// --------------------------------------------------
// Base classes
.label,
.badge {
font-size: @baseFontSize * .846;
font-weight: bold;
line-height: 14px; // ensure proper line-height if floated
color: @white;
vertical-align: baseline;
white-space: nowrap;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
background-color: @grayLight;
}
// Set unique padding and border-radii
.label {
padding: 1px 4px 2px;
.border-radius(3px);
}
.badge {
padding: 1px 9px 2px;
.border-radius(9px);
}
// Hover state, but only for links
a {
&.label:hover,
&.badge:hover {
color: @white;
text-decoration: none;
cursor: pointer;
}
}
// Colors
// Only give background-color difference to links (and to simplify, we don't qualifty with `a` but [href] attribute)
.label,
.badge {
// Important (red)
&-important { background-color: @errorText; }
&-important[href] { background-color: darken(@errorText, 10%); }
// Warnings (orange)
&-warning { background-color: @orange; }
&-warning[href] { background-color: darken(@orange, 10%); }
// Success (green)
&-success { background-color: @successText; }
&-success[href] { background-color: darken(@successText, 10%); }
// Info (turquoise)
&-info { background-color: @infoText; }
&-info[href] { background-color: darken(@infoText, 10%); }
// Inverse (black)
&-inverse { background-color: @grayDark; }
&-inverse[href] { background-color: darken(@grayDark, 10%); }
}
// Quick fix for labels/badges in buttons
.btn {
.label,
.badge {
position: relative;
top: -1px;
}
}
.btn-mini {
.label,
.badge {
top: 0;
}
}

View File

@ -0,0 +1,16 @@
//
// Layouts
// --------------------------------------------------
// Container (centered, fixed-width layouts)
.container {
.container-fixed();
}
// Fluid layouts (left aligned, with sidebar, min- & max-width content)
.container-fluid {
padding-right: @gridGutterWidth;
padding-left: @gridGutterWidth;
.clearfix();
}

681
bootstrap/less/mixins.less Normal file
View File

@ -0,0 +1,681 @@
//
// Mixins
// --------------------------------------------------
// UTILITY MIXINS
// --------------------------------------------------
// Clearfix
// --------
// For clearing floats like a boss h5bp.com/q
.clearfix {
*zoom: 1;
&:before,
&:after {
display: table;
content: "";
// Fixes Opera/contenteditable bug:
// http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952
line-height: 0;
}
&:after {
clear: both;
}
}
// Webkit-style focus
// ------------------
.tab-focus() {
// Default
outline: thin dotted #333;
// Webkit
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
// Center-align a block level element
// ----------------------------------
.center-block() {
display: block;
margin-left: auto;
margin-right: auto;
}
// IE7 inline-block
// ----------------
.ie7-inline-block() {
*display: inline; /* IE7 inline-block hack */
*zoom: 1;
}
// IE7 likes to collapse whitespace on either side of the inline-block elements.
// Ems because we're attempting to match the width of a space character. Left
// version is for form buttons, which typically come after other elements, and
// right version is for icons, which come before. Applying both is ok, but it will
// mean that space between those elements will be .6em (~2 space characters) in IE7,
// instead of the 1 space in other browsers.
.ie7-restore-left-whitespace() {
*margin-left: .3em;
&:first-child {
*margin-left: 0;
}
}
.ie7-restore-right-whitespace() {
*margin-right: .3em;
}
// Sizing shortcuts
// -------------------------
.size(@height, @width) {
width: @width;
height: @height;
}
.square(@size) {
.size(@size, @size);
}
// Placeholder text
// -------------------------
.placeholder(@color: @placeholderText) {
&:-moz-placeholder {
color: @color;
}
&:-ms-input-placeholder {
color: @color;
}
&::-webkit-input-placeholder {
color: @color;
}
}
// Text overflow
// -------------------------
// Requires inline-block or block for proper styling
.text-overflow() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// CSS image replacement
// -------------------------
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
.hide-text {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
// FONTS
// --------------------------------------------------
#font {
#family {
.serif() {
font-family: @serifFontFamily;
}
.sans-serif() {
font-family: @sansFontFamily;
}
.monospace() {
font-family: @monoFontFamily;
}
}
.shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
font-size: @size;
font-weight: @weight;
line-height: @lineHeight;
}
.serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
#font > #family > .serif;
#font > .shorthand(@size, @weight, @lineHeight);
}
.sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
#font > #family > .sans-serif;
#font > .shorthand(@size, @weight, @lineHeight);
}
.monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
#font > #family > .monospace;
#font > .shorthand(@size, @weight, @lineHeight);
}
}
// FORMS
// --------------------------------------------------
// Block level inputs
.input-block-level {
display: block;
width: 100%;
min-height: 30px; // Make inputs at least the height of their button counterpart
.box-sizing(border-box); // Makes inputs behave like true block-level elements
}
// Mixin for form field states
.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) {
// Set the text color
> label,
.help-block,
.help-inline {
color: @textColor;
}
// Style inputs accordingly
.checkbox,
.radio,
input,
select,
textarea {
color: @textColor;
}
input,
select,
textarea {
border-color: @borderColor;
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
&:focus {
border-color: darken(@borderColor, 10%);
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@borderColor, 20%));
}
}
// Give a small background color for input-prepend/-append
.input-prepend .add-on,
.input-append .add-on {
color: @textColor;
background-color: @backgroundColor;
border-color: @textColor;
}
}
// CSS3 PROPERTIES
// --------------------------------------------------
// Border Radius
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
// Single Corner Border Radius
.border-top-left-radius(@radius) {
-webkit-border-top-left-radius: @radius;
-moz-border-radius-topleft: @radius;
border-top-left-radius: @radius;
}
.border-top-right-radius(@radius) {
-webkit-border-top-right-radius: @radius;
-moz-border-radius-topright: @radius;
border-top-right-radius: @radius;
}
.border-bottom-right-radius(@radius) {
-webkit-border-bottom-right-radius: @radius;
-moz-border-radius-bottomright: @radius;
border-bottom-right-radius: @radius;
}
.border-bottom-left-radius(@radius) {
-webkit-border-bottom-left-radius: @radius;
-moz-border-radius-bottomleft: @radius;
border-bottom-left-radius: @radius;
}
// Single Side Border Radius
.border-top-radius(@radius) {
.border-top-right-radius(@radius);
.border-top-left-radius(@radius);
}
.border-right-radius(@radius) {
.border-top-right-radius(@radius);
.border-bottom-right-radius(@radius);
}
.border-bottom-radius(@radius) {
.border-bottom-right-radius(@radius);
.border-bottom-left-radius(@radius);
}
.border-left-radius(@radius) {
.border-top-left-radius(@radius);
.border-bottom-left-radius(@radius);
}
// Drop shadows
.box-shadow(@shadowA, @shadowB:X, ...){
// Multiple shadow solution from http://toekneestuck.com/blog/2012/05/15/less-css-arguments-variable/
@props: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`;
-webkit-box-shadow: @props;
-moz-box-shadow: @props;
box-shadow: @props;
}
// Transitions
.transition(@transition) {
-webkit-transition: @transition;
-moz-transition: @transition;
-o-transition: @transition;
transition: @transition;
}
.transition-delay(@transition-delay) {
-webkit-transition-delay: @transition-delay;
-moz-transition-delay: @transition-delay;
-o-transition-delay: @transition-delay;
transition-delay: @transition-delay;
}
// Transformations
.rotate(@degrees) {
-webkit-transform: rotate(@degrees);
-moz-transform: rotate(@degrees);
-ms-transform: rotate(@degrees);
-o-transform: rotate(@degrees);
transform: rotate(@degrees);
}
.scale(@ratio) {
-webkit-transform: scale(@ratio);
-moz-transform: scale(@ratio);
-ms-transform: scale(@ratio);
-o-transform: scale(@ratio);
transform: scale(@ratio);
}
.translate(@x, @y) {
-webkit-transform: translate(@x, @y);
-moz-transform: translate(@x, @y);
-ms-transform: translate(@x, @y);
-o-transform: translate(@x, @y);
transform: translate(@x, @y);
}
.skew(@x, @y) {
-webkit-transform: skew(@x, @y);
-moz-transform: skew(@x, @y);
-ms-transform: skewX(@x) skewY(@y); // See https://github.com/twitter/bootstrap/issues/4885
-o-transform: skew(@x, @y);
transform: skew(@x, @y);
}
.translate3d(@x, @y, @z) {
-webkit-transform: translate3d(@x, @y, @z);
-moz-transform: translate3d(@x, @y, @z);
-o-transform: translate3d(@x, @y, @z);
transform: translate3d(@x, @y, @z);
}
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden
// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples
.backface-visibility(@visibility){
-webkit-backface-visibility: @visibility;
-moz-backface-visibility: @visibility;
backface-visibility: @visibility;
}
// Background clipping
// Heads up: FF 3.6 and under need "padding" instead of "padding-box"
.background-clip(@clip) {
-webkit-background-clip: @clip;
-moz-background-clip: @clip;
background-clip: @clip;
}
// Background sizing
.background-size(@size){
-webkit-background-size: @size;
-moz-background-size: @size;
-o-background-size: @size;
background-size: @size;
}
// Box sizing
.box-sizing(@boxmodel) {
-webkit-box-sizing: @boxmodel;
-moz-box-sizing: @boxmodel;
box-sizing: @boxmodel;
}
// User select
// For selecting text on the page
.user-select(@select) {
-webkit-user-select: @select;
-moz-user-select: @select;
-ms-user-select: @select;
-o-user-select: @select;
user-select: @select;
}
// Resize anything
.resizable(@direction) {
resize: @direction; // Options: horizontal, vertical, both
overflow: auto; // Safari fix
}
// CSS3 Content Columns
.content-columns(@columnCount, @columnGap: @gridGutterWidth) {
-webkit-column-count: @columnCount;
-moz-column-count: @columnCount;
column-count: @columnCount;
-webkit-column-gap: @columnGap;
-moz-column-gap: @columnGap;
column-gap: @columnGap;
}
// Optional hyphenation
.hyphens(@mode: auto) {
word-wrap: break-word;
-webkit-hyphens: @mode;
-moz-hyphens: @mode;
-ms-hyphens: @mode;
-o-hyphens: @mode;
hyphens: @mode;
}
// Opacity
.opacity(@opacity) {
opacity: @opacity / 100;
filter: ~"alpha(opacity=@{opacity})";
}
// BACKGROUNDS
// --------------------------------------------------
// Add an alphatransparency value to any background or border color (via Elyse Holladay)
#translucent {
.background(@color: @white, @alpha: 1) {
background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
}
.border(@color: @white, @alpha: 1) {
border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
.background-clip(padding-box);
}
}
// Gradient Bar Colors for buttons and alerts
.gradientBar(@primaryColor, @secondaryColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) {
color: @textColor;
text-shadow: @textShadow;
#gradient > .vertical(@primaryColor, @secondaryColor);
border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%);
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%);
}
// Gradients
#gradient {
.horizontal(@startColor: #555, @endColor: #333) {
background-color: @endColor;
background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+
background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+
background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10
background-image: linear-gradient(to right, @startColor, @endColor); // Standard, IE10
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@startColor),argb(@endColor))); // IE9 and down
}
.vertical(@startColor: #555, @endColor: #333) {
background-color: mix(@startColor, @endColor, 60%);
background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+
background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10
background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10
background-repeat: repeat-x;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down
}
.directional(@startColor: #555, @endColor: #333, @deg: 45deg) {
background-color: @endColor;
background-repeat: repeat-x;
background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+
background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+
background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10
background-image: linear-gradient(@deg, @startColor, @endColor); // Standard, IE10
}
.vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) {
background-color: mix(@midColor, @endColor, 80%);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor));
background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor);
background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor);
background-repeat: no-repeat;
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback
}
.radial(@innerColor: #555, @outerColor: #333) {
background-color: @outerColor;
background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor));
background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor);
background-image: -moz-radial-gradient(circle, @innerColor, @outerColor);
background-image: -o-radial-gradient(circle, @innerColor, @outerColor);
background-repeat: no-repeat;
}
.striped(@color: #555, @angle: 45deg) {
background-color: @color;
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent));
background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
}
}
// Reset filters for IE
.reset-filter() {
filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
}
// COMPONENT MIXINS
// --------------------------------------------------
// Horizontal dividers
// -------------------------
// Dividers (basically an hr) within dropdowns and nav lists
.nav-divider(@top: #e5e5e5, @bottom: @white) {
// IE7 needs a set width since we gave a height. Restricting just
// to IE7 to keep the 1px left/right space in other browsers.
// It is unclear where IE is getting the extra space that we need
// to negative-margin away, but so it goes.
*width: 100%;
height: 1px;
margin: ((@baseLineHeight / 2) - 1) 1px; // 8px 1px
*margin: -5px 0 5px;
overflow: hidden;
background-color: @top;
border-bottom: 1px solid @bottom;
}
// Button backgrounds
// ------------------
.buttonBackground(@startColor, @endColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) {
// gradientBar will set the background to a pleasing blend of these, to support IE<=9
.gradientBar(@startColor, @endColor, @textColor, @textShadow);
*background-color: @endColor; /* Darken IE7 buttons by default so they stand out more given they won't have borders */
.reset-filter();
// in these cases the gradient won't cover the background, so we override
&:hover, &:active, &.active, &.disabled, &[disabled] {
color: @textColor;
background-color: @endColor;
*background-color: darken(@endColor, 5%);
}
// IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves
&:active,
&.active {
background-color: darken(@endColor, 10%) e("\9");
}
}
// Navbar vertical align
// -------------------------
// Vertically center elements in the navbar.
// Example: an element has a height of 30px, so write out `.navbarVerticalAlign(30px);` to calculate the appropriate top margin.
.navbarVerticalAlign(@elementHeight) {
margin-top: (@navbarHeight - @elementHeight) / 2;
}
// Grid System
// -----------
// Centered container element
.container-fixed() {
margin-right: auto;
margin-left: auto;
.clearfix();
}
// Table columns
.tableColumns(@columnSpan: 1) {
float: none; // undo default grid column styles
width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16; // 16 is total padding on left and right of table cells
margin-left: 0; // undo default grid column styles
}
// Make a Grid
// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior
.makeRow() {
margin-left: @gridGutterWidth * -1;
.clearfix();
}
.makeColumn(@columns: 1, @offset: 0) {
float: left;
margin-left: (@gridColumnWidth * @offset) + (@gridGutterWidth * (@offset - 1)) + (@gridGutterWidth * 2);
width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
}
// The Grid
#grid {
.core (@gridColumnWidth, @gridGutterWidth) {
.spanX (@index) when (@index > 0) {
(~".span@{index}") { .span(@index); }
.spanX(@index - 1);
}
.spanX (0) {}
.offsetX (@index) when (@index > 0) {
(~".offset@{index}") { .offset(@index); }
.offsetX(@index - 1);
}
.offsetX (0) {}
.offset (@columns) {
margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1));
}
.span (@columns) {
width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
}
.row {
margin-left: @gridGutterWidth * -1;
.clearfix();
}
[class*="span"] {
float: left;
min-height: 1px; // prevent collapsing columns
margin-left: @gridGutterWidth;
}
// Set the container width, and override it for fixed navbars in media queries
.container,
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container { .span(@gridColumns); }
// generate .spanX and .offsetX
.spanX (@gridColumns);
.offsetX (@gridColumns);
}
.fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) {
.spanX (@index) when (@index > 0) {
(~".span@{index}") { .span(@index); }
.spanX(@index - 1);
}
.spanX (0) {}
.offsetX (@index) when (@index > 0) {
(~'.offset@{index}') { .offset(@index); }
(~'.offset@{index}:first-child') { .offsetFirstChild(@index); }
.offsetX(@index - 1);
}
.offsetX (0) {}
.offset (@columns) {
margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth*2);
*margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + (@fluidGridGutterWidth*2) - (.5 / @gridRowWidth * 100 * 1%);
}
.offsetFirstChild (@columns) {
margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth);
*margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
}
.span (@columns) {
width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
*width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%);
}
.row-fluid {
width: 100%;
.clearfix();
[class*="span"] {
.input-block-level();
float: left;
margin-left: @fluidGridGutterWidth;
*margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
}
[class*="span"]:first-child {
margin-left: 0;
}
// generate .spanX and .offsetX
.spanX (@gridColumns);
.offsetX (@gridColumns);
}
}
.input(@gridColumnWidth, @gridGutterWidth) {
.spanX (@index) when (@index > 0) {
(~"input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index}") { .span(@index); }
.spanX(@index - 1);
}
.spanX (0) {}
.span(@columns) {
width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 14;
}
input,
textarea,
.uneditable-input {
margin-left: 0; // override margin-left from core grid system
}
// Space grid-sized controls properly if multiple per line
.controls-row [class*="span"] + [class*="span"] {
margin-left: @gridGutterWidth;
}
// generate .spanX
.spanX (@gridColumns);
}
}

View File

@ -0,0 +1,98 @@
//
// Modals
// --------------------------------------------------
// Recalculate z-index where appropriate,
// but only apply to elements within modal
.modal-open .modal {
.dropdown-menu { z-index: @zindexDropdown + @zindexModal; }
.dropdown.open { *z-index: @zindexDropdown + @zindexModal; }
.popover { z-index: @zindexPopover + @zindexModal; }
.tooltip { z-index: @zindexTooltip + @zindexModal; }
}
// Background
.modal-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: @zindexModalBackdrop;
background-color: @black;
// Fade for backdrop
&.fade { opacity: 0; }
}
.modal-backdrop,
.modal-backdrop.fade.in {
.opacity(80);
}
// Base modal
.modal {
position: fixed;
top: 50%;
left: 50%;
z-index: @zindexModal;
overflow: auto;
width: 560px;
margin: -250px 0 0 -280px;
background-color: @white;
border: 1px solid #999;
border: 1px solid rgba(0,0,0,.3);
*border: 1px solid #999; /* IE6-7 */
.border-radius(6px);
.box-shadow(0 3px 7px rgba(0,0,0,0.3));
.background-clip(padding-box);
&.fade {
.transition(e('opacity .3s linear, top .3s ease-out'));
top: -25%;
}
&.fade.in { top: 50%; }
}
.modal-header {
padding: 9px 15px;
border-bottom: 1px solid #eee;
// Close icon
.close { margin-top: 2px; }
// Heading
h3 {
margin: 0;
line-height: 30px;
}
}
// Body (where all modal content resides)
.modal-body {
overflow-y: auto;
max-height: 400px;
padding: 15px;
}
// Remove bottom margin if need be
.modal-form {
margin-bottom: 0;
}
// Footer (for actions)
.modal-footer {
padding: 14px 15px 15px;
margin-bottom: 0;
text-align: right; // right align buttons
background-color: #f5f5f5;
border-top: 1px solid #ddd;
.border-radius(0 0 6px 6px);
.box-shadow(inset 0 1px 0 @white);
.clearfix(); // clear it in case folks use .pull-* classes on buttons
// Properly space out buttons
.btn + .btn {
margin-left: 5px;
margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
}
// but override that for button groups
.btn-group .btn + .btn {
margin-left: -1px;
}
}

475
bootstrap/less/navbar.less Normal file
View File

@ -0,0 +1,475 @@
//
// Navbars (Redux)
// --------------------------------------------------
// COMMON STYLES
// -------------
// Base class and wrapper
.navbar {
overflow: visible;
margin-bottom: @baseLineHeight;
color: @navbarText;
// Fix for IE7's bad z-indexing so dropdowns don't appear below content that follows the navbar
*position: relative;
*z-index: 2;
}
// Inner for background effects
// Gradient is applied to its own element because overflow visible is not honored by IE when filter is present
.navbar-inner {
min-height: @navbarHeight;
padding-left: 20px;
padding-right: 20px;
#gradient > .vertical(@navbarBackgroundHighlight, @navbarBackground);
border: 1px solid @navbarBorder;
.border-radius(4px);
.box-shadow(0 1px 4px rgba(0,0,0,.065));
// Prevent floats from breaking the navbar
.clearfix();
}
// Set width to auto for default container
// We then reset it for fixed navbars in the #gridSystem mixin
.navbar .container {
width: auto;
}
// Override the default collapsed state
.nav-collapse.collapse {
height: auto;
}
// Brand: website or project name
// -------------------------
.navbar .brand {
float: left;
display: block;
// Vertically center the text given @navbarHeight
padding: ((@navbarHeight - @baseLineHeight) / 2) 20px ((@navbarHeight - @baseLineHeight) / 2);
margin-left: -20px; // negative indent to left-align the text down the page
font-size: 20px;
font-weight: 200;
color: @navbarBrandColor;
text-shadow: 0 1px 0 @navbarBackgroundHighlight;
&:hover {
text-decoration: none;
}
}
// Plain text in topbar
// -------------------------
.navbar-text {
margin-bottom: 0;
line-height: @navbarHeight;
}
// Janky solution for now to account for links outside the .nav
// -------------------------
.navbar-link {
color: @navbarLinkColor;
&:hover {
color: @navbarLinkColorHover;
}
}
// Dividers in navbar
// -------------------------
.navbar .divider-vertical {
height: @navbarHeight;
margin: 0 9px;
border-left: 1px solid @navbarBackground;
border-right: 1px solid @navbarBackgroundHighlight;
}
// Buttons in navbar
// -------------------------
.navbar .btn,
.navbar .btn-group {
.navbarVerticalAlign(30px); // Vertically center in navbar
}
.navbar .btn-group .btn,
.navbar .input-prepend .btn,
.navbar .input-append .btn {
margin-top: 0; // then undo the margin here so we don't accidentally double it
}
// Navbar forms
// -------------------------
.navbar-form {
margin-bottom: 0; // remove default bottom margin
.clearfix();
input,
select,
.radio,
.checkbox {
.navbarVerticalAlign(30px); // Vertically center in navbar
}
input,
select,
.btn {
display: inline-block;
margin-bottom: 0;
}
input[type="image"],
input[type="checkbox"],
input[type="radio"] {
margin-top: 3px;
}
.input-append,
.input-prepend {
margin-top: 6px;
white-space: nowrap; // preven two items from separating within a .navbar-form that has .pull-left
input {
margin-top: 0; // remove the margin on top since it's on the parent
}
}
}
// Navbar search
// -------------------------
.navbar-search {
position: relative;
float: left;
.navbarVerticalAlign(30px); // Vertically center in navbar
margin-bottom: 0;
.search-query {
margin-bottom: 0;
padding: 4px 14px;
#font > .sans-serif(13px, normal, 1);
.border-radius(15px); // redeclare because of specificity of the type attribute
}
}
// Static navbar
// -------------------------
.navbar-static-top {
position: static;
width: 100%;
margin-bottom: 0; // remove 18px margin for default navbar
.navbar-inner {
.border-radius(0);
}
}
// Fixed navbar
// -------------------------
// Shared (top/bottom) styles
.navbar-fixed-top,
.navbar-fixed-bottom {
position: fixed;
right: 0;
left: 0;
z-index: @zindexFixedNavbar;
margin-bottom: 0; // remove 18px margin for default navbar
}
.navbar-fixed-top .navbar-inner,
.navbar-static-top .navbar-inner {
border-width: 0 0 1px;
}
.navbar-fixed-bottom .navbar-inner {
border-width: 1px 0 0;
}
.navbar-fixed-top .navbar-inner,
.navbar-fixed-bottom .navbar-inner {
padding-left: 0;
padding-right: 0;
.border-radius(0);
}
// Reset container width
// Required here as we reset the width earlier on and the grid mixins don't override early enough
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
#grid > .core > .span(@gridColumns);
}
// Fixed to top
.navbar-fixed-top {
top: 0;
}
.navbar-fixed-top,
.navbar-static-top {
.navbar-inner {
.box-shadow(inset 0 -1px 0 rgba(0,0,0,.1), 0 1px 10px rgba(0,0,0,.1));
}
}
// Fixed to bottom
.navbar-fixed-bottom {
bottom: 0;
.navbar-inner {
.box-shadow(inset 0 1px 0 rgba(0,0,0,.1), 0 -1px 10px rgba(0,0,0,.1));
}
}
// NAVIGATION
// ----------
.navbar .nav {
position: relative;
left: 0;
display: block;
float: left;
margin: 0 10px 0 0;
}
.navbar .nav.pull-right {
float: right; // redeclare due to specificity
margin-right: 0; // remove margin on float right nav
}
.navbar .nav > li {
float: left;
}
// Links
.navbar .nav > li > a {
float: none;
// Vertically center the text given @navbarHeight
padding: ((@navbarHeight - @baseLineHeight) / 2) 15px ((@navbarHeight - @baseLineHeight) / 2);
color: @navbarLinkColor;
text-decoration: none;
text-shadow: 0 1px 0 @navbarBackgroundHighlight;
}
.navbar .nav .dropdown-toggle .caret {
margin-top: 8px;
}
// Hover
.navbar .nav > li > a:focus,
.navbar .nav > li > a:hover {
background-color: @navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover from .active
color: @navbarLinkColorHover;
text-decoration: none;
}
// Active nav items
.navbar .nav > .active > a,
.navbar .nav > .active > a:hover,
.navbar .nav > .active > a:focus {
color: @navbarLinkColorActive;
text-decoration: none;
background-color: @navbarLinkBackgroundActive;
.box-shadow(inset 0 3px 8px rgba(0,0,0,.125));
}
// Navbar button for toggling navbar items in responsive layouts
// These definitions need to come after '.navbar .btn'
.navbar .btn-navbar {
display: none;
float: right;
padding: 7px 10px;
margin-left: 5px;
margin-right: 5px;
.buttonBackground(darken(@navbarBackgroundHighlight, 5%), darken(@navbarBackground, 5%));
.box-shadow(inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075));
}
.navbar .btn-navbar .icon-bar {
display: block;
width: 18px;
height: 2px;
background-color: #f5f5f5;
.border-radius(1px);
.box-shadow(0 1px 0 rgba(0,0,0,.25));
}
.btn-navbar .icon-bar + .icon-bar {
margin-top: 3px;
}
// Dropdown menus
// --------------
// Menu position and menu carets
.navbar .nav > li > .dropdown-menu {
&:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: @dropdownBorder;
position: absolute;
top: -7px;
left: 9px;
}
&:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid @dropdownBackground;
position: absolute;
top: -6px;
left: 10px;
}
}
// Menu position and menu caret support for dropups via extra dropup class
.navbar-fixed-bottom .nav > li > .dropdown-menu {
&:before {
border-top: 7px solid #ccc;
border-top-color: @dropdownBorder;
border-bottom: 0;
bottom: -7px;
top: auto;
}
&:after {
border-top: 6px solid @dropdownBackground;
border-bottom: 0;
bottom: -6px;
top: auto;
}
}
// Remove background color from open dropdown
.navbar .nav li.dropdown.open > .dropdown-toggle,
.navbar .nav li.dropdown.active > .dropdown-toggle,
.navbar .nav li.dropdown.open.active > .dropdown-toggle {
background-color: @navbarLinkBackgroundActive;
color: @navbarLinkColorActive;
}
.navbar .nav li.dropdown > .dropdown-toggle .caret {
border-top-color: @navbarLinkColor;
border-bottom-color: @navbarLinkColor;
}
.navbar .nav li.dropdown.open > .dropdown-toggle .caret,
.navbar .nav li.dropdown.active > .dropdown-toggle .caret,
.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {
border-top-color: @navbarLinkColorActive;
border-bottom-color: @navbarLinkColorActive;
}
// Right aligned menus need alt position
.navbar .pull-right > li > .dropdown-menu,
.navbar .nav > li > .dropdown-menu.pull-right {
left: auto;
right: 0;
&:before {
left: auto;
right: 12px;
}
&:after {
left: auto;
right: 13px;
}
.dropdown-menu {
left: auto;
right: 100%;
margin-left: 0;
margin-right: -1px;
.border-radius(6px 0 6px 6px);
}
}
// Inverted navbar
// -------------------------
.navbar-inverse {
color: @navbarInverseText;
.navbar-inner {
#gradient > .vertical(@navbarInverseBackgroundHighlight, @navbarInverseBackground);
border-color: @navbarInverseBorder;
}
.brand,
.nav > li > a {
color: @navbarInverseLinkColor;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
&:hover {
color: @navbarInverseLinkColorHover;
}
}
.nav > li > a:focus,
.nav > li > a:hover {
background-color: @navbarInverseLinkBackgroundHover;
color: @navbarInverseLinkColorHover;
}
.nav .active > a,
.nav .active > a:hover,
.nav .active > a:focus {
color: @navbarInverseLinkColorActive;
background-color: @navbarInverseLinkBackgroundActive;
}
// Inline text links
.navbar-link {
color: @navbarInverseLinkColor;
&:hover {
color: @navbarInverseLinkColorHover;
}
}
// Dividers in navbar
.divider-vertical {
border-left-color: @navbarInverseBackground;
border-right-color: @navbarInverseBackgroundHighlight;
}
// Dropdowns
.nav li.dropdown.open > .dropdown-toggle,
.nav li.dropdown.active > .dropdown-toggle,
.nav li.dropdown.open.active > .dropdown-toggle {
background-color: @navbarInverseLinkBackgroundActive;
color: @navbarInverseLinkColorActive;
}
.nav li.dropdown > .dropdown-toggle .caret {
border-top-color: @navbarInverseLinkColor;
border-bottom-color: @navbarInverseLinkColor;
}
.nav li.dropdown.open > .dropdown-toggle .caret,
.nav li.dropdown.active > .dropdown-toggle .caret,
.nav li.dropdown.open.active > .dropdown-toggle .caret {
border-top-color: @navbarInverseLinkColorActive;
border-bottom-color: @navbarInverseLinkColorActive;
}
// Navbar search
.navbar-search {
.search-query {
color: @white;
background-color: @navbarInverseSearchBackground;
border-color: @navbarInverseSearchBorder;
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15));
.transition(none);
.placeholder(@navbarInverseSearchPlaceholderColor);
// Focus states (we use .focused since IE7-8 and down doesn't support :focus)
&:focus,
&.focused {
padding: 5px 15px;
color: @grayDark;
text-shadow: 0 1px 0 @white;
background-color: @navbarInverseSearchBackgroundFocus;
border: 0;
.box-shadow(0 0 3px rgba(0,0,0,.15));
outline: 0;
}
}
}
// Navbar collapse button
.btn-navbar {
.buttonBackground(darken(@navbarInverseBackgroundHighlight, 5%), darken(@navbarInverseBackground, 5%));
}
}

384
bootstrap/less/navs.less Normal file
View File

@ -0,0 +1,384 @@
//
// Navs
// --------------------------------------------------
// BASE CLASS
// ----------
.nav {
margin-left: 0;
margin-bottom: @baseLineHeight;
list-style: none;
}
// Make links block level
.nav > li > a {
display: block;
}
.nav > li > a:hover {
text-decoration: none;
background-color: @grayLighter;
}
// Redeclare pull classes because of specifity
.nav > .pull-right {
float: right;
}
// Nav headers (for dropdowns and lists)
.nav-header {
display: block;
padding: 3px 15px;
font-size: 11px;
font-weight: bold;
line-height: @baseLineHeight;
color: @grayLight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
text-transform: uppercase;
}
// Space them out when they follow another list item (link)
.nav li + .nav-header {
margin-top: 9px;
}
// NAV LIST
// --------
.nav-list {
padding-left: 15px;
padding-right: 15px;
margin-bottom: 0;
}
.nav-list > li > a,
.nav-list .nav-header {
margin-left: -15px;
margin-right: -15px;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
}
.nav-list > li > a {
padding: 3px 15px;
}
.nav-list > .active > a,
.nav-list > .active > a:hover {
color: @white;
text-shadow: 0 -1px 0 rgba(0,0,0,.2);
background-color: @linkColor;
}
.nav-list [class^="icon-"] {
margin-right: 2px;
}
// Dividers (basically an hr) within the dropdown
.nav-list .divider {
.nav-divider();
}
// TABS AND PILLS
// -------------
// Common styles
.nav-tabs,
.nav-pills {
.clearfix();
}
.nav-tabs > li,
.nav-pills > li {
float: left;
}
.nav-tabs > li > a,
.nav-pills > li > a {
padding-right: 12px;
padding-left: 12px;
margin-right: 2px;
line-height: 14px; // keeps the overall height an even number
}
// TABS
// ----
// Give the tabs something to sit on
.nav-tabs {
border-bottom: 1px solid #ddd;
}
// Make the list-items overlay the bottom border
.nav-tabs > li {
margin-bottom: -1px;
}
// Actual tabs (as links)
.nav-tabs > li > a {
padding-top: 8px;
padding-bottom: 8px;
line-height: @baseLineHeight;
border: 1px solid transparent;
.border-radius(4px 4px 0 0);
&:hover {
border-color: @grayLighter @grayLighter #ddd;
}
}
// Active state, and it's :hover to override normal :hover
.nav-tabs > .active > a,
.nav-tabs > .active > a:hover {
color: @gray;
background-color: @white;
border: 1px solid #ddd;
border-bottom-color: transparent;
cursor: default;
}
// PILLS
// -----
// Links rendered as pills
.nav-pills > li > a {
padding-top: 8px;
padding-bottom: 8px;
margin-top: 2px;
margin-bottom: 2px;
.border-radius(5px);
}
// Active state
.nav-pills > .active > a,
.nav-pills > .active > a:hover {
color: @white;
background-color: @linkColor;
}
// STACKED NAV
// -----------
// Stacked tabs and pills
.nav-stacked > li {
float: none;
}
.nav-stacked > li > a {
margin-right: 0; // no need for the gap between nav items
}
// Tabs
.nav-tabs.nav-stacked {
border-bottom: 0;
}
.nav-tabs.nav-stacked > li > a {
border: 1px solid #ddd;
.border-radius(0);
}
.nav-tabs.nav-stacked > li:first-child > a {
.border-top-radius(4px);
}
.nav-tabs.nav-stacked > li:last-child > a {
.border-bottom-radius(4px);
}
.nav-tabs.nav-stacked > li > a:hover {
border-color: #ddd;
z-index: 2;
}
// Pills
.nav-pills.nav-stacked > li > a {
margin-bottom: 3px;
}
.nav-pills.nav-stacked > li:last-child > a {
margin-bottom: 1px; // decrease margin to match sizing of stacked tabs
}
// DROPDOWNS
// ---------
.nav-tabs .dropdown-menu {
.border-radius(0 0 6px 6px); // remove the top rounded corners here since there is a hard edge above the menu
}
.nav-pills .dropdown-menu {
.border-radius(6px); // make rounded corners match the pills
}
// Default dropdown links
// -------------------------
// Make carets use linkColor to start
.nav .dropdown-toggle .caret {
border-top-color: @linkColor;
border-bottom-color: @linkColor;
margin-top: 6px;
}
.nav .dropdown-toggle:hover .caret {
border-top-color: @linkColorHover;
border-bottom-color: @linkColorHover;
}
/* move down carets for tabs */
.nav-tabs .dropdown-toggle .caret {
margin-top: 8px;
}
// Active dropdown links
// -------------------------
.nav .active .dropdown-toggle .caret {
border-top-color: #fff;
border-bottom-color: #fff;
}
.nav-tabs .active .dropdown-toggle .caret {
border-top-color: @gray;
border-bottom-color: @gray;
}
// Active:hover dropdown links
// -------------------------
.nav > .dropdown.active > a:hover {
cursor: pointer;
}
// Open dropdowns
// -------------------------
.nav-tabs .open .dropdown-toggle,
.nav-pills .open .dropdown-toggle,
.nav > li.dropdown.open.active > a:hover {
color: @white;
background-color: @grayLight;
border-color: @grayLight;
}
.nav li.dropdown.open .caret,
.nav li.dropdown.open.active .caret,
.nav li.dropdown.open a:hover .caret {
border-top-color: @white;
border-bottom-color: @white;
.opacity(100);
}
// Dropdowns in stacked tabs
.tabs-stacked .open > a:hover {
border-color: @grayLight;
}
// TABBABLE
// --------
// COMMON STYLES
// -------------
// Clear any floats
.tabbable {
.clearfix();
}
.tab-content {
overflow: auto; // prevent content from running below tabs
}
// Remove border on bottom, left, right
.tabs-below > .nav-tabs,
.tabs-right > .nav-tabs,
.tabs-left > .nav-tabs {
border-bottom: 0;
}
// Show/hide tabbable areas
.tab-content > .tab-pane,
.pill-content > .pill-pane {
display: none;
}
.tab-content > .active,
.pill-content > .active {
display: block;
}
// BOTTOM
// ------
.tabs-below > .nav-tabs {
border-top: 1px solid #ddd;
}
.tabs-below > .nav-tabs > li {
margin-top: -1px;
margin-bottom: 0;
}
.tabs-below > .nav-tabs > li > a {
.border-radius(0 0 4px 4px);
&:hover {
border-bottom-color: transparent;
border-top-color: #ddd;
}
}
.tabs-below > .nav-tabs > .active > a,
.tabs-below > .nav-tabs > .active > a:hover {
border-color: transparent #ddd #ddd #ddd;
}
// LEFT & RIGHT
// ------------
// Common styles
.tabs-left > .nav-tabs > li,
.tabs-right > .nav-tabs > li {
float: none;
}
.tabs-left > .nav-tabs > li > a,
.tabs-right > .nav-tabs > li > a {
min-width: 74px;
margin-right: 0;
margin-bottom: 3px;
}
// Tabs on the left
.tabs-left > .nav-tabs {
float: left;
margin-right: 19px;
border-right: 1px solid #ddd;
}
.tabs-left > .nav-tabs > li > a {
margin-right: -1px;
.border-radius(4px 0 0 4px);
}
.tabs-left > .nav-tabs > li > a:hover {
border-color: @grayLighter #ddd @grayLighter @grayLighter;
}
.tabs-left > .nav-tabs .active > a,
.tabs-left > .nav-tabs .active > a:hover {
border-color: #ddd transparent #ddd #ddd;
*border-right-color: @white;
}
// Tabs on the right
.tabs-right > .nav-tabs {
float: right;
margin-left: 19px;
border-left: 1px solid #ddd;
}
.tabs-right > .nav-tabs > li > a {
margin-left: -1px;
.border-radius(0 4px 4px 0);
}
.tabs-right > .nav-tabs > li > a:hover {
border-color: @grayLighter @grayLighter @grayLighter #ddd;
}
.tabs-right > .nav-tabs .active > a,
.tabs-right > .nav-tabs .active > a:hover {
border-color: #ddd #ddd #ddd transparent;
*border-left-color: @white;
}
// DISABLED STATES
// ---------------
// Gray out text
.nav > .disabled > a {
color: @grayLight;
}
// Nuke hover effects
.nav > .disabled > a:hover {
text-decoration: none;
background-color: transparent;
cursor: default;
}

40
bootstrap/less/pager.less Normal file
View File

@ -0,0 +1,40 @@
//
// Pager pagination
// --------------------------------------------------
.pager {
margin: @baseLineHeight 0;
list-style: none;
text-align: center;
.clearfix();
}
.pager li {
display: inline;
}
.pager a,
.pager span {
display: inline-block;
padding: 5px 14px;
background-color: #fff;
border: 1px solid #ddd;
.border-radius(15px);
}
.pager a:hover {
text-decoration: none;
background-color: #f5f5f5;
}
.pager .next a,
.pager .next span {
float: right;
}
.pager .previous a {
float: left;
}
.pager .disabled a,
.pager .disabled a:hover,
.pager .disabled span {
color: @grayLight;
background-color: #fff;
cursor: default;
}

View File

@ -0,0 +1,64 @@
//
// Pagination (multiple pages)
// --------------------------------------------------
.pagination {
height: @baseLineHeight * 2;
margin: @baseLineHeight 0;
}
.pagination ul {
display: inline-block;
.ie7-inline-block();
margin-left: 0;
margin-bottom: 0;
.border-radius(3px);
.box-shadow(0 1px 2px rgba(0,0,0,.05));
}
.pagination ul > li {
display: inline;
}
.pagination ul > li > a,
.pagination ul > li > span {
float: left;
padding: 0 14px;
line-height: (@baseLineHeight * 2) - 2;
text-decoration: none;
background-color: @paginationBackground;
border: 1px solid @paginationBorder;
border-left-width: 0;
}
.pagination ul > li > a:hover,
.pagination ul > .active > a,
.pagination ul > .active > span {
background-color: #f5f5f5;
}
.pagination ul > .active > a,
.pagination ul > .active > span {
color: @grayLight;
cursor: default;
}
.pagination ul > .disabled > span,
.pagination ul > .disabled > a,
.pagination ul > .disabled > a:hover {
color: @grayLight;
background-color: transparent;
cursor: default;
}
.pagination ul > li:first-child > a,
.pagination ul > li:first-child > span {
border-left-width: 1px;
.border-radius(3px 0 0 3px);
}
.pagination ul > li:last-child > a,
.pagination ul > li:last-child > span {
.border-radius(0 3px 3px 0);
}
// Centered
.pagination-centered {
text-align: center;
}
.pagination-right {
text-align: right;
}

View File

@ -0,0 +1,117 @@
//
// Popovers
// --------------------------------------------------
.popover {
position: absolute;
top: 0;
left: 0;
z-index: @zindexPopover;
display: none;
width: 236px;
padding: 1px;
background-color: @popoverBackground;
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.2);
.border-radius(6px);
.box-shadow(0 5px 10px rgba(0,0,0,.2));
// Offset the popover to account for the popover arrow
&.top { margin-bottom: 10px; }
&.right { margin-left: 10px; }
&.bottom { margin-top: 10px; }
&.left { margin-right: 10px; }
}
.popover-title {
margin: 0; // reset heading margin
padding: 8px 14px;
font-size: 14px;
font-weight: normal;
line-height: 18px;
background-color: @popoverTitleBackground;
border-bottom: 1px solid darken(@popoverTitleBackground, 5%);
.border-radius(5px 5px 0 0);
}
.popover-content {
padding: 9px 14px;
p, ul, ol {
margin-bottom: 0;
}
}
// Arrows
.popover .arrow,
.popover .arrow:after {
position: absolute;
display: inline-block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.popover .arrow:after {
content: "";
z-index: -1;
}
.popover {
&.top .arrow {
bottom: -@popoverArrowWidth;
left: 50%;
margin-left: -@popoverArrowWidth;
border-width: @popoverArrowWidth @popoverArrowWidth 0;
border-top-color: @popoverArrowColor;
&:after {
border-width: @popoverArrowOuterWidth @popoverArrowOuterWidth 0;
border-top-color: @popoverArrowOuterColor;
bottom: -1px;
left: -@popoverArrowOuterWidth;
}
}
&.right .arrow {
top: 50%;
left: -@popoverArrowWidth;
margin-top: -@popoverArrowWidth;
border-width: @popoverArrowWidth @popoverArrowWidth @popoverArrowWidth 0;
border-right-color: @popoverArrowColor;
&:after {
border-width: @popoverArrowOuterWidth @popoverArrowOuterWidth @popoverArrowOuterWidth 0;
border-right-color: @popoverArrowOuterColor;
bottom: -@popoverArrowOuterWidth;
left: -1px;
}
}
&.bottom .arrow {
top: -@popoverArrowWidth;
left: 50%;
margin-left: -@popoverArrowWidth;
border-width: 0 @popoverArrowWidth @popoverArrowWidth;
border-bottom-color: @popoverArrowColor;
&:after {
border-width: 0 @popoverArrowOuterWidth @popoverArrowOuterWidth;
border-bottom-color: @popoverArrowOuterColor;
top: -1px;
left: -@popoverArrowOuterWidth;
}
}
&.left .arrow {
top: 50%;
right: -@popoverArrowWidth;
margin-top: -@popoverArrowWidth;
border-width: @popoverArrowWidth 0 @popoverArrowWidth @popoverArrowWidth;
border-left-color: @popoverArrowColor;
&:after {
border-width: @popoverArrowOuterWidth 0 @popoverArrowOuterWidth @popoverArrowOuterWidth;
border-left-color: @popoverArrowOuterColor;
bottom: -@popoverArrowOuterWidth;
right: -1px;
}
}
}

View File

@ -0,0 +1,122 @@
//
// Progress bars
// --------------------------------------------------
// ANIMATIONS
// ----------
// Webkit
@-webkit-keyframes progress-bar-stripes {
from { background-position: 40px 0; }
to { background-position: 0 0; }
}
// Firefox
@-moz-keyframes progress-bar-stripes {
from { background-position: 40px 0; }
to { background-position: 0 0; }
}
// IE9
@-ms-keyframes progress-bar-stripes {
from { background-position: 40px 0; }
to { background-position: 0 0; }
}
// Opera
@-o-keyframes progress-bar-stripes {
from { background-position: 0 0; }
to { background-position: 40px 0; }
}
// Spec
@keyframes progress-bar-stripes {
from { background-position: 40px 0; }
to { background-position: 0 0; }
}
// THE BARS
// --------
// Outer container
.progress {
overflow: hidden;
height: @baseLineHeight;
margin-bottom: @baseLineHeight;
#gradient > .vertical(#f5f5f5, #f9f9f9);
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
.border-radius(4px);
}
// Bar of progress
.progress .bar {
width: 0%;
height: 100%;
color: @white;
float: left;
font-size: 12px;
text-align: center;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
#gradient > .vertical(#149bdf, #0480be);
.box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
.box-sizing(border-box);
.transition(width .6s ease);
}
.progress .bar + .bar {
.box-shadow(inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15));
}
// Striped bars
.progress-striped .bar {
#gradient > .striped(#149bdf);
.background-size(40px 40px);
}
// Call animation for the active one
.progress.active .bar {
-webkit-animation: progress-bar-stripes 2s linear infinite;
-moz-animation: progress-bar-stripes 2s linear infinite;
-ms-animation: progress-bar-stripes 2s linear infinite;
-o-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
// COLORS
// ------
// Danger (red)
.progress-danger .bar, .progress .bar-danger {
#gradient > .vertical(#ee5f5b, #c43c35);
}
.progress-danger.progress-striped .bar, .progress-striped .bar-danger {
#gradient > .striped(#ee5f5b);
}
// Success (green)
.progress-success .bar, .progress .bar-success {
#gradient > .vertical(#62c462, #57a957);
}
.progress-success.progress-striped .bar, .progress-striped .bar-success {
#gradient > .striped(#62c462);
}
// Info (teal)
.progress-info .bar, .progress .bar-info {
#gradient > .vertical(#5bc0de, #339bb9);
}
.progress-info.progress-striped .bar, .progress-striped .bar-info {
#gradient > .striped(#5bc0de);
}
// Warning (orange)
.progress-warning .bar, .progress .bar-warning {
#gradient > .vertical(lighten(@orange, 15%), @orange);
}
.progress-warning.progress-striped .bar, .progress-striped .bar-warning {
#gradient > .striped(lighten(@orange, 15%));
}

137
bootstrap/less/reset.less Normal file
View File

@ -0,0 +1,137 @@
//
// Modals
// Adapted from http://github.com/necolas/normalize.css
// --------------------------------------------------
// Display in IE6-9 and FF3
// -------------------------
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section {
display: block;
}
// Display block in IE6-9 and FF3
// -------------------------
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
// Prevents modern browsers from displaying 'audio' without controls
// -------------------------
audio:not([controls]) {
display: none;
}
// Base settings
// -------------------------
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
// Focus states
a:focus {
.tab-focus();
}
// Hover & Active
a:hover,
a:active {
outline: 0;
}
// Prevents sub and sup affecting line-height in all browsers
// -------------------------
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
// Img border in a's and image quality
// -------------------------
img {
/* Responsive images (ensure images don't scale beyond their parents) */
max-width: 100%; /* Part 1: Set a maxium relative to the parent */
width: auto\9; /* IE7-8 need help adjusting responsive images */
height: auto; /* Part 2: Scale the height according to the width, otherwise you get stretching */
vertical-align: middle;
border: 0;
-ms-interpolation-mode: bicubic;
}
// Prevent max-width from affecting Google Maps
#map_canvas img {
max-width: none;
}
// Forms
// -------------------------
// Font size in all browsers, margin changes, misc consistency
button,
input,
select,
textarea {
margin: 0;
font-size: 100%;
vertical-align: middle;
}
button,
input {
*overflow: visible; // Inner spacing ie IE6/7
line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
}
button::-moz-focus-inner,
input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
padding: 0;
border: 0;
}
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer; // Cursors on all buttons applied consistently
-webkit-appearance: button; // Style clickable inputs in iOS
}
input[type="search"] { // Appearance in Safari/Chrome
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
-webkit-appearance: textfield;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
}
textarea {
overflow: auto; // Remove vertical scrollbar in IE6-9
vertical-align: top; // Readability and alignment cross-browser
}

View File

@ -0,0 +1,28 @@
//
// Responsive: Large desktop and up
// --------------------------------------------------
@media (min-width: 1200px) {
// Fixed grid
#grid > .core(@gridColumnWidth1200, @gridGutterWidth1200);
// Fluid grid
#grid > .fluid(@fluidGridColumnWidth1200, @fluidGridGutterWidth1200);
// Input grid
#grid > .input(@gridColumnWidth1200, @gridGutterWidth1200);
// Thumbnails
.thumbnails {
margin-left: -@gridGutterWidth1200;
}
.thumbnails > li {
margin-left: @gridGutterWidth1200;
}
.row-fluid .thumbnails {
margin-left: 0;
}
}

View File

@ -0,0 +1,174 @@
//
// Responsive: Landscape phone to desktop/tablet
// --------------------------------------------------
@media (max-width: 767px) {
// Padding to set content in a bit
body {
padding-left: 20px;
padding-right: 20px;
}
// Negative indent the now static "fixed" navbar
.navbar-fixed-top,
.navbar-fixed-bottom,
.navbar-static-top {
margin-left: -20px;
margin-right: -20px;
}
// Remove padding on container given explicit padding set on body
.container-fluid {
padding: 0;
}
// TYPOGRAPHY
// ----------
// Reset horizontal dl
.dl-horizontal {
dt {
float: none;
clear: none;
width: auto;
text-align: left;
}
dd {
margin-left: 0;
}
}
// GRID & CONTAINERS
// -----------------
// Remove width from containers
.container {
width: auto;
}
// Fluid rows
.row-fluid {
width: 100%;
}
// Undo negative margin on rows and thumbnails
.row,
.thumbnails {
margin-left: 0;
}
.thumbnails > li {
float: none;
margin-left: 0; // Reset the default margin for all li elements when no .span* classes are present
}
// Make all grid-sized elements block level again
[class*="span"],
.row-fluid [class*="span"] {
float: none;
display: block;
width: 100%;
margin-left: 0;
.box-sizing(border-box);
}
.span12,
.row-fluid .span12 {
width: 100%;
.box-sizing(border-box);
}
// FORM FIELDS
// -----------
// Make span* classes full width
.input-large,
.input-xlarge,
.input-xxlarge,
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
.input-block-level();
}
// But don't let it screw up prepend/append inputs
.input-prepend input,
.input-append input,
.input-prepend input[class*="span"],
.input-append input[class*="span"] {
display: inline-block; // redeclare so they don't wrap to new lines
width: auto;
}
.controls-row [class*="span"] + [class*="span"] {
margin-left: 0;
}
// Modals
.modal {
position: fixed;
top: 20px;
left: 20px;
right: 20px;
width: auto;
margin: 0;
&.fade.in { top: auto; }
}
}
// UP TO LANDSCAPE PHONE
// ---------------------
@media (max-width: 480px) {
// Smooth out the collapsing/expanding nav
.nav-collapse {
-webkit-transform: translate3d(0, 0, 0); // activate the GPU
}
// Block level the page header small tag for readability
.page-header h1 small {
display: block;
line-height: @baseLineHeight;
}
// Update checkboxes for iOS
input[type="checkbox"],
input[type="radio"] {
border: 1px solid #ccc;
}
// Remove the horizontal form styles
.form-horizontal {
.control-label {
float: none;
width: auto;
padding-top: 0;
text-align: left;
}
// Move over all input controls and content
.controls {
margin-left: 0;
}
// Move the options list down to align with labels
.control-list {
padding-top: 0; // has to be padding because margin collaspes
}
// Move over buttons in .form-actions to align with .controls
.form-actions {
padding-left: 10px;
padding-right: 10px;
}
}
// Modals
.modal {
top: 10px;
left: 10px;
right: 10px;
}
.modal-header .close {
padding: 10px;
margin: -10px;
}
// Carousel
.carousel-caption {
position: static;
}
}

View File

@ -0,0 +1,19 @@
//
// Responsive: Tablet to desktop
// --------------------------------------------------
@media (min-width: 768px) and (max-width: 979px) {
// Fixed grid
#grid > .core(@gridColumnWidth768, @gridGutterWidth768);
// Fluid grid
#grid > .fluid(@fluidGridColumnWidth768, @fluidGridGutterWidth768);
// Input grid
#grid > .input(@gridColumnWidth768, @gridGutterWidth768);
// No need to reset .thumbnails here since it's the same @gridGutterWidth
}

View File

@ -0,0 +1,177 @@
//
// Responsive: Navbar
// --------------------------------------------------
// TABLETS AND BELOW
// -----------------
@media (max-width: @navbarCollapseWidth) {
// UNFIX THE TOPBAR
// ----------------
// Remove any padding from the body
body {
padding-top: 0;
}
// Unfix the navbars
.navbar-fixed-top,
.navbar-fixed-bottom {
position: static;
}
.navbar-fixed-top {
margin-bottom: @baseLineHeight;
}
.navbar-fixed-bottom {
margin-top: @baseLineHeight;
}
.navbar-fixed-top .navbar-inner,
.navbar-fixed-bottom .navbar-inner {
padding: 5px;
}
.navbar .container {
width: auto;
padding: 0;
}
// Account for brand name
.navbar .brand {
padding-left: 10px;
padding-right: 10px;
margin: 0 0 0 -5px;
}
// COLLAPSIBLE NAVBAR
// ------------------
// Nav collapse clears brand
.nav-collapse {
clear: both;
}
// Block-level the nav
.nav-collapse .nav {
float: none;
margin: 0 0 (@baseLineHeight / 2);
}
.nav-collapse .nav > li {
float: none;
}
.nav-collapse .nav > li > a {
margin-bottom: 2px;
}
.nav-collapse .nav > .divider-vertical {
display: none;
}
.nav-collapse .nav .nav-header {
color: @navbarText;
text-shadow: none;
}
// Nav and dropdown links in navbar
.nav-collapse .nav > li > a,
.nav-collapse .dropdown-menu a {
padding: 9px 15px;
font-weight: bold;
color: @navbarLinkColor;
.border-radius(3px);
}
// Buttons
.nav-collapse .btn {
padding: 4px 10px 4px;
font-weight: normal;
.border-radius(4px);
}
.nav-collapse .dropdown-menu li + li a {
margin-bottom: 2px;
}
.nav-collapse .nav > li > a:hover,
.nav-collapse .dropdown-menu a:hover {
background-color: @navbarBackground;
}
.navbar-inverse .nav-collapse .nav > li > a:hover,
.navbar-inverse .nav-collapse .dropdown-menu a:hover {
background-color: @navbarInverseBackground;
}
// Buttons in the navbar
.nav-collapse.in .btn-group {
margin-top: 5px;
padding: 0;
}
// Dropdowns in the navbar
.nav-collapse .dropdown-menu {
position: static;
top: auto;
left: auto;
float: none;
display: block;
max-width: none;
margin: 0 15px;
padding: 0;
background-color: transparent;
border: none;
.border-radius(0);
.box-shadow(none);
}
.nav-collapse .dropdown-menu:before,
.nav-collapse .dropdown-menu:after {
display: none;
}
.nav-collapse .dropdown-menu .divider {
display: none;
}
.nav-collapse .nav > li > .dropdown-menu {
&:before,
&:after {
display: none;
}
}
// Forms in navbar
.nav-collapse .navbar-form,
.nav-collapse .navbar-search {
float: none;
padding: (@baseLineHeight / 2) 15px;
margin: (@baseLineHeight / 2) 0;
border-top: 1px solid @navbarBackground;
border-bottom: 1px solid @navbarBackground;
.box-shadow(inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1));
}
.navbar-inverse .nav-collapse .navbar-form,
.navbar-inverse .nav-collapse .navbar-search {
border-top-color: @navbarInverseBackground;
border-bottom-color: @navbarInverseBackground;
}
// Pull right (secondary) nav content
.navbar .nav-collapse .nav.pull-right {
float: none;
margin-left: 0;
}
// Hide everything in the navbar save .brand and toggle button */
.nav-collapse,
.nav-collapse.collapse {
overflow: hidden;
height: 0;
}
// Navbar button
.navbar .btn-navbar {
display: block;
}
// STATIC NAVBAR
// -------------
.navbar-static .navbar-inner {
padding-left: 10px;
padding-right: 10px;
}
}
// DEFAULT DESKTOP
// ---------------
@media (min-width: 980px) {
// Required to make the collapsing navbar work on regular desktops
.nav-collapse.collapse {
height: auto !important;
overflow: visible !important;
}
}

View File

@ -0,0 +1,43 @@
//
// Responsive: Utility classes
// --------------------------------------------------
// Hide from screenreaders and browsers
// Credit: HTML5 Boilerplate
.hidden {
display: none;
visibility: hidden;
}
// Visibility utilities
// For desktops
.visible-phone { display: none !important; }
.visible-tablet { display: none !important; }
.hidden-phone { }
.hidden-tablet { }
.hidden-desktop { display: none !important; }
.visible-desktop { display: inherit !important; }
// Tablets & small desktops only
@media (min-width: 768px) and (max-width: 979px) {
// Hide everything else
.hidden-desktop { display: inherit !important; }
.visible-desktop { display: none !important ; }
// Show
.visible-tablet { display: inherit !important; }
// Hide
.hidden-tablet { display: none !important; }
}
// Phones only
@media (max-width: 767px) {
// Hide everything else
.hidden-desktop { display: inherit !important; }
.visible-desktop { display: none !important; }
// Show
.visible-phone { display: inherit !important; } // Use inherit to restore previous behavior
// Hide
.hidden-phone { display: none !important; }
}

View File

@ -0,0 +1,48 @@
/*!
* Bootstrap Responsive v2.1.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/
// Responsive.less
// For phone and tablet devices
// -------------------------------------------------------------
// REPEAT VARIABLES & MIXINS
// -------------------------
// Required since we compile the responsive stuff separately
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
@import "mixins.less";
// RESPONSIVE CLASSES
// ------------------
@import "responsive-utilities.less";
// MEDIA QUERIES
// ------------------
// Large desktops
@import "responsive-1200px-min.less";
// Tablets to regular desktops
@import "responsive-768px-979px.less";
// Phones to portrait tablets and narrow desktops
@import "responsive-767px-max.less";
// RESPONSIVE NAVBAR
// ------------------
// From 979px and below, show a button to toggle navbar contents
@import "responsive-navbar.less";

View File

@ -0,0 +1,52 @@
//
// Scaffolding
// --------------------------------------------------
// Body reset
// -------------------------
body {
margin: 0;
font-family: @baseFontFamily;
font-size: @baseFontSize;
line-height: @baseLineHeight;
color: @textColor;
background-color: @bodyBackground;
}
// Links
// -------------------------
a {
color: @linkColor;
text-decoration: none;
}
a:hover {
color: @linkColorHover;
text-decoration: underline;
}
// Images
// -------------------------
// Rounded corners
.img-rounded {
.border-radius(6px);
}
// Add polaroid-esque trim
.img-polaroid {
padding: 4px;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.2);
.box-shadow(0 1px 3px rgba(0,0,0,.1));
}
// Perfect circle
.img-circle {
.border-radius(500px); // crank the border-radius so it works with most reasonably sized images
}

193
bootstrap/less/sprites.less Normal file
View File

@ -0,0 +1,193 @@
//
// Sprites
// --------------------------------------------------
// ICONS
// -----
// All icons receive the styles of the <i> tag with a base class
// of .i and are then given a unique class to add width, height,
// and background-position. Your resulting HTML will look like
// <i class="icon-inbox"></i>.
// For the white version of the icons, just add the .icon-white class:
// <i class="icon-inbox icon-white"></i>
[class^="icon-"],
[class*=" icon-"] {
display: inline-block;
width: 14px;
height: 14px;
.ie7-restore-right-whitespace();
line-height: 14px;
vertical-align: text-top;
background-image: url("@{iconSpritePath}");
background-position: 14px 14px;
background-repeat: no-repeat;
margin-top: 1px;
}
/* White icons with optional class, or on hover/active states of certain elements */
.icon-white,
.nav-tabs > .active > a > [class^="icon-"],
.nav-tabs > .active > a > [class*=" icon-"],
.nav-pills > .active > a > [class^="icon-"],
.nav-pills > .active > a > [class*=" icon-"],
.nav-list > .active > a > [class^="icon-"],
.nav-list > .active > a > [class*=" icon-"],
.navbar-inverse .nav > .active > a > [class^="icon-"],
.navbar-inverse .nav > .active > a > [class*=" icon-"],
.dropdown-menu > li > a:hover > [class^="icon-"],
.dropdown-menu > li > a:hover > [class*=" icon-"],
.dropdown-menu > .active > a > [class^="icon-"],
.dropdown-menu > .active > a > [class*=" icon-"] {
background-image: url("@{iconWhiteSpritePath}");
}
.icon-glass { background-position: 0 0; }
.icon-music { background-position: -24px 0; }
.icon-search { background-position: -48px 0; }
.icon-envelope { background-position: -72px 0; }
.icon-heart { background-position: -96px 0; }
.icon-star { background-position: -120px 0; }
.icon-star-empty { background-position: -144px 0; }
.icon-user { background-position: -168px 0; }
.icon-film { background-position: -192px 0; }
.icon-th-large { background-position: -216px 0; }
.icon-th { background-position: -240px 0; }
.icon-th-list { background-position: -264px 0; }
.icon-ok { background-position: -288px 0; }
.icon-remove { background-position: -312px 0; }
.icon-zoom-in { background-position: -336px 0; }
.icon-zoom-out { background-position: -360px 0; }
.icon-off { background-position: -384px 0; }
.icon-signal { background-position: -408px 0; }
.icon-cog { background-position: -432px 0; }
.icon-trash { background-position: -456px 0; }
.icon-home { background-position: 0 -24px; }
.icon-file { background-position: -24px -24px; }
.icon-time { background-position: -48px -24px; }
.icon-road { background-position: -72px -24px; }
.icon-download-alt { background-position: -96px -24px; }
.icon-download { background-position: -120px -24px; }
.icon-upload { background-position: -144px -24px; }
.icon-inbox { background-position: -168px -24px; }
.icon-play-circle { background-position: -192px -24px; }
.icon-repeat { background-position: -216px -24px; }
.icon-refresh { background-position: -240px -24px; }
.icon-list-alt { background-position: -264px -24px; }
.icon-lock { background-position: -287px -24px; } // 1px off
.icon-flag { background-position: -312px -24px; }
.icon-headphones { background-position: -336px -24px; }
.icon-volume-off { background-position: -360px -24px; }
.icon-volume-down { background-position: -384px -24px; }
.icon-volume-up { background-position: -408px -24px; }
.icon-qrcode { background-position: -432px -24px; }
.icon-barcode { background-position: -456px -24px; }
.icon-tag { background-position: 0 -48px; }
.icon-tags { background-position: -25px -48px; } // 1px off
.icon-book { background-position: -48px -48px; }
.icon-bookmark { background-position: -72px -48px; }
.icon-print { background-position: -96px -48px; }
.icon-camera { background-position: -120px -48px; }
.icon-font { background-position: -144px -48px; }
.icon-bold { background-position: -167px -48px; } // 1px off
.icon-italic { background-position: -192px -48px; }
.icon-text-height { background-position: -216px -48px; }
.icon-text-width { background-position: -240px -48px; }
.icon-align-left { background-position: -264px -48px; }
.icon-align-center { background-position: -288px -48px; }
.icon-align-right { background-position: -312px -48px; }
.icon-align-justify { background-position: -336px -48px; }
.icon-list { background-position: -360px -48px; }
.icon-indent-left { background-position: -384px -48px; }
.icon-indent-right { background-position: -408px -48px; }
.icon-facetime-video { background-position: -432px -48px; }
.icon-picture { background-position: -456px -48px; }
.icon-pencil { background-position: 0 -72px; }
.icon-map-marker { background-position: -24px -72px; }
.icon-adjust { background-position: -48px -72px; }
.icon-tint { background-position: -72px -72px; }
.icon-edit { background-position: -96px -72px; }
.icon-share { background-position: -120px -72px; }
.icon-check { background-position: -144px -72px; }
.icon-move { background-position: -168px -72px; }
.icon-step-backward { background-position: -192px -72px; }
.icon-fast-backward { background-position: -216px -72px; }
.icon-backward { background-position: -240px -72px; }
.icon-play { background-position: -264px -72px; }
.icon-pause { background-position: -288px -72px; }
.icon-stop { background-position: -312px -72px; }
.icon-forward { background-position: -336px -72px; }
.icon-fast-forward { background-position: -360px -72px; }
.icon-step-forward { background-position: -384px -72px; }
.icon-eject { background-position: -408px -72px; }
.icon-chevron-left { background-position: -432px -72px; }
.icon-chevron-right { background-position: -456px -72px; }
.icon-plus-sign { background-position: 0 -96px; }
.icon-minus-sign { background-position: -24px -96px; }
.icon-remove-sign { background-position: -48px -96px; }
.icon-ok-sign { background-position: -72px -96px; }
.icon-question-sign { background-position: -96px -96px; }
.icon-info-sign { background-position: -120px -96px; }
.icon-screenshot { background-position: -144px -96px; }
.icon-remove-circle { background-position: -168px -96px; }
.icon-ok-circle { background-position: -192px -96px; }
.icon-ban-circle { background-position: -216px -96px; }
.icon-arrow-left { background-position: -240px -96px; }
.icon-arrow-right { background-position: -264px -96px; }
.icon-arrow-up { background-position: -289px -96px; } // 1px off
.icon-arrow-down { background-position: -312px -96px; }
.icon-share-alt { background-position: -336px -96px; }
.icon-resize-full { background-position: -360px -96px; }
.icon-resize-small { background-position: -384px -96px; }
.icon-plus { background-position: -408px -96px; }
.icon-minus { background-position: -433px -96px; }
.icon-asterisk { background-position: -456px -96px; }
.icon-exclamation-sign { background-position: 0 -120px; }
.icon-gift { background-position: -24px -120px; }
.icon-leaf { background-position: -48px -120px; }
.icon-fire { background-position: -72px -120px; }
.icon-eye-open { background-position: -96px -120px; }
.icon-eye-close { background-position: -120px -120px; }
.icon-warning-sign { background-position: -144px -120px; }
.icon-plane { background-position: -168px -120px; }
.icon-calendar { background-position: -192px -120px; }
.icon-random { background-position: -216px -120px; width: 16px; }
.icon-comment { background-position: -240px -120px; }
.icon-magnet { background-position: -264px -120px; }
.icon-chevron-up { background-position: -288px -120px; }
.icon-chevron-down { background-position: -313px -119px; } // 1px, 1px off
.icon-retweet { background-position: -336px -120px; }
.icon-shopping-cart { background-position: -360px -120px; }
.icon-folder-close { background-position: -384px -120px; }
.icon-folder-open { background-position: -408px -120px; width: 16px; }
.icon-resize-vertical { background-position: -432px -119px; } // 1px, 1px off
.icon-resize-horizontal { background-position: -456px -118px; } // 1px, 2px off
.icon-hdd { background-position: 0 -144px; }
.icon-bullhorn { background-position: -24px -144px; }
.icon-bell { background-position: -48px -144px; }
.icon-certificate { background-position: -72px -144px; }
.icon-thumbs-up { background-position: -96px -144px; }
.icon-thumbs-down { background-position: -120px -144px; }
.icon-hand-right { background-position: -144px -144px; }
.icon-hand-left { background-position: -168px -144px; }
.icon-hand-up { background-position: -192px -144px; }
.icon-hand-down { background-position: -216px -144px; }
.icon-circle-arrow-right { background-position: -240px -144px; }
.icon-circle-arrow-left { background-position: -264px -144px; }
.icon-circle-arrow-up { background-position: -288px -144px; }
.icon-circle-arrow-down { background-position: -312px -144px; }
.icon-globe { background-position: -336px -144px; }
.icon-wrench { background-position: -360px -144px; }
.icon-tasks { background-position: -384px -144px; }
.icon-filter { background-position: -408px -144px; }
.icon-briefcase { background-position: -432px -144px; }
.icon-fullscreen { background-position: -456px -144px; }

245
bootstrap/less/tables.less Normal file
View File

@ -0,0 +1,245 @@
//
// Tables
// --------------------------------------------------
// BASE TABLES
// -----------------
table {
max-width: 100%;
background-color: @tableBackground;
border-collapse: collapse;
border-spacing: 0;
}
// BASELINE STYLES
// ---------------
.table {
width: 100%;
margin-bottom: @baseLineHeight;
// Cells
th,
td {
padding: 8px;
line-height: @baseLineHeight;
text-align: left;
vertical-align: top;
border-top: 1px solid @tableBorder;
}
th {
font-weight: bold;
}
// Bottom align for column headings
thead th {
vertical-align: bottom;
}
// Remove top border from thead by default
caption + thead tr:first-child th,
caption + thead tr:first-child td,
colgroup + thead tr:first-child th,
colgroup + thead tr:first-child td,
thead:first-child tr:first-child th,
thead:first-child tr:first-child td {
border-top: 0;
}
// Account for multiple tbody instances
tbody + tbody {
border-top: 2px solid @tableBorder;
}
}
// CONDENSED TABLE W/ HALF PADDING
// -------------------------------
.table-condensed {
th,
td {
padding: 4px 5px;
}
}
// BORDERED VERSION
// ----------------
.table-bordered {
border: 1px solid @tableBorder;
border-collapse: separate; // Done so we can round those corners!
*border-collapse: collapse; // IE7 can't round corners anyway
border-left: 0;
.border-radius(4px);
th,
td {
border-left: 1px solid @tableBorder;
}
// Prevent a double border
caption + thead tr:first-child th,
caption + tbody tr:first-child th,
caption + tbody tr:first-child td,
colgroup + thead tr:first-child th,
colgroup + tbody tr:first-child th,
colgroup + tbody tr:first-child td,
thead:first-child tr:first-child th,
tbody:first-child tr:first-child th,
tbody:first-child tr:first-child td {
border-top: 0;
}
// For first th or td in the first row in the first thead or tbody
thead:first-child tr:first-child th:first-child,
tbody:first-child tr:first-child td:first-child {
-webkit-border-top-left-radius: 4px;
border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
}
thead:first-child tr:first-child th:last-child,
tbody:first-child tr:first-child td:last-child {
-webkit-border-top-right-radius: 4px;
border-top-right-radius: 4px;
-moz-border-radius-topright: 4px;
}
// For first th or td in the first row in the first thead or tbody
thead:last-child tr:last-child th:first-child,
tbody:last-child tr:last-child td:first-child,
tfoot:last-child tr:last-child td:first-child {
.border-radius(0 0 0 4px);
-webkit-border-bottom-left-radius: 4px;
border-bottom-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
}
thead:last-child tr:last-child th:last-child,
tbody:last-child tr:last-child td:last-child,
tfoot:last-child tr:last-child td:last-child {
-webkit-border-bottom-right-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomright: 4px;
}
// Special fixes to round the left border on the first td/th
caption + thead tr:first-child th:first-child,
caption + tbody tr:first-child td:first-child,
colgroup + thead tr:first-child th:first-child,
colgroup + tbody tr:first-child td:first-child {
-webkit-border-top-left-radius: 4px;
border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
}
caption + thead tr:first-child th:last-child,
caption + tbody tr:first-child td:last-child,
colgroup + thead tr:first-child th:last-child,
colgroup + tbody tr:first-child td:last-child {
-webkit-border-top-right-radius: 4px;
border-top-right-radius: 4px;
-moz-border-radius-topleft: 4px;
}
}
// ZEBRA-STRIPING
// --------------
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
.table-striped {
tbody {
tr:nth-child(odd) td,
tr:nth-child(odd) th {
background-color: @tableBackgroundAccent;
}
}
}
// HOVER EFFECT
// ------------
// Placed here since it has to come after the potential zebra striping
.table-hover {
tbody {
tr:hover td,
tr:hover th {
background-color: @tableBackgroundHover;
}
}
}
// TABLE CELL SIZING
// -----------------
// Reset default grid behavior
table [class*=span],
.row-fluid table [class*=span] {
display: table-cell;
float: none; // undo default grid column styles
margin-left: 0; // undo default grid column styles
}
// Change the column widths to account for td/th padding
.table {
.span1 { .tableColumns(1); }
.span2 { .tableColumns(2); }
.span3 { .tableColumns(3); }
.span4 { .tableColumns(4); }
.span5 { .tableColumns(5); }
.span6 { .tableColumns(6); }
.span7 { .tableColumns(7); }
.span8 { .tableColumns(8); }
.span9 { .tableColumns(9); }
.span10 { .tableColumns(10); }
.span11 { .tableColumns(11); }
.span12 { .tableColumns(12); }
.span13 { .tableColumns(13); }
.span14 { .tableColumns(14); }
.span15 { .tableColumns(15); }
.span16 { .tableColumns(16); }
.span17 { .tableColumns(17); }
.span18 { .tableColumns(18); }
.span19 { .tableColumns(19); }
.span20 { .tableColumns(20); }
.span21 { .tableColumns(21); }
.span22 { .tableColumns(22); }
.span23 { .tableColumns(23); }
.span24 { .tableColumns(24); }
}
// TABLE BACKGROUNDS
// -----------------
// Exact selectors below required to override .table-striped
.table tbody tr {
&.success td {
background-color: @successBackground;
}
&.error td {
background-color: @errorBackground;
}
&.warning td {
background-color: @warningBackground;
}
&.info td {
background-color: @infoBackground;
}
}
// Hover states for .table-hover
.table-hover tbody tr {
&.success:hover td {
background-color: darken(@successBackground, 5%);
}
&.error:hover td {
background-color: darken(@errorBackground, 5%);
}
&.warning:hover td {
background-color: darken(@warningBackground, 5%);
}
&.info:hover td {
background-color: darken(@infoBackground, 5%);
}
}

View File

@ -0,0 +1,52 @@
//
// Thumbnails
// --------------------------------------------------
// Note: `.thumbnails` and `.thumbnails > li` are overriden in responsive files
// Make wrapper ul behave like the grid
.thumbnails {
margin-left: -@gridGutterWidth;
list-style: none;
.clearfix();
}
// Fluid rows have no left margin
.row-fluid .thumbnails {
margin-left: 0;
}
// Float li to make thumbnails appear in a row
.thumbnails > li {
float: left; // Explicity set the float since we don't require .span* classes
margin-bottom: @baseLineHeight;
margin-left: @gridGutterWidth;
}
// The actual thumbnail (can be `a` or `div`)
.thumbnail {
display: block;
padding: 4px;
line-height: @baseLineHeight;
border: 1px solid #ddd;
.border-radius(4px);
.box-shadow(0 1px 3px rgba(0,0,0,.055));
.transition(all .2s ease-in-out);
}
// Add a hover state for linked versions only
a.thumbnail:hover {
border-color: @linkColor;
.box-shadow(0 1px 4px rgba(0,105,214,.25));
}
// Images and captions
.thumbnail > img {
display: block;
max-width: 100%;
margin-left: auto;
margin-right: auto;
}
.thumbnail .caption {
padding: 9px;
color: @gray;
}

View File

@ -0,0 +1,70 @@
//
// Tooltips
// --------------------------------------------------
// Base class
.tooltip {
position: absolute;
z-index: @zindexTooltip;
display: block;
visibility: visible;
padding: 5px;
font-size: 11px;
.opacity(0);
&.in { .opacity(80); }
&.top { margin-top: -3px; }
&.right { margin-left: 3px; }
&.bottom { margin-top: 3px; }
&.left { margin-left: -3px; }
}
// Wrapper for the tooltip content
.tooltip-inner {
max-width: 200px;
padding: 3px 8px;
color: @tooltipColor;
text-align: center;
text-decoration: none;
background-color: @tooltipBackground;
.border-radius(4px);
}
// Arrows
.tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.tooltip {
&.top .tooltip-arrow {
bottom: 0;
left: 50%;
margin-left: -@tooltipArrowWidth;
border-width: @tooltipArrowWidth @tooltipArrowWidth 0;
border-top-color: @tooltipArrowColor;
}
&.right .tooltip-arrow {
top: 50%;
left: 0;
margin-top: -@tooltipArrowWidth;
border-width: @tooltipArrowWidth @tooltipArrowWidth @tooltipArrowWidth 0;
border-right-color: @tooltipArrowColor;
}
&.left .tooltip-arrow {
top: 50%;
right: 0;
margin-top: -@tooltipArrowWidth;
border-width: @tooltipArrowWidth 0 @tooltipArrowWidth @tooltipArrowWidth;
border-left-color: @tooltipArrowColor;
}
&.bottom .tooltip-arrow {
top: 0;
left: 50%;
margin-left: -@tooltipArrowWidth;
border-width: 0 @tooltipArrowWidth @tooltipArrowWidth;
border-bottom-color: @tooltipArrowColor;
}
}

221
bootstrap/less/type.less Normal file
View File

@ -0,0 +1,221 @@
//
// Typography
// --------------------------------------------------
// Body text
// -------------------------
p {
margin: 0 0 @baseLineHeight / 2;
}
.lead {
margin-bottom: @baseLineHeight;
font-size: @baseFontSize * 1.5;
font-weight: 200;
line-height: @baseLineHeight * 1.5;
}
// Emphasis & misc
// -------------------------
small {
font-size: 85%; // Ex: 14px base font * 85% = about 12px
}
strong {
font-weight: bold;
}
em {
font-style: italic;
}
cite {
font-style: normal;
}
// Utility classes
.muted {
color: @grayLight;
}
.text-warning {
color: @warningText;
}
.text-error {
color: @errorText;
}
.text-info {
color: @infoText;
}
.text-success {
color: @successText;
}
// Headings
// -------------------------
h1, h2, h3, h4, h5, h6 {
margin: (@baseLineHeight / 2) 0;
font-family: @headingsFontFamily;
font-weight: @headingsFontWeight;
line-height: 1;
color: @headingsColor;
text-rendering: optimizelegibility; // Fix the character spacing for headings
small {
font-weight: normal;
line-height: 1;
color: @grayLight;
}
}
h1 { font-size: 36px; line-height: 40px; }
h2 { font-size: 30px; line-height: 40px; }
h3 { font-size: 24px; line-height: 40px; }
h4 { font-size: 18px; line-height: 20px; }
h5 { font-size: 14px; line-height: 20px; }
h6 { font-size: 12px; line-height: 20px; }
h1 small { font-size: 24px; }
h2 small { font-size: 18px; }
h3 small { font-size: 14px; }
h4 small { font-size: 14px; }
// Page header
// -------------------------
.page-header {
padding-bottom: (@baseLineHeight / 2) - 1;
margin: @baseLineHeight 0 (@baseLineHeight * 1.5);
border-bottom: 1px solid @grayLighter;
}
// Lists
// --------------------------------------------------
// Unordered and Ordered lists
ul, ol {
padding: 0;
margin: 0 0 @baseLineHeight / 2 25px;
}
ul ul,
ul ol,
ol ol,
ol ul {
margin-bottom: 0;
}
li {
line-height: @baseLineHeight;
}
ul.unstyled,
ol.unstyled {
margin-left: 0;
list-style: none;
}
// Description Lists
dl {
margin-bottom: @baseLineHeight;
}
dt,
dd {
line-height: @baseLineHeight;
}
dt {
font-weight: bold;
}
dd {
margin-left: @baseLineHeight / 2;
}
// Horizontal layout (like forms)
.dl-horizontal {
.clearfix(); // Ensure dl clears floats if empty dd elements present
dt {
float: left;
width: @horizontalComponentOffset - 20;
clear: left;
text-align: right;
.text-overflow();
}
dd {
margin-left: @horizontalComponentOffset;
}
}
// MISC
// ----
// Horizontal rules
hr {
margin: @baseLineHeight 0;
border: 0;
border-top: 1px solid @hrBorder;
border-bottom: 1px solid @white;
}
// Abbreviations and acronyms
abbr[title] {
cursor: help;
border-bottom: 1px dotted @grayLight;
}
abbr.initialism {
font-size: 90%;
text-transform: uppercase;
}
// Blockquotes
blockquote {
padding: 0 0 0 15px;
margin: 0 0 @baseLineHeight;
border-left: 5px solid @grayLighter;
p {
margin-bottom: 0;
#font > .shorthand(16px,300,@baseLineHeight * 1.25);
}
small {
display: block;
line-height: @baseLineHeight;
color: @grayLight;
&:before {
content: '\2014 \00A0';
}
}
// Float right with text-align: right
&.pull-right {
float: right;
padding-right: 15px;
padding-left: 0;
border-right: 5px solid @grayLighter;
border-left: 0;
p,
small {
text-align: right;
}
small {
&:before {
content: '';
}
&:after {
content: '\00A0 \2014';
}
}
}
}
// Quotes
q:before,
q:after,
blockquote:before,
blockquote:after {
content: "";
}
// Addresses
address {
display: block;
margin-bottom: @baseLineHeight;
font-style: normal;
line-height: @baseLineHeight;
}

View File

@ -0,0 +1,30 @@
//
// Utility classes
// --------------------------------------------------
// Quick floats
.pull-right {
float: right;
}
.pull-left {
float: left;
}
// Toggling content
.hide {
display: none;
}
.show {
display: block;
}
// Visibility
.invisible {
visibility: hidden;
}
// For Affix plugin
.affix {
position: fixed;
}

View File

@ -0,0 +1,279 @@
//
// Variables
// --------------------------------------------------
// Global values
// --------------------------------------------------
// Grays
// -------------------------
@black: #000;
@grayDarker: #222;
@grayDark: #333;
@gray: #555;
@grayLight: #999;
@grayLighter: #eee;
@white: #fff;
// Accent colors
// -------------------------
@blue: #049cdb;
@blueDark: #0064cd;
@green: #46a546;
@red: #9d261d;
@yellow: #ffc40d;
@orange: #f89406;
@pink: #c3325f;
@purple: #7a43b6;
// Scaffolding
// -------------------------
@bodyBackground: @white;
@textColor: #5F5F5F;
// Links
// -------------------------
@linkColor: #08c;
@linkColorHover: darken(@linkColor, 15%);
// Typography
// -------------------------
@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif;
@serifFontFamily: Georgia, "Times New Roman", Times, serif;
@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace;
@baseFontSize: 12px;
@baseFontFamily: @sansFontFamily;
@baseLineHeight: 22px;
@altFontFamily: @serifFontFamily;
@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily
@headingsFontWeight: bold; // instead of browser default, bold
@headingsColor: inherit; // empty to use BS default, @textColor
// Tables
// -------------------------
@tableBackground: transparent; // overall background-color
@tableBackgroundAccent: #f9f9f9; // for striping
@tableBackgroundHover: #f5f5f5; // for hover
@tableBorder: #ddd; // table and cell border
// Buttons
// -------------------------
@btnBackground: @white;
@btnBackgroundHighlight: darken(@white, 10%);
@btnBorder: #bbb;
@btnPrimaryBackground: @linkColor;
@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%);
@btnInfoBackground: #5bc0de;
@btnInfoBackgroundHighlight: #2f96b4;
@btnSuccessBackground: #62c462;
@btnSuccessBackgroundHighlight: #51a351;
@btnWarningBackground: lighten(@orange, 15%);
@btnWarningBackgroundHighlight: @orange;
@btnDangerBackground: #ee5f5b;
@btnDangerBackgroundHighlight: #bd362f;
@btnInverseBackground: #444;
@btnInverseBackgroundHighlight: @grayDarker;
// Forms
// -------------------------
@inputBackground: #fdfdfd;
@inputBorder: #ccc;
@inputBorderRadius: 3px;
@inputDisabledBackground: @grayLighter;
@formActionsBackground: #f5f5f5;
// Dropdowns
// -------------------------
@dropdownBackground: @white;
@dropdownBorder: rgba(0,0,0,.2);
@dropdownDividerTop: #e5e5e5;
@dropdownDividerBottom: @white;
@dropdownLinkColor: @grayDark;
@dropdownLinkColorHover: @white;
@dropdownLinkColorActive: @dropdownLinkColor;
@dropdownLinkBackgroundActive: @linkColor;
@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive;
// COMPONENT VARIABLES
// --------------------------------------------------
// Z-index master list
// -------------------------
// Used for a bird's eye view of components dependent on the z-axis
// Try to avoid customizing these :)
@zindexDropdown: 1000;
@zindexPopover: 1010;
@zindexTooltip: 1030;
@zindexFixedNavbar: 1030;
@zindexModalBackdrop: 1040;
@zindexModal: 1050;
// Sprite icons path
// -------------------------
@iconSpritePath: "../img/glyphicons-halflings.png";
@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png";
// Input placeholder text color
// -------------------------
@placeholderText: @grayLight;
// Hr border color
// -------------------------
@hrBorder: @grayLighter;
// Horizontal forms & lists
// -------------------------
@horizontalComponentOffset: 180px;
// Wells
// -------------------------
@wellBackground: #f5f5f5;
// Navbar
// -------------------------
@navbarCollapseWidth: 979px;
@navbarHeight: 40px;
@navbarBackgroundHighlight: #ffffff;
@navbarBackground: darken(@navbarBackgroundHighlight, 5%);
@navbarBorder: darken(@navbarBackground, 12%);
@navbarText: #777;
@navbarLinkColor: #777;
@navbarLinkColorHover: @grayDark;
@navbarLinkColorActive: @gray;
@navbarLinkBackgroundHover: transparent;
@navbarLinkBackgroundActive: darken(@navbarBackground, 5%);
@navbarBrandColor: @navbarLinkColor;
// Inverted navbar
@navbarInverseBackground: #111111;
@navbarInverseBackgroundHighlight: #222222;
@navbarInverseBorder: #252525;
@navbarInverseText: @grayLight;
@navbarInverseLinkColor: @grayLight;
@navbarInverseLinkColorHover: @white;
@navbarInverseLinkColorActive: @navbarInverseLinkColorHover;
@navbarInverseLinkBackgroundHover: transparent;
@navbarInverseLinkBackgroundActive: @navbarInverseBackground;
@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%);
@navbarInverseSearchBackgroundFocus: @white;
@navbarInverseSearchBorder: @navbarInverseBackground;
@navbarInverseSearchPlaceholderColor: #ccc;
@navbarInverseBrandColor: @navbarInverseLinkColor;
// Pagination
// -------------------------
@paginationBackground: #fff;
@paginationBorder: #ddd;
@paginationActiveBackground: #f5f5f5;
// Hero unit
// -------------------------
@heroUnitBackground: @grayLighter;
@heroUnitHeadingColor: inherit;
@heroUnitLeadColor: inherit;
// Form states and alerts
// -------------------------
@warningText: #c09853;
@warningBackground: #fcf8e3;
@warningBorder: darken(spin(@warningBackground, -10), 3%);
@errorText: #b94a48;
@errorBackground: #f2dede;
@errorBorder: darken(spin(@errorBackground, -10), 3%);
@successText: #468847;
@successBackground: #dff0d8;
@successBorder: darken(spin(@successBackground, -10), 5%);
@infoText: #3a87ad;
@infoBackground: #d9edf7;
@infoBorder: darken(spin(@infoBackground, -10), 7%);
// Tooltips and popovers
// -------------------------
@tooltipColor: #fff;
@tooltipBackground: #000;
@tooltipArrowWidth: 5px;
@tooltipArrowColor: @tooltipBackground;
@popoverBackground: #fff;
@popoverArrowWidth: 10px;
@popoverArrowColor: #fff;
@popoverTitleBackground: darken(@popoverBackground, 3%);
// Special enhancement for popovers
@popoverArrowOuterWidth: @popoverArrowWidth + 1;
@popoverArrowOuterColor: rgba(0,0,0,.25);
// GRID
// --------------------------------------------------
// Default 940px grid
// -------------------------
@gridColumns: 12;
@gridColumnWidth: 60px;
@gridGutterWidth: 20px;
@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
// 1200px min
@gridColumnWidth1200: 70px;
@gridGutterWidth1200: 30px;
@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1));
// 768px-979px
@gridColumnWidth768: 42px;
@gridGutterWidth768: 20px;
@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1));
// Fluid grid
// -------------------------
@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth);
@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth);
// 1200px min
@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200);
@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200);
// 768px-979px
@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768);
@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768);

29
bootstrap/less/wells.less Normal file
View File

@ -0,0 +1,29 @@
//
// Wells
// --------------------------------------------------
// Base class
.well {
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
background-color: @wellBackground;
border: 1px solid darken(@wellBackground, 7%);
.border-radius(4px);
.box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
blockquote {
border-color: #ddd;
border-color: rgba(0,0,0,.15);
}
}
// Sizes
.well-large {
padding: 24px;
.border-radius(6px);
}
.well-small {
padding: 9px;
.border-radius(3px);
}

2027
bootstrap/tmp/bootstrap.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
bootstrap/tmp/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
/*!\n* Bootstrap.js by @fat & @mdo\n* Copyright 2012 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/

58
build.xml Normal file
View File

@ -0,0 +1,58 @@
<project name="biomed" basedir="." default="war">
<property name="gwt.module.name" value="com.biomed.Biomed" />
<property name="jar.name" value="biomed.jar" />
<property name="war.name" value="biomed.war" />
<property name="src.dir" location="src" />
<property name="build.dir" location="build" />
<property name="lib.dir" location="war/WEB-INF/lib" />
<path id="project.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar" />
</fileset>
</path>
<target name="prepare">
<mkdir dir="${build.dir}" />
</target>
<target name="clean">
<delete dir="${build.dir}" />
</target>
<target name="compile" depends="prepare">
<javac target="1.7" srcdir="${src.dir}" destdir="${build.dir}">
<classpath refid="project.classpath" />
</javac>
</target>
<target name="gwt-compile" depends="compile">
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<pathelement location="${src.dir}" />
<pathelement location="${build.dir}" />
<path refid="project.classpath" />
</classpath>
<jvmarg value="-Xmx256M" />
<arg value="${gwt.module.name}" />
</java>
</target>
<target name="jar" depends="compile">
<jar jarfile="${lib.dir}/${jar.name}" basedir="${build.dir}/">
<exclude name="${gwt.client.dir}/**/*.class" />
</jar>
</target>
<target name="war" depends="gwt-compile,jar">
<war basedir="war" destfile="${war.name}" webxml="war/WEB-INF/web.xml">
<exclude name="WEB-INF/**" />
<webinf dir="war/WEB-INF/">
<include name="**/*.jar" />
<exclude name="**/gwt-dev.jar" />
<exclude name="**/gwt-user.jar" />
</webinf>
</war>
</target>
</project>

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to="biomed" >
<inherits name="com.allen_sauer.gwt.dnd.gwt-dnd" />
<inherits name="com.bradrydzewski.gwt.calendar.Calendar" />
<inherits name="com.github.gwtbootstrap.Bootstrap" />
<inherits name="com.github.gwtbootstrap.datepicker.Datepicker" />
<inherits name="com.google.common.base.Base" />
<inherits name="com.google.common.collect.Collect" />
<inherits name="com.google.gwt.activity.Activity" />
<inherits name="com.google.gwt.inject.Inject"/>
<inherits name="com.google.gwt.json.JSON" />
<inherits name="com.google.gwt.i18n.I18N"/>
<inherits name="com.google.gwt.user.User" />
<inherits name="com.google.gwt.useragent.UserAgent" />
<inherits name="com.google.maps.gwt.GoogleMaps" />
<set-property name="user.agent" value="safari,gecko1_8"/>
<extend-property name="locale" values="en"/>
<set-property name="locale" value="en" />
<entry-point class="com.biomed.client.BiomedEntryPoint" />
<source path="client" />
<source path="shared" />
<source path="resources" />
<public path="resources">
<exclude name="**/*.java"/>
<exclude name="**/*.class"/>
</public>
<script src="http://maps.google.com/maps/api/js?sensor=false" />
<replace-with class="com.biomed.resources.BiomedConfigurator">
<when-type-is class="com.github.gwtbootstrap.client.ui.config.Configurator" />
</replace-with>
<replace-with class="com.biomed.client.resources.BiomedMonthViewStyleManager">
<when-type-is class="com.bradrydzewski.gwt.calendar.client.monthview.MonthViewStyleManager"/>
</replace-with>
<replace-with class="com.biomed.client.resources.BiomedDayViewStyleManager">
<when-type-is class="com.bradrydzewski.gwt.calendar.client.dayview.DayViewStyleManager"/>
</replace-with>
</module>

View File

@ -0,0 +1,26 @@
package com.biomed.client;
import com.biomed.client.place.BiomedPlace;
public abstract class AbstractBiomedActivity implements BiomedActivity {
protected BiomedPlace place;
@Override
public String mayStop() {
return null;
}
@Override
public void onCancel() {
}
@Override
public void onStop() {
}
@Override
public void setPlace(BiomedPlace place) {
this.place = place;
}
}

View File

@ -0,0 +1,46 @@
package com.biomed.client;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.place.BiomedPlace;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.web.bindery.event.shared.EventBus;
public interface BiomedActivity {
/**
* Called when the user is trying to navigate away from this activity.
*
* @return A message to display to the user, e.g. to warn of unsaved work, or
* null to say nothing
*/
String mayStop();
/**
* Called when {@link #start} has not yet replied to its callback, but the
* user has lost interest.
*/
void onCancel();
/**
* Called when the Activity's widget has been removed from view. All event
* handlers it registered will have been removed before this method is called.
*/
void onStop();
/**
* Called when the Activity should ready its widget for the user. When the
* widget is ready (typically after an RPC response has been received),
* receiver should present it by calling
* {@link AcceptsOneWidget#setWidget} on the given panel.
* <p>
* Any handlers attached to the provided event bus will be de-registered when
* the activity is stopped, so activities will rarely need to hold on to the
* {@link com.google.gwt.event.shared.HandlerRegistration HandlerRegistration}
* instances returned by {@link EventBus#addHandler}.
*
* @param panel the panel to display this activity's widget when it is ready
* @param eventBus the event bus
*/
void start(SiteContainer panel, EventBus eventBus);
void setPlace(BiomedPlace place);
}

View File

@ -0,0 +1,266 @@
package com.biomed.client;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import com.biomed.client.place.BiomedPlace;
import com.google.common.collect.Maps;
import com.google.gwt.event.shared.UmbrellaException;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceChangeRequestEvent;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.google.web.bindery.event.shared.ResettableEventBus;
public class BiomedActivityManager implements PlaceChangeEvent.Handler,
PlaceChangeRequestEvent.Handler {
/**
* Wraps our real display to prevent an Activity from taking it over if it is
* not the currentActivity.
*/
public class SiteContainer {
private final BiomedActivity activity;
SiteContainer(BiomedActivity activity) {
this.activity = activity;
}
public void setWidget(BiomedSite site, IsWidget view) {
if (this.activity == BiomedActivityManager.this.currentActivity) {
startingNext = false;
showWidget(site, view);
}
}
}
private static final BiomedActivity NULL_ACTIVITY = new AbstractBiomedActivity() {
public void start(SiteContainer container, EventBus eventBus) {
}
};
private final BiomedActivityMapper mapper;
private final EventBus eventBus;
/*
* Note that we use the legacy class from com.google.gwt.event.shared, because
* we can't change the Activity interface.
*/
private final ResettableEventBus stopperedEventBus;
private BiomedActivity currentActivity = NULL_ACTIVITY;
private Map<BiomedSite, AcceptsOneWidget> sites = Maps.newHashMap();
private boolean startingNext = false;
private HandlerRegistration handlerRegistration;
/**
* Create an ActivityManager. Next call {@link #setDisplay}.
*
* @param mapper
* finds the {@link BiomedActivity} for a given
* {@link com.google.gwt.place.shared.Place}
* @param eventBus
* source of {@link PlaceChangeEvent} and
* {@link PlaceChangeRequestEvent} events.
*/
public BiomedActivityManager(BiomedActivityMapper mapper, EventBus eventBus) {
this.mapper = mapper;
this.eventBus = eventBus;
this.stopperedEventBus = new ResettableEventBus(eventBus);
}
/**
* Returns an event bus which is in use by the currently running activity.
* <p>
* Any handlers attached to the returned event bus will be de-registered when
* the current activity is stopped.
*
* @return the event bus used by the current activity
*/
public EventBus getActiveEventBus() {
return stopperedEventBus;
}
/**
* Deactivate the current activity, find the next one from our ActivityMapper,
* and start it.
* <p>
* The current activity's widget will be hidden immediately, which can cause
* flicker if the next activity provides its widget asynchronously. That can
* be minimized by decent caching. Perenially slow activities might mitigate
* this by providing a widget immediately, with some kind of "loading"
* treatment.
*/
public void onPlaceChange(PlaceChangeEvent event) {
BiomedActivity nextActivity = getNextActivity(event);
Throwable caughtOnStop = null;
Throwable caughtOnCancel = null;
Throwable caughtOnStart = null;
if (nextActivity == null) {
nextActivity = NULL_ACTIVITY;
}
if (currentActivity.equals(nextActivity)) {
return;
}
if (startingNext) {
// The place changed again before the new current activity showed its
// widget
caughtOnCancel = tryStopOrCancel(false);
currentActivity = NULL_ACTIVITY;
startingNext = false;
} else if (!currentActivity.equals(NULL_ACTIVITY)) {
for (AcceptsOneWidget display : sites.values()) {
display.setWidget(null);
}
/*
* Kill off the activity's handlers, so it doesn't have to worry about
* them accidentally firing as a side effect of its tear down
*/
stopperedEventBus.removeHandlers();
caughtOnStop = tryStopOrCancel(true);
}
currentActivity = nextActivity;
if (currentActivity.equals(NULL_ACTIVITY)) {
for (AcceptsOneWidget display : sites.values()) {
display.setWidget(null);
}
} else {
startingNext = true;
caughtOnStart = tryStart();
}
if (caughtOnStart != null || caughtOnCancel != null || caughtOnStop != null) {
Set<Throwable> causes = new LinkedHashSet<Throwable>();
if (caughtOnStop != null) {
causes.add(caughtOnStop);
}
if (caughtOnCancel != null) {
causes.add(caughtOnCancel);
}
if (caughtOnStart != null) {
causes.add(caughtOnStart);
}
throw new UmbrellaException(causes);
}
}
/**
* Reject the place change if the current activity is not willing to stop.
*
* @see com.google.gwt.place.shared.PlaceChangeRequestEvent.Handler#onPlaceChangeRequest(PlaceChangeRequestEvent)
*/
public void onPlaceChangeRequest(PlaceChangeRequestEvent event) {
event.setWarning(currentActivity.mayStop());
}
/**
* Sets the display for the receiver, and has the side effect of starting or
* stopping its monitoring the event bus for place change events.
* <p>
* If you are disposing of an ActivityManager, it is important to call
* setDisplay(null) to get it to deregister from the event bus, so that it can
* be garbage collected.
*/
public void setSiteDisplay(BiomedSite site, AcceptsOneWidget display) {
boolean wasActive = sites.size() > 0;
if (display != null) {
sites.put(site, display);
} else {
sites.remove(site);
}
boolean willBeActive = sites.size() > 0;
if (wasActive != willBeActive) {
updateHandlers(willBeActive);
}
}
private BiomedActivity getNextActivity(PlaceChangeEvent event) {
if (sites.size() == 0) {
/*
* Display may have been nulled during PlaceChangeEvent dispatch. Don't
* bother the mapper, just return a null to ensure we shut down the
* current activity
*/
return null;
}
return mapper.getActivity((BiomedPlace) event.getNewPlace());
}
private void showWidget(BiomedSite site, IsWidget view) {
if (sites.containsKey(site)) {
sites.get(site).setWidget(view);
}
}
private Throwable tryStart() {
Throwable caughtOnStart = null;
try {
/*
* Wrap the actual display with a per-call instance that protects the
* display from canceled or stopped activities, and which maintains our
* startingNext state.
*/
currentActivity.start(new SiteContainer(currentActivity), stopperedEventBus);
} catch (Throwable t) {
caughtOnStart = t;
}
return caughtOnStart;
}
private Throwable tryStopOrCancel(boolean stop) {
Throwable caughtOnStop = null;
try {
if (stop) {
currentActivity.onStop();
} else {
currentActivity.onCancel();
}
} catch (Throwable t) {
caughtOnStop = t;
} finally {
/*
* Kill off the handlers again in case it was naughty and added new ones
* during onstop or oncancel
*/
stopperedEventBus.removeHandlers();
}
return caughtOnStop;
}
private void updateHandlers(boolean activate) {
if (activate) {
final HandlerRegistration placeReg = eventBus.addHandler(PlaceChangeEvent.TYPE, this);
final HandlerRegistration placeRequestReg = eventBus.addHandler(PlaceChangeRequestEvent.TYPE,
this);
this.handlerRegistration = new HandlerRegistration() {
public void removeHandler() {
placeReg.removeHandler();
placeRequestReg.removeHandler();
}
};
} else {
if (handlerRegistration != null) {
handlerRegistration.removeHandler();
handlerRegistration = null;
}
}
}
}

View File

@ -0,0 +1,97 @@
package com.biomed.client;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.biomed.client.activity.EditClientDevicesActivity;
import com.biomed.client.activity.EditClientFrequencyActivity;
import com.biomed.client.activity.EditClientOverviewActivity;
import com.biomed.client.activity.EditClientWorkordersActivity;
import com.biomed.client.activity.EditWorkorderActivity;
import com.biomed.client.activity.NewClientActivity;
import com.biomed.client.activity.NewMessageActivity;
import com.biomed.client.activity.ViewClientsActivity;
import com.biomed.client.activity.ViewScheduleActivity;
import com.biomed.client.activity.ViewWorkordersActivity;
import com.biomed.client.place.BiomedPlace;
import com.biomed.client.place.EditClientDevicesPlace;
import com.biomed.client.place.EditClientFrequencyPlace;
import com.biomed.client.place.EditClientOverviewPlace;
import com.biomed.client.place.EditClientWorkordersPlace;
import com.biomed.client.place.EditWorkorderPlace;
import com.biomed.client.place.NewClientPlace;
import com.biomed.client.place.NewMessagePlace;
import com.biomed.client.place.ViewClientsPlace;
import com.biomed.client.place.ViewSchedulePlace;
import com.biomed.client.place.ViewWorkordersPlace;
import com.google.inject.Provider;
@Singleton
public class BiomedActivityMapper {
@Inject Provider<EditClientOverviewActivity> editClientOverviewActivityProvider;
@Inject Provider<EditClientDevicesActivity> editClientDevicesActivityProvider;
@Inject Provider<EditClientFrequencyActivity> editClientFrequencyActivityProvider;
@Inject Provider<EditClientWorkordersActivity> editClientWorkordersActivityProvider;
@Inject Provider<EditWorkorderActivity> editWorkorderActivityProvider;
@Inject Provider<NewClientActivity> newClientActivityProvider;
@Inject Provider<NewMessageActivity> newMessageActivityProvider;
@Inject Provider<ViewClientsActivity> viewClientsActivityProvider;
@Inject Provider<ViewScheduleActivity> viewScheduleActivityProvider;
@Inject Provider<ViewWorkordersActivity> viewWorkordersActivityProvider;
public BiomedActivity getActivity(BiomedPlace place) {
BiomedActivity activity = getActivityInternal(place);
if (activity != null) {
activity.setPlace(place);
}
return activity;
}
private BiomedActivity getActivityInternal(BiomedPlace place) {
if (place instanceof EditClientOverviewPlace) {
return editClientOverviewActivityProvider.get();
}
if (place instanceof EditClientDevicesPlace) {
return editClientDevicesActivityProvider.get();
}
if (place instanceof EditClientFrequencyPlace) {
return editClientFrequencyActivityProvider.get();
}
if (place instanceof EditClientWorkordersPlace) {
return editClientWorkordersActivityProvider.get();
}
if (place instanceof EditWorkorderPlace) {
return editWorkorderActivityProvider.get();
}
if (place instanceof NewClientPlace) {
return newClientActivityProvider.get();
}
if (place instanceof NewMessagePlace) {
return newMessageActivityProvider.get();
}
if (place instanceof ViewClientsPlace) {
return viewClientsActivityProvider.get();
}
if (place instanceof ViewSchedulePlace) {
return viewScheduleActivityProvider.get();
}
if (place instanceof ViewWorkordersPlace) {
return viewWorkordersActivityProvider.get();
}
return null;
}
}

View File

@ -0,0 +1,18 @@
package com.biomed.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.RootPanel;
public class BiomedEntryPoint implements EntryPoint {
private final BiomedGinjector injector = GWT.create(BiomedGinjector.class);
@Override
public void onModuleLoad() {
DOM.getElementById("loading").removeFromParent();
RootPanel.get().add(injector.getAppWidget());
injector.getPlaceHistoryHandler().handleCurrentHistory();
}
}

View File

@ -0,0 +1,44 @@
package com.biomed.client;
import javax.inject.Singleton;
import com.biomed.client.dispatch.ClientDispatchGinModule;
import com.biomed.client.place.ViewSchedulePlace;
import com.biomed.client.services.ServicesGinModule;
import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.inject.Provides;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.SimpleEventBus;
public class BiomedGinModule extends AbstractGinModule {
@Override
protected void configure() {
install(new ClientDispatchGinModule());
install(new ServicesGinModule());
bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
bind(PlaceHistoryMapper.class).to(BiomedPlaceHistoryMapper.class).in(Singleton.class);
}
@Provides
@Singleton
public PlaceHistoryHandler getHistoryHandler(PlaceController placeController,
PlaceHistoryMapper historyMapper, EventBus eventBus) {
PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
historyHandler.register(placeController, eventBus, ViewSchedulePlace.INSTANCE);
return historyHandler;
}
@Provides
@Singleton
public PlaceController providesPlaceController(EventBus eventBus) {
return new PlaceController(eventBus);
}
}

View File

@ -0,0 +1,14 @@
package com.biomed.client;
import com.biomed.client.ui.MainPanel;
import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
import com.google.gwt.place.shared.PlaceHistoryHandler;
@GinModules(BiomedGinModule.class)
public interface BiomedGinjector extends Ginjector {
PlaceHistoryHandler getPlaceHistoryHandler();
MainPanel getAppWidget();
}

View File

@ -0,0 +1,29 @@
package com.biomed.client;
import com.biomed.client.place.EditClientDevicesPlace;
import com.biomed.client.place.EditClientFrequencyPlace;
import com.biomed.client.place.EditClientOverviewPlace;
import com.biomed.client.place.EditClientWorkordersPlace;
import com.biomed.client.place.EditWorkorderPlace;
import com.biomed.client.place.NewClientPlace;
import com.biomed.client.place.NewMessagePlace;
import com.biomed.client.place.ViewClientsPlace;
import com.biomed.client.place.ViewSchedulePlace;
import com.biomed.client.place.ViewWorkordersPlace;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.gwt.place.shared.WithTokenizers;
@WithTokenizers({
EditClientDevicesPlace.Tokenizer.class,
EditClientFrequencyPlace.Tokenizer.class,
EditClientOverviewPlace.Tokenizer.class,
EditClientWorkordersPlace.Tokenizer.class,
EditWorkorderPlace.Tokenizer.class,
NewClientPlace.Tokenizer.class,
NewMessagePlace.Tokenizer.class,
ViewClientsPlace.Tokenizer.class,
ViewSchedulePlace.Tokenizer.class,
ViewWorkordersPlace.Tokenizer.class
})
public interface BiomedPlaceHistoryMapper extends PlaceHistoryMapper { }

View File

@ -0,0 +1,9 @@
package com.biomed.client;
public enum BiomedSection {
DASHBOARD,
CLIENTS,
MESSAGES,
WORKORDERS,
SCHEDULE
}

View File

@ -0,0 +1,6 @@
package com.biomed.client;
public enum BiomedSite {
CONTENT,
SIDEBAR
}

View File

@ -0,0 +1,116 @@
package com.biomed.client.activity;
import javax.inject.Inject;
import com.biomed.client.AbstractBiomedActivity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.place.EditClientDevicesPlace;
import com.biomed.client.place.EditClientFrequencyPlace;
import com.biomed.client.place.EditClientOverviewPlace;
import com.biomed.client.place.EditClientWorkordersPlace;
import com.biomed.client.place.HasClientId;
import com.biomed.client.ui.clienteditor.ClientEditorSidebarPanel;
import com.biomed.client.ui.clienteditor.ClientEditorSidebarPanel.Tabs;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.place.shared.PlaceController;
import com.google.inject.Provider;
import com.google.web.bindery.event.shared.EventBus;
@SuppressWarnings("rawtypes")
public abstract class BaseClientActivity extends AbstractBiomedActivity implements
ValueChangeHandler {
@Inject
Provider<ClientEditorSidebarPanel> sidebarProvider;
@Inject
PlaceController placeController;
private boolean isDirty;
protected abstract boolean showNavigationPanel();
protected Tabs getTab() {
return null;
}
protected abstract void createContentPanel(SiteContainer panel);
@Override
public final void start(SiteContainer panel, EventBus eventBus) {
if (showNavigationPanel()) {
ClientEditorSidebarPanel sidebar = sidebarProvider.get();
sidebar.setActive(getTab());
addSidebarEventHandlers(sidebar);
panel.setWidget(BiomedSite.SIDEBAR, sidebar);
}
createContentPanel(panel);
}
private void addSidebarEventHandlers(ClientEditorSidebarPanel sidebar) {
Tabs tab = getTab();
if (tab != Tabs.OVERVIEW) {
sidebar.getOverviewTab().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
placeController.goTo(EditClientOverviewPlace.getPlace(getClientId()));
}
});
}
if (tab != Tabs.FREQUENCY) {
sidebar.getFrequencyTab().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
placeController.goTo(EditClientFrequencyPlace.getPlace(getClientId()));
}
});
}
if (tab != Tabs.DEVICES) {
sidebar.getDevicesTab().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
placeController.goTo(EditClientDevicesPlace.getPlace(getClientId()));
}
});
}
if (tab != Tabs.WORKORDERS) {
sidebar.getWorkordersTab().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
placeController.goTo(EditClientWorkordersPlace.getPlace(getClientId()));
}
});
}
}
protected int getClientId() {
return ((HasClientId) place).getId();
}
protected void resetDirtyFlag() {
isDirty = false;
}
@Override
public String mayStop() {
if (isDirty) {
return "You have unsaved changed, are you sure?";
} else {
return null;
}
}
@Override
public void onValueChange(ValueChangeEvent event) {
isDirty = true;
}
}

View File

@ -0,0 +1,102 @@
package com.biomed.client.activity;
import javax.inject.Inject;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.clienteditor.ClientOverviewEditorPanel;
import com.biomed.shared.api.EmptyResult;
import com.biomed.shared.api.SaveClientAction;
import com.biomed.shared.api.dto.ClientDTO;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
public abstract class BaseClientOverviewActivity extends BaseClientActivity {
@Inject
ClientOverviewEditorPanel view;
@Inject
BiomedService biomedService;
ClientDTO client;
@SuppressWarnings("unchecked")
protected void setupEvents() {
view.getIdentifierField().addValueChangeHandler(this);
view.getNameField().addValueChangeHandler(this);
view.getPrimaryAddressField().addValueChangeHandler(this);
view.getPrimaryAddress2Field().addValueChangeHandler(this);
view.getPrimaryCityField().addValueChangeHandler(this);
view.getPrimaryStateField().addValueChangeHandler(this);
view.getPrimaryZipField().addValueChangeHandler(this);
view.getPrimaryContactField().addValueChangeHandler(this);
view.getPrimaryPhoneField().addValueChangeHandler(this);
view.getPrimaryEmailField().addValueChangeHandler(this);
view.getSecondaryContactField().addValueChangeHandler(this);
view.getSecondaryPhoneField().addValueChangeHandler(this);
view.getSecondaryEmailField().addValueChangeHandler(this);
view.getNotesField().addValueChangeHandler(this);
view.getSaveButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
saveClient();
}
});
}
protected void setView(ClientDTO client) {
view.getIdentifierField().setValue(client.getIdentifier());
view.getNameField().setValue(client.getName());
view.getPrimaryAddressField().setValue(client.getPrimaryAddress());
view.getPrimaryAddress2Field().setValue(client.getPrimaryAddress2());
view.getPrimaryCityField().setValue(client.getPrimaryCity());
view.getPrimaryStateField().setValue(client.getPrimaryState());
view.getPrimaryZipField().setValue(client.getPrimaryZip());
view.getPrimaryContactField().setValue(client.getPrimaryContactName());
view.getPrimaryPhoneField().setValue(client.getPrimaryPhone());
view.getPrimaryEmailField().setValue(client.getPrimaryEmail());
view.getSecondaryContactField().setValue(client.getSecondaryContactName());
view.getSecondaryPhoneField().setValue(client.getSecondaryPhone());
view.getSecondaryEmailField().setValue(client.getSecondaryEmail());
view.getNotesField().setValue(client.getNotes());
}
protected void getView(ClientDTO client) {
client.setIdentifier(view.getIdentifierField().getValue());
client.setName(view.getNameField().getValue());
client.setPrimaryAddress(view.getPrimaryAddressField().getValue());
client.setPrimaryAddress2(view.getPrimaryAddress2Field().getValue());
client.setPrimaryCity(view.getPrimaryCityField().getValue());
client.setPrimaryState(view.getPrimaryStateField().getValue());
client.setPrimaryZip(view.getPrimaryZipField().getValue());
client.setPrimaryContactName(view.getPrimaryContactField().getValue());
client.setPrimaryPhone(view.getPrimaryPhoneField().getValue());
client.setPrimaryEmail(view.getPrimaryEmailField().getValue());
client.setSecondaryContactName(view.getSecondaryContactField().getValue());
client.setSecondaryPhone(view.getSecondaryPhoneField().getValue());
client.setSecondaryEmail(view.getSecondaryEmailField().getValue());
client.setNotes(view.getNotesField().getValue());
}
private void saveClient() {
getView(client);
SaveClientAction action = new SaveClientAction();
action.setClient(client);
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
resetDirtyFlag();
onSaveComplete();
}
});
}
protected void onSaveComplete() {
}
}

View File

@ -0,0 +1,53 @@
package com.biomed.client.activity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.clienteditor.ClientDevicesEditorPanel;
import com.biomed.client.ui.clienteditor.ClientEditorSidebarPanel.Tabs;
import com.biomed.shared.api.GetDevicesAction;
import com.biomed.shared.api.ListResult;
import com.biomed.shared.api.dto.DeviceDTO;
import com.google.gwt.view.client.ListDataProvider;
import com.google.inject.Inject;
public class EditClientDevicesActivity extends BaseClientActivity {
@Inject
ClientDevicesEditorPanel view;
@Inject
BiomedService biomedService;
private ListDataProvider<DeviceDTO> dataProvider;
@Override
protected boolean showNavigationPanel() {
return true;
}
@Override
protected Tabs getTab() {
return Tabs.DEVICES;
}
@Override
protected void createContentPanel(SiteContainer panel) {
dataProvider = new ListDataProvider<DeviceDTO>();
dataProvider.addDataDisplay(view.getTable());
panel.setWidget(BiomedSite.CONTENT, view);
view.showLoading();
GetDevicesAction action = new GetDevicesAction();
action.setClientId(getClientId());
biomedService.execute(action, new DefaultCallback<ListResult<DeviceDTO>>() {
@Override
public void onSuccess(ListResult<DeviceDTO> result) {
dataProvider.setList(result.getResult());
}
});
}
}

View File

@ -0,0 +1,66 @@
package com.biomed.client.activity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.clienteditor.ClientEditorSidebarPanel.Tabs;
import com.biomed.client.ui.clienteditor.ClientFrequencyEditorPanel;
import com.biomed.shared.api.EmptyResult;
import com.biomed.shared.api.GetClientFrequencyAction;
import com.biomed.shared.api.SaveClientFrequenciesAction;
import com.biomed.shared.api.SingleResult;
import com.biomed.shared.api.dto.FrequencyDTO;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.inject.Inject;
public class EditClientFrequencyActivity extends BaseClientActivity {
@Inject
ClientFrequencyEditorPanel view;
@Inject
BiomedService biomedService;
@Override
protected boolean showNavigationPanel() {
return true;
}
@Override
protected Tabs getTab() {
return Tabs.FREQUENCY;
}
@Override
protected void createContentPanel(SiteContainer panel) {
panel.setWidget(BiomedSite.CONTENT, view);
GetClientFrequencyAction action = new GetClientFrequencyAction();
action.setClientId(getClientId());
biomedService.execute(action, new DefaultCallback<SingleResult<FrequencyDTO>>() {
@Override
public void onSuccess(SingleResult<FrequencyDTO> result) {
view.setFrequencies(result.getResult());
}
});
view.getSaveButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
SaveClientFrequenciesAction action = new SaveClientFrequenciesAction();
action.setClientId(getClientId());
action.setFrequencies(view.getFrequencies());
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
}
});
}
});
}
}

View File

@ -0,0 +1,43 @@
package com.biomed.client.activity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.ui.clienteditor.ClientEditorSidebarPanel.Tabs;
import com.biomed.shared.api.GetClientAction;
import com.biomed.shared.api.SingleResult;
import com.biomed.shared.api.dto.ClientDTO;
public class EditClientOverviewActivity extends BaseClientOverviewActivity {
@Override
protected boolean showNavigationPanel() {
return true;
}
@Override
protected Tabs getTab() {
return Tabs.OVERVIEW;
}
@Override
protected void createContentPanel(final SiteContainer panel) {
setupEvents();
fetchClient(panel, getClientId());
}
private void fetchClient(final SiteContainer panel, int id) {
GetClientAction action = new GetClientAction();
action.setClientId(id);
biomedService.execute(action, new DefaultCallback<SingleResult<ClientDTO>>() {
@Override
public void onSuccess(SingleResult<ClientDTO> result) {
panel.setWidget(BiomedSite.CONTENT, view);
client = result.getResult();
setView(client);
}
});
}
}

View File

@ -0,0 +1,60 @@
package com.biomed.client.activity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.place.EditWorkorderPlace;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.clienteditor.ClientEditorSidebarPanel.Tabs;
import com.biomed.client.ui.clienteditor.ClientWorkordersEditorPanel;
import com.biomed.shared.api.GetWorkordersAction;
import com.biomed.shared.api.ListResult;
import com.biomed.shared.api.dto.WorkorderDTO;
import com.google.gwt.view.client.ListDataProvider;
import com.google.inject.Inject;
public class EditClientWorkordersActivity extends BaseClientActivity {
@Inject
ClientWorkordersEditorPanel view;
@Inject
BiomedService biomedService;
private ListDataProvider<WorkorderDTO> dataProvider;
@Override
protected boolean showNavigationPanel() {
return true;
}
@Override
protected Tabs getTab() {
return Tabs.WORKORDERS;
}
@Override
protected void createContentPanel(SiteContainer panel) {
dataProvider = new ListDataProvider<WorkorderDTO>();
dataProvider.addDataDisplay(view.getTable());
view.activity = this;
panel.setWidget(BiomedSite.CONTENT, view);
view.showLoading();
GetWorkordersAction action = new GetWorkordersAction();
action.setClientId(getClientId());
biomedService.execute(action, new DefaultCallback<ListResult<WorkorderDTO>>() {
@Override
public void onSuccess(ListResult<WorkorderDTO> result) {
dataProvider.setList(result.getResult());
}
});
}
public void onWorkorderClicked(int id) {
placeController.goTo(EditWorkorderPlace.getPlace(id));
}
}

View File

@ -0,0 +1,136 @@
package com.biomed.client.activity;
import java.util.List;
import javax.inject.Inject;
import com.biomed.client.AbstractBiomedActivity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.place.EditWorkorderPlace;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.workorders.EditWorkorderPanel;
import com.biomed.shared.api.DeleteWorkorderAction;
import com.biomed.shared.api.EmptyResult;
import com.biomed.shared.api.GetUsersAction;
import com.biomed.shared.api.GetWorkorderViewAction;
import com.biomed.shared.api.ListResult;
import com.biomed.shared.api.SaveWorkorderAction;
import com.biomed.shared.api.SingleResult;
import com.biomed.shared.api.dto.EditWorkorderViewDTO;
import com.biomed.shared.api.dto.ScheduleTime;
import com.biomed.shared.api.dto.UserDTO;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.web.bindery.event.shared.EventBus;
public class EditWorkorderActivity extends AbstractBiomedActivity {
@Inject
BiomedService biomedService;
@Inject
EditWorkorderPanel view;
private List<UserDTO> techs;
@Override
public void start(SiteContainer container, EventBus eventBus) {
container.setWidget(BiomedSite.CONTENT, view);
view.getStartTimeField().setValue(ScheduleTime.H8M00A);
view.getStartTimeField().setAcceptableValues(ScheduleTime.getValues());
view.getEndTimeField().setValue(ScheduleTime.H5M00P);
view.getEndTimeField().setAcceptableValues(ScheduleTime.getValues());
view.getSaveButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
SaveWorkorderAction action = new SaveWorkorderAction();
action.setWorkorderReason(view.getWorkorderReasonField().getValue());
action.setWorkorderStatus(view.getWorkorderStatusField().getValue());
action.setActionTaken(view.getActionTakenField().getValue());
action.setRemarks(view.getRemarksField().getValue());
action.setId(getWorkorderId());
action.setTechId(view.getTechField().getValue().getId());
action.setJobDate(view.getWorkorderJobDateField().getValue());
action.setStartTime(view.getStartTimeField().getValue());
action.setEndTime(view.getEndTimeField().getValue());
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
}
});
}
});
view.getDeleteButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (Window.confirm("Are you sure you wish to delete this workorder?")) {
DeleteWorkorderAction action = new DeleteWorkorderAction();
action.setWorkorderId(getWorkorderId());
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
History.back();
}
});
}
}
});
loadTechList();
}
private void loadTechList() {
GetUsersAction action = new GetUsersAction();
action.setUserTypeId(1);
biomedService.execute(action, new DefaultCallback<ListResult<UserDTO>>() {
@Override
public void onSuccess(ListResult<UserDTO> result) {
techs = result.getResult();
view.getTechField().setAcceptableValues(techs);
loadWorkorder();
}
});
}
private void loadWorkorder() {
GetWorkorderViewAction action = new GetWorkorderViewAction();
action.setWorkorderId(getWorkorderId());
biomedService.execute(action, new DefaultCallback<SingleResult<EditWorkorderViewDTO>>() {
@Override
public void onSuccess(SingleResult<EditWorkorderViewDTO> result) {
EditWorkorderViewDTO data = result.getResult();
view.setStaticValues(data);
view.getStartTimeField().setValue(data.getWorkorderStartTime());
view.getEndTimeField().setValue(data.getWorkorderEndTime());
view.getWorkorderJobDateField().setValue(data.getWorkorderJobDate());
for (UserDTO tech : techs) {
if (tech.getId() == data.getTechId()) {
view.getTechField().setValue(tech);
break;
}
}
}
});
}
protected int getWorkorderId() {
return ((EditWorkorderPlace) place).getId();
}
}

View File

@ -0,0 +1,36 @@
package com.biomed.client.activity;
import javax.inject.Inject;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.place.ViewClientsPlace;
import com.biomed.client.services.BiomedService;
import com.biomed.shared.api.dto.ClientDTO;
import com.google.gwt.place.shared.PlaceController;
public class NewClientActivity extends BaseClientOverviewActivity {
@Inject PlaceController placeController;
@Inject BiomedService biomedService;
@Override
protected boolean showNavigationPanel() {
return false;
}
@Override
protected void createContentPanel(final SiteContainer panel) {
setupEvents();
client = new ClientDTO();
setView(client);
panel.setWidget(BiomedSite.CONTENT, view);
}
@Override
protected void onSaveComplete() {
placeController.goTo(ViewClientsPlace.INSTANCE);
}
}

View File

@ -0,0 +1,63 @@
package com.biomed.client.activity;
import java.util.Arrays;
import javax.inject.Inject;
import com.biomed.client.AbstractBiomedActivity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.messages.MessageFor;
import com.biomed.client.ui.messages.MessagesPanel;
import com.biomed.shared.api.EmptyResult;
import com.biomed.shared.api.SendMessageAction;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.History;
import com.google.web.bindery.event.shared.EventBus;
public class NewMessageActivity extends AbstractBiomedActivity {
@Inject BiomedService biomedService;
@Inject MessagesPanel view;
@Override
public void start(SiteContainer container, EventBus eventBus) {
container.setWidget(BiomedSite.CONTENT, view);
view.getMessageForField().setValue(MessageFor.ChrisEndres);
view.getMessageForField().setAcceptableValues(Arrays.asList(MessageFor.values()));
view.getSendButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
SendMessageAction action = new SendMessageAction();
action.setUserId(view.getMessageForField().getValue().getId());
action.setName(view.getNameField().getValue());
action.setCompany(view.getCompanyField().getValue());
action.setPhone(view.getPhoneField().getValue());
action.setPhoneExtension(view.getPhoneExtensionField().getValue());
action.setTimeToReturnCall(view.getTimeToReturnCallField().getValue());
action.setTelephoned(view.getTelephonedField().getValue());
action.setCameToSeeYou(view.getCameToSeeYouField().getValue());
action.setWantsToSeeYou(view.getWantsToSeeYouField().getValue());
action.setReturnedYourCall(view.getReturnedYourCallField().getValue());
action.setPleaseCall(view.getPleaseCallField().getValue());
action.setWillCallAgain(view.getWillCallAgainField().getValue());
action.setRush(view.getRushField().getValue());
action.setSpecialAttention(view.getSpecialAttentionField().getValue());
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
History.back();
}
});
}
});
}
}

View File

@ -0,0 +1,72 @@
package com.biomed.client.activity;
import javax.inject.Inject;
import com.biomed.client.AbstractBiomedActivity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.place.EditClientOverviewPlace;
import com.biomed.client.place.NewClientPlace;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.clientlist.ClientListPanel;
import com.biomed.client.ui.clientlist.ClientListSidebarPanel;
import com.biomed.shared.api.GetClientsAction;
import com.biomed.shared.api.GetClientsAction.View;
import com.biomed.shared.api.ListResult;
import com.biomed.shared.api.dto.ClientDTO;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.view.client.ListDataProvider;
import com.google.web.bindery.event.shared.EventBus;
public class ViewClientsActivity extends AbstractBiomedActivity {
@Inject ClientListPanel view;
@Inject ClientListSidebarPanel sidebar;
@Inject PlaceController placeController;
@Inject BiomedService biomedService;
private ListDataProvider<ClientDTO> dataProvider;
private String filter;
@Override
public void start(SiteContainer container, EventBus eventBus) {
view.activity = this;
sidebar.activity = this;
dataProvider = new ListDataProvider<ClientDTO>();
dataProvider.addDataDisplay(view.getTable());
container.setWidget(BiomedSite.CONTENT, view);
container.setWidget(BiomedSite.SIDEBAR, sidebar);
requestData();
}
public void onNewClientClicked() {
placeController.goTo(NewClientPlace.INSTANCE);
}
public void onClientClicked(int id) {
placeController.goTo(EditClientOverviewPlace.getPlace(id));
}
private void requestData() {
view.showLoading();
GetClientsAction action = new GetClientsAction();
action.setView(View.CLIENT_PREVIEW);
action.setFilter(filter);
biomedService.execute(action, new DefaultCallback<ListResult<ClientDTO>>() {
@Override
public void onSuccess(ListResult<ClientDTO> result) {
dataProvider.setList(result.getResult());
}
});
}
public void filterTable(String filter) {
this.filter = filter;
requestData();
}
}

View File

@ -0,0 +1,214 @@
package com.biomed.client.activity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import com.biomed.client.AbstractBiomedActivity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.schedule.DateUtil;
import com.biomed.client.ui.schedule.SchedulePanel;
import com.biomed.client.ui.schedule.ScheduleSidebarPanel;
import com.biomed.client.ui.schedule.Workorder;
import com.biomed.shared.api.EmptyResult;
import com.biomed.shared.api.GetClientsAction;
import com.biomed.shared.api.GetClientsAction.View;
import com.biomed.shared.api.GetUsersAction;
import com.biomed.shared.api.ListResult;
import com.biomed.shared.api.PropertyBag;
import com.biomed.shared.api.ScheduleAction;
import com.biomed.shared.api.SendTechScheduleEmailAction;
import com.biomed.shared.api.SqlResultSet;
import com.biomed.shared.api.dto.ClientDTO;
import com.biomed.shared.api.dto.ScheduleTime;
import com.biomed.shared.api.dto.UserDTO;
import com.biomed.shared.api.dto.WorkorderReasonDTO;
import com.biomed.shared.api.dto.WorkorderStatusDTO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.google.web.bindery.event.shared.EventBus;
public class ViewScheduleActivity extends AbstractBiomedActivity {
private static final DateTimeFormat format = DateTimeFormat.getFormat("yyyy-MM-dd");
@Inject
SchedulePanel view;
@Inject
ScheduleSidebarPanel sidebar;
@Inject
BiomedService biomedService;
int colorIndex = 0;
private Map<Integer, Integer> techColorMap;
private Date currentDate = new Date();
private int techId = 0;
@Override
public void start(SiteContainer container, EventBus eventBus) {
sidebar.activity = this;
container.setWidget(BiomedSite.CONTENT, view);
container.setWidget(BiomedSite.SIDEBAR, sidebar);
loadTechList();
loadClients();
sidebar.getWorkorderStatusField().setValue(WorkorderStatusDTO.PM_DUE);
sidebar.getWorkorderStatusField().setAcceptableValues(WorkorderStatusDTO.VALUES);
sidebar.getStartTimeField().setValue(ScheduleTime.H8M00A);
sidebar.getStartTimeField().setAcceptableValues(ScheduleTime.getValues());
sidebar.getEndTimeField().setValue(ScheduleTime.H5M00P);
sidebar.getEndTimeField().setAcceptableValues(ScheduleTime.getValues());
sidebar.getReasonField().setValue(WorkorderReasonDTO.PM_RESCHEDULE);
sidebar.getReasonField().setAcceptableValues(WorkorderReasonDTO.VALUES);
sidebar.getSaveButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
saveWorkorder();
}
});
}
public void setTechId(int techId) {
this.techId = techId;
updateView();
}
public void setDate(Date currentDate) {
this.currentDate = currentDate;
updateView();
}
private void saveWorkorder() {
ScheduleAction action = new ScheduleAction();
action.setJobDate(sidebar.getJobDateField().getValue());
action.setClientId(sidebar.getClientField().getValue().getId());
action.setTechId(sidebar.getTechField().getValue().getId());
action.setStartTime(sidebar.getStartTimeField().getValue());
action.setEndTime(sidebar.getEndTimeField().getValue());
action.setReason(sidebar.getReasonField().getValue());
action.setRequestedBy(sidebar.getRequestedByField().getValue());
action.setRemarks(sidebar.getRemarksField().getValue());
action.setStatus(sidebar.getWorkorderStatusField().getValue());
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
updateView();
}
});
}
public void sendReport() {
SendTechScheduleEmailAction action = new SendTechScheduleEmailAction();
action.setUserId(sidebar.getReportTechField().getValue().getId());
action.setDate(sidebar.getReportDateField().getValue());
biomedService.execute(action, new DefaultCallback<EmptyResult>() {
@Override
public void onSuccess(EmptyResult result) {
}
});
}
private void updateView() {
if (techId != 0) {
loadScheduleForTech(currentDate, techId);
} else {
loadScheduleForDay(currentDate);
}
}
private void loadTechList() {
GetUsersAction action = new GetUsersAction();
action.setUserTypeId(1);
biomedService.execute(action, new DefaultCallback<ListResult<UserDTO>>() {
@Override
public void onSuccess(ListResult<UserDTO> result) {
colorIndex = 0;
techColorMap = Maps.newHashMap();
for (UserDTO user : result.getResult()) {
techColorMap.put(user.getId(), colorIndex);
colorIndex = (colorIndex + 1) % 12;
}
sidebar.setTechList(result.getResult());
loadScheduleForDay(DateUtil.getNextWorkDay(new Date()));
}
});
}
private void loadScheduleForDay(final Date day) {
biomedService.getSchedule(format.format(day), format.format(day), 0,
new DefaultCallback<SqlResultSet>() {
@Override
public void onSuccess(SqlResultSet result) {
List<Workorder> workorders = Lists.newArrayList();
for (PropertyBag bag : result.results) {
Workorder workorder = new Workorder(bag);
workorder.color = techColorMap.get(workorder.techId);
workorders.add(workorder);
}
view.setView(day, 1);
view.addWorkorders(workorders);
}
});
}
private void loadScheduleForTech(final Date date, final int techId) {
final Date startDate = DateUtil.getWorkFirstDay(date);
final Date endDate = DateUtil.addDays(date, 5);
biomedService.getSchedule(format.format(startDate), format.format(endDate), techId,
new DefaultCallback<SqlResultSet>() {
@Override
public void onSuccess(SqlResultSet result) {
List<Workorder> workorders = Lists.newArrayList();
for (PropertyBag bag : result.results) {
Workorder workorder = new Workorder(bag);
workorder.color = techColorMap.get(workorder.techId);
workorders.add(workorder);
}
view.setView(startDate, 5);
view.addWorkorders(workorders);
}
});
}
private void loadClients() {
GetClientsAction action = new GetClientsAction();
action.setView(View.NAMES_ONLY);
biomedService.execute(action, new DefaultCallback<ListResult<ClientDTO>>() {
@Override
public void onSuccess(ListResult<ClientDTO> result) {
ArrayList<ClientDTO> results = result.getResult();
Collections.sort(results, new ClientDTO.IdentifierComparator());
sidebar.getClientField().setAcceptableValues(results);
}
});
}
}

View File

@ -0,0 +1,133 @@
package com.biomed.client.activity;
import java.util.ArrayList;
import java.util.Collections;
import javax.inject.Inject;
import com.biomed.client.AbstractBiomedActivity;
import com.biomed.client.BiomedActivityManager.SiteContainer;
import com.biomed.client.BiomedSite;
import com.biomed.client.dispatch.DefaultCallback;
import com.biomed.client.place.EditWorkorderPlace;
import com.biomed.client.services.BiomedService;
import com.biomed.client.ui.workorders.WorkordersPanel;
import com.biomed.client.ui.workorders.WorkordersSidebarPanel;
import com.biomed.shared.api.GetClientsAction;
import com.biomed.shared.api.GetClientsAction.View;
import com.biomed.shared.api.GetUsersAction;
import com.biomed.shared.api.GetWorkordersAction;
import com.biomed.shared.api.ListResult;
import com.biomed.shared.api.dto.ClientDTO;
import com.biomed.shared.api.dto.UserDTO;
import com.biomed.shared.api.dto.WorkorderDTO;
import com.biomed.shared.api.dto.WorkorderStatusDTO;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.view.client.ListDataProvider;
import com.google.web.bindery.event.shared.EventBus;
public class ViewWorkordersActivity extends AbstractBiomedActivity {
@Inject
WorkordersPanel view;
@Inject
WorkordersSidebarPanel sidebar;
@Inject
BiomedService biomedService;
@Inject
PlaceController placeController;
private ListDataProvider<WorkorderDTO> dataProvider;
@Override
public void start(SiteContainer container, EventBus eventBus) {
view.activity = this;
dataProvider = new ListDataProvider<WorkorderDTO>();
dataProvider.addDataDisplay(view.getTable());
container.setWidget(BiomedSite.CONTENT, view);
container.setWidget(BiomedSite.SIDEBAR, sidebar);
sidebar.getSearchButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
requestData();
}
});
sidebar.getWorkorderStatusField().setAcceptableValues(WorkorderStatusDTO.VALUES);
loadUsers();
loadClients();
}
public void onWorkorderClicked(int id) {
placeController.goTo(EditWorkorderPlace.getPlace(id));
}
private void loadUsers() {
GetUsersAction action = new GetUsersAction();
action.setUserTypeId(1);
biomedService.execute(action, new DefaultCallback<ListResult<UserDTO>>() {
@Override
public void onSuccess(ListResult<UserDTO> result) {
ArrayList<UserDTO> results = result.getResult();
Collections.sort(results, new UserDTO.DisplayNameComparator());
sidebar.getTechField().setAcceptableValues(results);
}
});
}
private void loadClients() {
GetClientsAction action = new GetClientsAction();
action.setView(View.NAMES_ONLY);
biomedService.execute(action, new DefaultCallback<ListResult<ClientDTO>>() {
@Override
public void onSuccess(ListResult<ClientDTO> result) {
ArrayList<ClientDTO> results = result.getResult();
Collections.sort(results, new ClientDTO.IdentifierComparator());
sidebar.getClientField().setAcceptableValues(results);
}
});
}
private void requestData() {
view.showLoading();
GetWorkordersAction action = new GetWorkordersAction();
action.setStartDate(sidebar.getStartDateField().getValue());
action.setEndDate(sidebar.getEndDateField().getValue());
UserDTO tech = sidebar.getTechField().getValue();
if (tech != null) {
action.setTechId(tech.getId());
}
WorkorderStatusDTO status = sidebar.getWorkorderStatusField().getValue();
if (status != null) {
action.setWorkorderStatusId(status.getId());
}
ClientDTO client = sidebar.getClientField().getValue();
if (client != null) {
action.setClientId(client.getId());
}
biomedService.execute(action, new DefaultCallback<ListResult<WorkorderDTO>>() {
@Override
public void onSuccess(ListResult<WorkorderDTO> result) {
dataProvider.setList(result.getResult());
}
});
}
}

View File

@ -0,0 +1,17 @@
package com.biomed.client.components;
import java.util.Date;
import com.github.gwtbootstrap.datepicker.client.ui.base.DateBoxBase;
import com.google.gwt.user.client.ui.SimplePanel;
public class DatePicker extends DateBoxBase {
private final SimplePanel panel;
public DatePicker() {
this.panel = new SimplePanel();
setElement(panel.getElement());
setValue(new Date());
}
}

View File

@ -0,0 +1,16 @@
package com.biomed.client.components;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.client.ui.Widget;
public class HeaderPanel extends Widget {
interface Binder extends UiBinder<DivElement, HeaderPanel> {}
private static Binder binder = GWT.create(Binder.class);
public HeaderPanel() {
setElement(binder.createAndBindUi(this));
}
}

View File

@ -0,0 +1,14 @@
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<div id="top">
<div class="wrapper">
<div class="logo"></div>
<a href="#" title="" class="logoText">Atlantic Biomedical</a>
<div class="topNav">
<ul class="userNav">
</ul>
</div>
</div>
</div>
</ui:UiBinder>

View File

@ -0,0 +1,93 @@
package com.biomed.client.components;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.biomed.client.place.ClientsPlace;
import com.biomed.client.place.MessagesPlace;
import com.biomed.client.place.NewMessagePlace;
import com.biomed.client.place.SchedulePlace;
import com.biomed.client.place.ViewClientsPlace;
import com.biomed.client.place.ViewSchedulePlace;
import com.biomed.client.place.ViewWorkordersPlace;
import com.biomed.client.place.WorkordersPlace;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.web.bindery.event.shared.EventBus;
@Singleton
public class NavigationPanel extends Composite implements PlaceChangeEvent.Handler {
interface Binder extends UiBinder<HTMLPanel, NavigationPanel> {}
private final PlaceController placeController;
@UiField Anchor scheduleLink;
@UiField Anchor clientsLink;
@UiField Anchor messagesLink;
@UiField Anchor workordersLink;
Anchor activeLink;
@Inject
public NavigationPanel(PlaceController placeController, EventBus eventBus, Binder binder) {
this.placeController = placeController;
eventBus.addHandler(PlaceChangeEvent.TYPE, this);
initWidget(binder.createAndBindUi(this));
}
@UiHandler("scheduleLink")
void onScheduleLinkClicked(ClickEvent event) {
placeController.goTo(ViewSchedulePlace.INSTANCE);
}
@UiHandler("clientsLink")
void onClientsLinkClicked(ClickEvent event) {
placeController.goTo(ViewClientsPlace.INSTANCE);
}
@UiHandler("messagesLink")
void onMessagesLinkClicked(ClickEvent event) {
placeController.goTo(NewMessagePlace.INSTANCE);
}
@UiHandler("workordersLink")
void onWorkordersLinkClicked(ClickEvent event) {
placeController.goTo(ViewWorkordersPlace.INSTANCE);
}
@Override
public void onPlaceChange(PlaceChangeEvent event) {
Place place = event.getNewPlace();
if (place instanceof ClientsPlace) {
setLinkActive(clientsLink);
} else if (place instanceof MessagesPlace) {
setLinkActive(messagesLink);
} else if (place instanceof SchedulePlace) {
setLinkActive(scheduleLink);
} else if (place instanceof WorkordersPlace) {
setLinkActive(workordersLink);
} else {
setLinkActive(null);
}
}
private void setLinkActive(Anchor link) {
if (activeLink != null) {
activeLink.removeStyleName("active");
}
activeLink = link;
activeLink.addStyleName("active");
}
}

View File

@ -0,0 +1,37 @@
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<g:HTMLPanel>
<ul ui:field="navigation" class="mainNav">
<li>
<g:Anchor ui:field="scheduleLink" title="">
<img src="resources/images/icons/mainnav/tables.png" alt="" />
<span>Schedule</span>
</g:Anchor>
</li>
<li>
<g:Anchor ui:field="workordersLink" title="">
<img src="resources/images/icons/mainnav/dashboard.png" alt="" />
<span>Workorders</span>
</g:Anchor>
</li>
<li>
<g:Anchor ui:field="clientsLink" title="">
<img src="resources/images/icons/mainnav/clients.png" alt="" />
<span>Clients</span>
</g:Anchor>
</li>
<li>
<g:Anchor ui:field="messagesLink" title="">
<img src="resources/images/icons/mainnav/messages.png" alt="" />
<span>Messages</span>
</g:Anchor>
</li>
<li>
<a href="http://atlanticbiomedical.com/ticket/" target="_blank">
<img src="resources/images/icons/mainnav/forms.png" alt="" />
<span>Tickets</span>
</a>
</li>
</ul>
</g:HTMLPanel>
</ui:UiBinder>

View File

@ -0,0 +1,251 @@
package com.biomed.client.components;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.cellview.client.AbstractPager;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.view.client.HasRows;
import com.google.gwt.view.client.Range;
public class Pager extends AbstractPager {
private final Label label;
private final Image loading;
private final Anchor firstPage;
private final Anchor prevPage;
private final Anchor nextPage;
private final Anchor lastPage;
public Pager() {
label = new Label();
label.setStyleName("dataTables_info");
loading = new Image();
loading.setStyleName("loading");
loading.setUrl("resources/images/elements/loaders/9.gif");
loading.setVisible(false);
firstPage = new Anchor("First");
firstPage.setStyleName("first paginate_button");
firstPage.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
firstPage();
}
});
prevPage = new Anchor("Previous");
prevPage.setStyleName("previous paginate_button");
prevPage.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
previousPage();
}
});
nextPage = new Anchor("Next");
nextPage.setStyleName("next paginate_button");
nextPage.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
nextPage();
}
});
lastPage = new Anchor("Last");
lastPage.setStyleName("last paginate_button");
lastPage.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
lastPage();
}
});
FlowPanel buttonsPanel = new FlowPanel();
buttonsPanel.setStyleName("dataTables_paginate paging_full_numbers");
buttonsPanel.add(firstPage);
buttonsPanel.add(prevPage);
buttonsPanel.add(nextPage);
buttonsPanel.add(lastPage);
FlowPanel layout = new FlowPanel();
layout.setStyleName("tableFooter");
layout.add(loading);
layout.add(label);
layout.add(buttonsPanel);
initWidget(layout);
setDisplay(null);
}
@Override
public void setDisplay(HasRows display) {
boolean disableButtons = (display == null);
setNextPageButtonsDisabled(disableButtons);
setPrevPageButtonsDisabled(disableButtons);
super.setDisplay(display);
}
public void startLoading() {
getDisplay().setRowCount(0, true);
loading.setVisible(true);
label.setText("Loading...");
}
protected String createText() {
// Default text is 1 based.
NumberFormat formatter = NumberFormat.getFormat("#,###");
HasRows display = getDisplay();
Range range = display.getVisibleRange();
int pageStart = range.getStart() + 1;
int pageSize = range.getLength();
int dataSize = display.getRowCount();
int endIndex = Math.min(dataSize, pageStart + pageSize - 1);
endIndex = Math.max(pageStart, endIndex);
boolean exact = display.isRowCountExact();
return "Showing " + formatter.format(pageStart) + " to " + formatter.format(endIndex)
+ (exact ? " of " : " of over ") + formatter.format(dataSize) + " entries";
}
@Override
protected void onRangeOrRowCountChanged() {
HasRows display = getDisplay();
label.setText(createText());
loading.setVisible(false);
// Update the prev and first buttons.
setPrevPageButtonsDisabled(!hasPreviousPage());
// Update the next and last buttons.
if (isRangeLimited() || !display.isRowCountExact()) {
setNextPageButtonsDisabled(!hasNextPage());
// setFastForwardDisabled(!hasNextPages(getFastForwardPages()));
}
}
/**
* Enable or disable the next page buttons.
*
* @param disabled true to disable, false to enable
*/
private void setNextPageButtonsDisabled(boolean disabled) {
if (disabled) {
lastPage.addStyleName("paginate_button_disabled");
nextPage.addStyleName("paginate_button_disabled");
} else {
lastPage.removeStyleName("paginate_button_disabled");
nextPage.removeStyleName("paginate_button_disabled");
}
lastPage.setEnabled(!disabled);
nextPage.setEnabled(!disabled);
}
/**
* Enable or disable the previous page buttons.
*
* @param disabled true to disable, false to enable
*/
private void setPrevPageButtonsDisabled(boolean disabled) {
if (disabled) {
firstPage.addStyleName("paginate_button_disabled");
prevPage.addStyleName("paginate_button_disabled");
} else {
firstPage.removeStyleName("paginate_button_disabled");
prevPage.removeStyleName("paginate_button_disabled");
}
firstPage.setEnabled(!disabled);
prevPage.setEnabled(!disabled);
}
@Override
public void firstPage() {
super.firstPage();
}
@Override
public int getPage() {
return super.getPage();
}
@Override
public int getPageCount() {
return super.getPageCount();
}
@Override
public boolean hasNextPage() {
return super.hasNextPage();
}
@Override
public boolean hasNextPages(int pages) {
return super.hasNextPages(pages);
}
@Override
public boolean hasPage(int index) {
return super.hasPage(index);
}
@Override
public boolean hasPreviousPage() {
return super.hasPreviousPage();
}
@Override
public boolean hasPreviousPages(int pages) {
return super.hasPreviousPages(pages);
}
@Override
public void lastPage() {
super.lastPage();
}
@Override
public void lastPageStart() {
super.lastPageStart();
}
@Override
public void nextPage() {
super.nextPage();
}
@Override
public void previousPage() {
super.previousPage();
}
@Override
public void setPage(int index) {
super.setPage(index);
}
@Override
public void setPageSize(int pageSize) {
super.setPageSize(pageSize);
}
@Override
public void setPageStart(int index) {
super.setPageStart(index);
}
}

View File

@ -0,0 +1,14 @@
package com.biomed.client.dispatch;
import javax.inject.Singleton;
import com.biomed.shared.dispatch.DispatchAsync;
import com.google.gwt.inject.client.AbstractGinModule;
public class ClientDispatchGinModule extends AbstractGinModule {
@Override
protected void configure() {
bind(DispatchAsync.class).to(DefaultDispatchAsync.class).in(Singleton.class);
}
}

View File

@ -0,0 +1,10 @@
package com.biomed.client.dispatch;
import com.google.gwt.user.client.rpc.AsyncCallback;
public abstract class DefaultCallback<T> implements AsyncCallback<T> {
@Override
public void onFailure(Throwable caught) {
throw new RuntimeException(caught);
}
}

View File

@ -0,0 +1,31 @@
package com.biomed.client.dispatch;
import com.biomed.shared.dispatch.DispatchAction;
import com.biomed.shared.dispatch.DispatchAsync;
import com.biomed.shared.dispatch.DispatchService;
import com.biomed.shared.dispatch.DispatchServiceAsync;
import com.biomed.shared.dispatch.DispatchResult;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class DefaultDispatchAsync implements DispatchAsync {
private static final DispatchServiceAsync realService = GWT.create(DispatchService.class);
public DefaultDispatchAsync() {
}
public <A extends DispatchAction<R>, R extends DispatchResult> void execute(final A action,
final AsyncCallback<R> callback) {
realService.execute(action, new AsyncCallback<DispatchResult>() {
public void onFailure(Throwable caught) {
callback.onFailure(caught);
}
@SuppressWarnings("unchecked")
public void onSuccess(DispatchResult result) {
callback.onSuccess((R) result);
}
});
}
}

View File

@ -0,0 +1,5 @@
package com.biomed.client.place;
import com.google.gwt.place.shared.Place;
public abstract class BiomedPlace extends Place { }

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