From 64176caa972fdf925fe244cdbf1d53d82da592f4 Mon Sep 17 00:00:00 2001 From: Jacob Thornton Date: Sat, 10 Sep 2011 22:14:57 -0700 Subject: add bootstrap-scrollspy --- js/bootstrap-modal.js | 3 ++ js/bootstrap-scrollspy.js | 88 ++++++++++++++++++++++++++++++++++++ js/tests/unit/bootstrap-modal.js | 68 ++++++++++++++++++++-------- js/tests/unit/bootstrap-scrollspy.js | 31 +++++++++++++ 4 files changed, 171 insertions(+), 19 deletions(-) create mode 100644 js/bootstrap-scrollspy.js create mode 100644 js/tests/unit/bootstrap-scrollspy.js (limited to 'js') diff --git a/js/bootstrap-modal.js b/js/bootstrap-modal.js index a7ab252eb..f1e795668 100644 --- a/js/bootstrap-modal.js +++ b/js/bootstrap-modal.js @@ -59,6 +59,7 @@ this.isShown = true _.escape.call(this) + _.backdrop.call(this, function () { that.$element .appendTo(document.body) @@ -133,6 +134,8 @@ $.support.transition && this.$element.hasClass('fade')? this.$backdrop.one(transitionEnd, removeElement) : removeElement() + } else { + callback() } } diff --git a/js/bootstrap-scrollspy.js b/js/bootstrap-scrollspy.js new file mode 100644 index 000000000..c492e2fee --- /dev/null +++ b/js/bootstrap-scrollspy.js @@ -0,0 +1,88 @@ +/* ============================================================= + * bootstrap-scrollspy.js + * http://twitter.github.com/bootstrap/javascript.html#scrollspy + * ============================================================= + * Copyright 2011 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 ( $ ) { + + var $window = $(window) + + function ScrollSpy( topbar ) { + var processScroll = $.proxy(this.processScroll, this) + this.$topbar = $(topbar) + this.setup() + this.$topbar + .delegate('li > a', 'click', processScroll) + .bind('topbar:refresh', $.proxy(this.setup, this)) + $window.scroll(processScroll) + this.processScroll() + } + + ScrollSpy.prototype = { + + setup: function () { + this.targets = this.$topbar.find('li > a').map(function () { + var href = $(this).attr('href') + return /^#\w/.test(href) && $(href).length ? href : null + }) + + this.offsets = $.map(this.targets, function (id) { + return $(id).offset().top + }) + } + + , processScroll: function () { + var scrollTop = $window.scrollTop() + 10 + , offsets = this.offsets + , targets = this.targets + , activeTarget = this.activeTarget + , i + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) + && this.activateButton( targets[i] ) + } + } + + , activateButton: function (target) { + this.activeTarget = target + + this.$topbar + .find('.active') + .removeClass('active') + + this.$topbar + .find('a[href=' + target + ']') + .parent('li') + .addClass('active') + } + + } + + /* SCROLLSPY PLUGIN DEFINITION + * =========================== */ + + $.fn.scrollSpy = function() { + return this.each(function () { + new ScrollSpy(this) + }) + } + +}( jQuery || ender ) \ No newline at end of file diff --git a/js/tests/unit/bootstrap-modal.js b/js/tests/unit/bootstrap-modal.js index cfdf4064d..513d28780 100644 --- a/js/tests/unit/bootstrap-modal.js +++ b/js/tests/unit/bootstrap-modal.js @@ -17,40 +17,70 @@ $(function () { }) test("should insert into dom when modal:show event is called", function () { + stop() $.support.transition = false var div = $("") - div.modal().trigger("modal:show") - ok($('#modal-test').length, 'modal insterted into dom') - div.remove() + div + .modal() + .trigger("modal:show") + .bind("modal:shown", function () { + ok($('#modal-test').length, 'modal insterted into dom') + start() + div.remove() + }) }) - test("should remove from dom when close is called", function () { + test("should remove from dom when modal:hide is called", function () { + stop() $.support.transition = false var div = $("") - div.modal().trigger("modal:show") - ok($('#modal-test').length, 'modal insterted into dom') - div.trigger("modal:hide") - ok(!$('#modal-test').length, 'modal removed from dom') - div.remove() + div + .modal() + .trigger("modal:show") + .bind("modal:shown", function () { + ok($('#modal-test').length, 'modal insterted into dom') + div.trigger("modal:hide") + }) + .bind("modal:hidden", function() { + ok(!$('#modal-test').length, 'modal removed from dom') + start() + div.remove() + }) }) test("should toggle when toggle is called", function () { + stop() $.support.transition = false var div = $("") - div.modal().trigger("modal:toggle") - ok($('#modal-test').length, 'modal insterted into dom') - div.trigger("modal:toggle") - ok(!$('#modal-test').length, 'modal removed from dom') - div.remove() + div + .modal() + .trigger("modal:toggle") + .bind("modal:shown", function () { + ok($('#modal-test').length, 'modal insterted into dom') + div.trigger("modal:toggle") + }) + .bind("modal:hidden", function() { + ok(!$('#modal-test').length, 'modal removed from dom') + start() + div.remove() + }) }) test("should remove from dom when click .close", function () { + stop() $.support.transition = false var div = $("") - div.modal().trigger("modal:toggle") - ok($('#modal-test').length, 'modal insterted into dom') - div.find('.close').click() - ok(!$('#modal-test').length, 'modal removed from dom') - div.remove() + div + .modal() + .trigger("modal:toggle") + .bind("modal:shown", function () { + ok($('#modal-test').length, 'modal insterted into dom') + div.find('.close').click() + }) + .bind("modal:hidden", function() { + ok(!$('#modal-test').length, 'modal removed from dom') + start() + div.remove() + }) }) }) \ No newline at end of file diff --git a/js/tests/unit/bootstrap-scrollspy.js b/js/tests/unit/bootstrap-scrollspy.js new file mode 100644 index 000000000..b9b309062 --- /dev/null +++ b/js/tests/unit/bootstrap-scrollspy.js @@ -0,0 +1,31 @@ +$(function () { + + module("bootstrap-scrollspy") + + test("should be defined on jquery object", function () { + ok($(document.body).scrollspy, 'scrollspy method is defined') + }) + + test("should return element", function () { + ok($(document.body).scrollspy()[0] == document.body, 'document.body returned') + }) + + test("should switch active class on scroll", function () { + var sectionHTML = '
' + , $section = $(sectionHTML).append('#qunit-runoff') + , topbarHTML ='
' + + '
' + + '
' + + '

Bootstrap

' + + '' + + '
' + + '
' + + '
' + , $topbar = $(topbarHTML).topbar() + + ok(topbar.find('.active', true) + }) + +}) \ No newline at end of file -- cgit v1.2.3