beautiful_scaffold 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -1,10 +1,43 @@
1
- Beautiful Scaffold is a gem which propose generators for a complete scaffold with paginate, sort and filter.
1
+ = Beautiful Scaffold
2
+
3
+ Beautiful Scaffold is a gem which propose generators for a complete scaffold with paginate, sort and filter.
2
4
  Fully customizable.
5
+ More info : http://www.beautiful-scaffold.com/
6
+ Demo : http://demo.beautiful-scaffold.com/
7
+
8
+ == Install
9
+
10
+ Add this in your Gemfile :
11
+ gem 'beautiful_scaffold', '0.1.8'
12
+ And run
13
+ bundle install
14
+
15
+ == Usage
16
+
17
+ === Scaffold
3
18
 
4
- rails generate beautiful_scaffold mode attr:type attr:type... [--namespace=name]
19
+ rails generate beautiful_scaffold model attr:type attr:type... [--namespace=name]
20
+
21
+ type available :
22
+ * integer
23
+ * float
24
+ * text
25
+ * string
26
+ * price
27
+ * color
28
+ * richtext
29
+ * wysiwyg
5
30
 
6
31
  # Example : products
7
32
  rails generate beautiful_scaffold product name:string price:price tva:float description:richtext visible:boolean && rake db:migrate
8
33
 
9
34
  # Example : admin products
10
35
  rails generate beautiful_scaffold product name:string price:price tva:float description:richtext overview_description:richtext visible:boolean --namespace=admin && rake db:migrate
36
+
37
+ === Locale (i18n)
38
+
39
+ rails generate beautiful_locale all
40
+
41
+ === Join Table (has_and_belongs_to_many relation)
42
+
43
+ rails generate beautiful_jointable model1 model2
@@ -3,12 +3,12 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "beautiful_scaffold"
6
- s.version = "0.1.8"
6
+ s.version = "0.1.9"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.summary = "Beautiful Scaffold generate fully customizable scaffold"
9
9
  s.email = "claudel.sylvain@gmail.com"
10
10
  s.homepage = "http://beautiful-scaffold.com"
11
- s.description = "Beautiful Scaffold generate a complete scaffold (sort, export, paginate and filter data)"
11
+ s.description = "Beautiful Scaffold generate a complete scaffold (sort, export, paginate and filter data) http://www.beautiful-scaffold.com"
12
12
  s.authors = ['Sylvain Claudel']
13
13
  s.files = `git ls-files`.split("\n")
14
14
 
@@ -1,5 +1,5 @@
1
1
  /* ===================================================
2
- * bootstrap-transition.js v2.0.4
2
+ * bootstrap-transition.js v2.1.0
3
3
  * http://twitter.github.com/bootstrap/javascript.html#transitions
4
4
  * ===================================================
5
5
  * Copyright 2012 Twitter, Inc.
@@ -36,8 +36,7 @@
36
36
  , transEndEventNames = {
37
37
  'WebkitTransition' : 'webkitTransitionEnd'
38
38
  , 'MozTransition' : 'transitionend'
39
- , 'OTransition' : 'oTransitionEnd'
40
- , 'msTransition' : 'MSTransitionEnd'
39
+ , 'OTransition' : 'oTransitionEnd otransitionend'
41
40
  , 'transition' : 'transitionend'
42
41
  }
43
42
  , name
@@ -59,7 +58,7 @@
59
58
  })
60
59
 
61
60
  }(window.jQuery);/* ==========================================================
62
- * bootstrap-alert.js v2.0.4
61
+ * bootstrap-alert.js v2.1.0
63
62
  * http://twitter.github.com/bootstrap/javascript.html#alerts
64
63
  * ==========================================================
65
64
  * Copyright 2012 Twitter, Inc.
@@ -148,7 +147,7 @@
148
147
  })
149
148
 
150
149
  }(window.jQuery);/* ============================================================
151
- * bootstrap-button.js v2.0.4
150
+ * bootstrap-button.js v2.1.0
152
151
  * http://twitter.github.com/bootstrap/javascript.html#buttons
153
152
  * ============================================================
154
153
  * Copyright 2012 Twitter, Inc.
@@ -243,7 +242,7 @@
243
242
  })
244
243
 
245
244
  }(window.jQuery);/* ==========================================================
246
- * bootstrap-carousel.js v2.0.4
245
+ * bootstrap-carousel.js v2.1.0
247
246
  * http://twitter.github.com/bootstrap/javascript.html#carousel
248
247
  * ==========================================================
249
248
  * Copyright 2012 Twitter, Inc.
@@ -290,7 +289,7 @@
290
289
  }
291
290
 
292
291
  , to: function (pos) {
293
- var $active = this.$element.find('.active')
292
+ var $active = this.$element.find('.item.active')
294
293
  , children = $active.parent().children()
295
294
  , activePos = children.index($active)
296
295
  , that = this
@@ -312,6 +311,10 @@
312
311
 
313
312
  , pause: function (e) {
314
313
  if (!e) this.paused = true
314
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
315
+ this.$element.trigger($.support.transition.end)
316
+ this.cycle()
317
+ }
315
318
  clearInterval(this.interval)
316
319
  this.interval = null
317
320
  return this
@@ -328,13 +331,15 @@
328
331
  }
329
332
 
330
333
  , slide: function (type, next) {
331
- var $active = this.$element.find('.active')
334
+ var $active = this.$element.find('.item.active')
332
335
  , $next = next || $active[type]()
333
336
  , isCycling = this.interval
334
337
  , direction = type == 'next' ? 'left' : 'right'
335
338
  , fallback = type == 'next' ? 'first' : 'last'
336
339
  , that = this
337
- , e = $.Event('slide')
340
+ , e = $.Event('slide', {
341
+ relatedTarget: $next[0]
342
+ })
338
343
 
339
344
  this.sliding = true
340
345
 
@@ -382,9 +387,10 @@
382
387
  var $this = $(this)
383
388
  , data = $this.data('carousel')
384
389
  , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
390
+ , action = typeof option == 'string' ? option : options.slide
385
391
  if (!data) $this.data('carousel', (data = new Carousel(this, options)))
386
392
  if (typeof option == 'number') data.to(option)
387
- else if (typeof option == 'string' || (option = options.slide)) data[option]()
393
+ else if (action) data[action]()
388
394
  else if (options.interval) data.cycle()
389
395
  })
390
396
  }
@@ -411,7 +417,7 @@
411
417
  })
412
418
 
413
419
  }(window.jQuery);/* =============================================================
414
- * bootstrap-collapse.js v2.0.4
420
+ * bootstrap-collapse.js v2.1.0
415
421
  * http://twitter.github.com/bootstrap/javascript.html#collapse
416
422
  * =============================================================
417
423
  * Copyright 2012 Twitter, Inc.
@@ -479,7 +485,7 @@
479
485
 
480
486
  this.$element[dimension](0)
481
487
  this.transition('addClass', $.Event('show'), 'shown')
482
- this.$element[dimension](this.$element[0][scroll])
488
+ $.support.transition && this.$element[dimension](this.$element[0][scroll])
483
489
  }
484
490
 
485
491
  , hide: function () {
@@ -556,18 +562,19 @@
556
562
  * ==================== */
557
563
 
558
564
  $(function () {
559
- $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
565
+ $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
560
566
  var $this = $(this), href
561
567
  , target = $this.attr('data-target')
562
568
  || e.preventDefault()
563
569
  || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
564
570
  , option = $(target).data('collapse') ? 'toggle' : $this.data()
571
+ $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
565
572
  $(target).collapse(option)
566
573
  })
567
574
  })
568
575
 
569
576
  }(window.jQuery);/* ============================================================
570
- * bootstrap-dropdown.js v2.0.4
577
+ * bootstrap-dropdown.js v2.1.0
571
578
  * http://twitter.github.com/bootstrap/javascript.html#dropdowns
572
579
  * ============================================================
573
580
  * Copyright 2012 Twitter, Inc.
@@ -594,7 +601,7 @@
594
601
  /* DROPDOWN CLASS DEFINITION
595
602
  * ========================= */
596
603
 
597
- var toggle = '[data-toggle="dropdown"]'
604
+ var toggle = '[data-toggle=dropdown]'
598
605
  , Dropdown = function (element) {
599
606
  var $el = $(element).on('click.dropdown.data-api', this.toggle)
600
607
  $('html').on('click.dropdown.data-api', function () {
@@ -609,34 +616,82 @@
609
616
  , toggle: function (e) {
610
617
  var $this = $(this)
611
618
  , $parent
612
- , selector
613
619
  , isActive
614
620
 
615
621
  if ($this.is('.disabled, :disabled')) return
616
622
 
617
- selector = $this.attr('data-target')
623
+ $parent = getParent($this)
618
624
 
619
- if (!selector) {
620
- selector = $this.attr('href')
621
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
625
+ isActive = $parent.hasClass('open')
626
+
627
+ clearMenus()
628
+
629
+ if (!isActive) {
630
+ $parent.toggleClass('open')
631
+ $this.focus()
622
632
  }
623
633
 
624
- $parent = $(selector)
625
- $parent.length || ($parent = $this.parent())
634
+ return false
635
+ }
636
+
637
+ , keydown: function (e) {
638
+ var $this
639
+ , $items
640
+ , $active
641
+ , $parent
642
+ , isActive
643
+ , index
644
+
645
+ if (!/(38|40|27)/.test(e.keyCode)) return
646
+
647
+ $this = $(this)
648
+
649
+ e.preventDefault()
650
+ e.stopPropagation()
651
+
652
+ if ($this.is('.disabled, :disabled')) return
653
+
654
+ $parent = getParent($this)
626
655
 
627
656
  isActive = $parent.hasClass('open')
628
657
 
629
- clearMenus()
658
+ if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
630
659
 
631
- if (!isActive) $parent.toggleClass('open')
660
+ $items = $('[role=menu] li:not(.divider) a', $parent)
632
661
 
633
- return false
662
+ if (!$items.length) return
663
+
664
+ index = $items.index($items.filter(':focus'))
665
+
666
+ if (e.keyCode == 38 && index > 0) index-- // up
667
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
668
+ if (!~index) index = 0
669
+
670
+ $items
671
+ .eq(index)
672
+ .focus()
634
673
  }
635
674
 
636
675
  }
637
676
 
638
677
  function clearMenus() {
639
- $(toggle).parent().removeClass('open')
678
+ getParent($(toggle))
679
+ .removeClass('open')
680
+ }
681
+
682
+ function getParent($this) {
683
+ var selector = $this.attr('data-target')
684
+ , $parent
685
+
686
+ if (!selector) {
687
+ selector = $this.attr('href')
688
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
689
+ }
690
+
691
+ $parent = $(selector)
692
+ $parent.length || ($parent = $this.parent())
693
+
694
+ return $parent
640
695
  }
641
696
 
642
697
 
@@ -659,14 +714,16 @@
659
714
  * =================================== */
660
715
 
661
716
  $(function () {
662
- $('html').on('click.dropdown.data-api', clearMenus)
717
+ $('html')
718
+ .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
663
719
  $('body')
664
- .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() })
665
- .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
720
+ .on('click.dropdown touchstart.dropdown.data-api', '.dropdown', function (e) { e.stopPropagation() })
721
+ .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
722
+ .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
666
723
  })
667
724
 
668
725
  }(window.jQuery);/* =========================================================
669
- * bootstrap-modal.js v2.0.4
726
+ * bootstrap-modal.js v2.1.0
670
727
  * http://twitter.github.com/bootstrap/javascript.html#modals
671
728
  * =========================================================
672
729
  * Copyright 2012 Twitter, Inc.
@@ -693,10 +750,11 @@
693
750
  /* MODAL CLASS DEFINITION
694
751
  * ====================== */
695
752
 
696
- var Modal = function (content, options) {
753
+ var Modal = function (element, options) {
697
754
  this.options = options
698
- this.$element = $(content)
755
+ this.$element = $(element)
699
756
  .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
757
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
700
758
  }
701
759
 
702
760
  Modal.prototype = {
@@ -719,8 +777,9 @@
719
777
 
720
778
  this.isShown = true
721
779
 
722
- escape.call(this)
723
- backdrop.call(this, function () {
780
+ this.escape()
781
+
782
+ this.backdrop(function () {
724
783
  var transition = $.support.transition && that.$element.hasClass('fade')
725
784
 
726
785
  if (!that.$element.parent().length) {
@@ -734,7 +793,12 @@
734
793
  that.$element[0].offsetWidth // force reflow
735
794
  }
736
795
 
737
- that.$element.addClass('in')
796
+ that.$element
797
+ .addClass('in')
798
+ .attr('aria-hidden', false)
799
+ .focus()
800
+
801
+ that.enforceFocus()
738
802
 
739
803
  transition ?
740
804
  that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
@@ -758,90 +822,98 @@
758
822
 
759
823
  $('body').removeClass('modal-open')
760
824
 
761
- escape.call(this)
825
+ this.escape()
762
826
 
763
- this.$element.removeClass('in')
827
+ $(document).off('focusin.modal')
828
+
829
+ this.$element
830
+ .removeClass('in')
831
+ .attr('aria-hidden', true)
764
832
 
765
833
  $.support.transition && this.$element.hasClass('fade') ?
766
- hideWithTransition.call(this) :
767
- hideModal.call(this)
834
+ this.hideWithTransition() :
835
+ this.hideModal()
768
836
  }
769
837
 
770
- }
771
-
772
-
773
- /* MODAL PRIVATE METHODS
774
- * ===================== */
838
+ , enforceFocus: function () {
839
+ var that = this
840
+ $(document).on('focusin.modal', function (e) {
841
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
842
+ that.$element.focus()
843
+ }
844
+ })
845
+ }
775
846
 
776
- function hideWithTransition() {
777
- var that = this
778
- , timeout = setTimeout(function () {
779
- that.$element.off($.support.transition.end)
780
- hideModal.call(that)
781
- }, 500)
847
+ , escape: function () {
848
+ var that = this
849
+ if (this.isShown && this.options.keyboard) {
850
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
851
+ e.which == 27 && that.hide()
852
+ })
853
+ } else if (!this.isShown) {
854
+ this.$element.off('keyup.dismiss.modal')
855
+ }
856
+ }
782
857
 
783
- this.$element.one($.support.transition.end, function () {
784
- clearTimeout(timeout)
785
- hideModal.call(that)
786
- })
787
- }
858
+ , hideWithTransition: function () {
859
+ var that = this
860
+ , timeout = setTimeout(function () {
861
+ that.$element.off($.support.transition.end)
862
+ that.hideModal()
863
+ }, 500)
788
864
 
789
- function hideModal(that) {
790
- this.$element
791
- .hide()
792
- .trigger('hidden')
865
+ this.$element.one($.support.transition.end, function () {
866
+ clearTimeout(timeout)
867
+ that.hideModal()
868
+ })
869
+ }
793
870
 
794
- backdrop.call(this)
795
- }
871
+ , hideModal: function (that) {
872
+ this.$element
873
+ .hide()
874
+ .trigger('hidden')
796
875
 
797
- function backdrop(callback) {
798
- var that = this
799
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
876
+ this.backdrop()
877
+ }
800
878
 
801
- if (this.isShown && this.options.backdrop) {
802
- var doAnimate = $.support.transition && animate
879
+ , removeBackdrop: function () {
880
+ this.$backdrop.remove()
881
+ this.$backdrop = null
882
+ }
803
883
 
804
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
805
- .appendTo(document.body)
884
+ , backdrop: function (callback) {
885
+ var that = this
886
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
806
887
 
807
- if (this.options.backdrop != 'static') {
808
- this.$backdrop.click($.proxy(this.hide, this))
809
- }
888
+ if (this.isShown && this.options.backdrop) {
889
+ var doAnimate = $.support.transition && animate
810
890
 
811
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
891
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
892
+ .appendTo(document.body)
812
893
 
813
- this.$backdrop.addClass('in')
894
+ if (this.options.backdrop != 'static') {
895
+ this.$backdrop.click($.proxy(this.hide, this))
896
+ }
814
897
 
815
- doAnimate ?
816
- this.$backdrop.one($.support.transition.end, callback) :
817
- callback()
898
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
818
899
 
819
- } else if (!this.isShown && this.$backdrop) {
820
- this.$backdrop.removeClass('in')
900
+ this.$backdrop.addClass('in')
821
901
 
822
- $.support.transition && this.$element.hasClass('fade')?
823
- this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
824
- removeBackdrop.call(this)
902
+ doAnimate ?
903
+ this.$backdrop.one($.support.transition.end, callback) :
904
+ callback()
825
905
 
826
- } else if (callback) {
827
- callback()
828
- }
829
- }
906
+ } else if (!this.isShown && this.$backdrop) {
907
+ this.$backdrop.removeClass('in')
830
908
 
831
- function removeBackdrop() {
832
- this.$backdrop.remove()
833
- this.$backdrop = null
834
- }
909
+ $.support.transition && this.$element.hasClass('fade')?
910
+ this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
911
+ this.removeBackdrop()
835
912
 
836
- function escape() {
837
- var that = this
838
- if (this.isShown && this.options.keyboard) {
839
- $(document).on('keyup.dismiss.modal', function ( e ) {
840
- e.which == 27 && that.hide()
841
- })
842
- } else if (!this.isShown) {
843
- $(document).off('keyup.dismiss.modal')
844
- }
913
+ } else if (callback) {
914
+ callback()
915
+ }
916
+ }
845
917
  }
846
918
 
847
919
 
@@ -873,17 +945,23 @@
873
945
 
874
946
  $(function () {
875
947
  $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
876
- var $this = $(this), href
877
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
878
- , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
948
+ var $this = $(this)
949
+ , href = $this.attr('href')
950
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
951
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
879
952
 
880
953
  e.preventDefault()
881
- $target.modal(option)
954
+
955
+ $target
956
+ .modal(option)
957
+ .one('hide', function () {
958
+ $this.focus()
959
+ })
882
960
  })
883
961
  })
884
962
 
885
963
  }(window.jQuery);/* ===========================================================
886
- * bootstrap-tooltip.js v2.0.4
964
+ * bootstrap-tooltip.js v2.1.0
887
965
  * http://twitter.github.com/bootstrap/javascript.html#tooltips
888
966
  * Inspired by the original jQuery.tipsy by Jason Frame
889
967
  * ===========================================================
@@ -928,11 +1006,13 @@
928
1006
  this.options = this.getOptions(options)
929
1007
  this.enabled = true
930
1008
 
931
- if (this.options.trigger != 'manual') {
932
- eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
1009
+ if (this.options.trigger == 'click') {
1010
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1011
+ } else if (this.options.trigger != 'manual') {
1012
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
933
1013
  eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
934
- this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
935
- this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
1014
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1015
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
936
1016
  }
937
1017
 
938
1018
  this.options.selector ?
@@ -1032,20 +1112,11 @@
1032
1112
  }
1033
1113
  }
1034
1114
 
1035
- , isHTML: function(text) {
1036
- // html string detection logic adapted from jQuery
1037
- return typeof text != 'string'
1038
- || ( text.charAt(0) === "<"
1039
- && text.charAt( text.length - 1 ) === ">"
1040
- && text.length >= 3
1041
- ) || /^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(text)
1042
- }
1043
-
1044
1115
  , setContent: function () {
1045
1116
  var $tip = this.tip()
1046
1117
  , title = this.getTitle()
1047
1118
 
1048
- $tip.find('.tooltip-inner')[this.isHTML(title) ? 'html' : 'text'](title)
1119
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1049
1120
  $tip.removeClass('fade in top bottom left right')
1050
1121
  }
1051
1122
 
@@ -1069,6 +1140,8 @@
1069
1140
  $.support.transition && this.$tip.hasClass('fade') ?
1070
1141
  removeWithAnimation() :
1071
1142
  $tip.remove()
1143
+
1144
+ return this
1072
1145
  }
1073
1146
 
1074
1147
  , fixTitle: function () {
@@ -1128,6 +1201,10 @@
1128
1201
  this[this.tip().hasClass('in') ? 'hide' : 'show']()
1129
1202
  }
1130
1203
 
1204
+ , destroy: function () {
1205
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1206
+ }
1207
+
1131
1208
  }
1132
1209
 
1133
1210
 
@@ -1154,11 +1231,12 @@
1154
1231
  , trigger: 'hover'
1155
1232
  , title: ''
1156
1233
  , delay: 0
1234
+ , html: true
1157
1235
  }
1158
1236
 
1159
1237
  }(window.jQuery);
1160
1238
  /* ===========================================================
1161
- * bootstrap-popover.js v2.0.4
1239
+ * bootstrap-popover.js v2.1.0
1162
1240
  * http://twitter.github.com/bootstrap/javascript.html#popovers
1163
1241
  * ===========================================================
1164
1242
  * Copyright 2012 Twitter, Inc.
@@ -1185,7 +1263,7 @@
1185
1263
  /* POPOVER PUBLIC CLASS DEFINITION
1186
1264
  * =============================== */
1187
1265
 
1188
- var Popover = function ( element, options ) {
1266
+ var Popover = function (element, options) {
1189
1267
  this.init('popover', element, options)
1190
1268
  }
1191
1269
 
@@ -1202,8 +1280,8 @@
1202
1280
  , title = this.getTitle()
1203
1281
  , content = this.getContent()
1204
1282
 
1205
- $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title)
1206
- $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content)
1283
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1284
+ $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
1207
1285
 
1208
1286
  $tip.removeClass('fade top bottom left right in')
1209
1287
  }
@@ -1230,6 +1308,10 @@
1230
1308
  return this.$tip
1231
1309
  }
1232
1310
 
1311
+ , destroy: function () {
1312
+ this.hide().$element.off('.' + this.type).removeData(this.type)
1313
+ }
1314
+
1233
1315
  })
1234
1316
 
1235
1317
 
@@ -1250,12 +1332,13 @@
1250
1332
 
1251
1333
  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1252
1334
  placement: 'right'
1335
+ , trigger: 'click'
1253
1336
  , content: ''
1254
1337
  , 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>'
1255
1338
  })
1256
1339
 
1257
1340
  }(window.jQuery);/* =============================================================
1258
- * bootstrap-scrollspy.js v2.0.4
1341
+ * bootstrap-scrollspy.js v2.1.0
1259
1342
  * http://twitter.github.com/bootstrap/javascript.html#scrollspy
1260
1343
  * =============================================================
1261
1344
  * Copyright 2012 Twitter, Inc.
@@ -1279,15 +1362,15 @@
1279
1362
  "use strict"; // jshint ;_;
1280
1363
 
1281
1364
 
1282
- /* SCROLLSPY CLASS DEFINITION
1283
- * ========================== */
1365
+ /* SCROLLSPY CLASS DEFINITION
1366
+ * ========================== */
1284
1367
 
1285
- function ScrollSpy( element, options) {
1368
+ function ScrollSpy(element, options) {
1286
1369
  var process = $.proxy(this.process, this)
1287
1370
  , $element = $(element).is('body') ? $(window) : $(element)
1288
1371
  , href
1289
1372
  this.options = $.extend({}, $.fn.scrollspy.defaults, options)
1290
- this.$scrollElement = $element.on('scroll.scroll.data-api', process)
1373
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
1291
1374
  this.selector = (this.options.target
1292
1375
  || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1293
1376
  || '') + ' .nav li > a'
@@ -1314,7 +1397,7 @@
1314
1397
  , href = $el.data('target') || $el.attr('href')
1315
1398
  , $href = /^#\w/.test(href) && $(href)
1316
1399
  return ( $href
1317
- && href.length
1400
+ && $href.length
1318
1401
  && [[ $href.position().top, href ]] ) || null
1319
1402
  })
1320
1403
  .sort(function (a, b) { return a[0] - b[0] })
@@ -1364,7 +1447,7 @@
1364
1447
  .parent('li')
1365
1448
  .addClass('active')
1366
1449
 
1367
- if (active.parent('.dropdown-menu')) {
1450
+ if (active.parent('.dropdown-menu').length) {
1368
1451
  active = active.closest('li.dropdown').addClass('active')
1369
1452
  }
1370
1453
 
@@ -1377,7 +1460,7 @@
1377
1460
  /* SCROLLSPY PLUGIN DEFINITION
1378
1461
  * =========================== */
1379
1462
 
1380
- $.fn.scrollspy = function ( option ) {
1463
+ $.fn.scrollspy = function (option) {
1381
1464
  return this.each(function () {
1382
1465
  var $this = $(this)
1383
1466
  , data = $this.data('scrollspy')
@@ -1397,7 +1480,7 @@
1397
1480
  /* SCROLLSPY DATA-API
1398
1481
  * ================== */
1399
1482
 
1400
- $(function () {
1483
+ $(window).on('load', function () {
1401
1484
  $('[data-spy="scroll"]').each(function () {
1402
1485
  var $spy = $(this)
1403
1486
  $spy.scrollspy($spy.data())
@@ -1405,7 +1488,7 @@
1405
1488
  })
1406
1489
 
1407
1490
  }(window.jQuery);/* ========================================================
1408
- * bootstrap-tab.js v2.0.4
1491
+ * bootstrap-tab.js v2.1.0
1409
1492
  * http://twitter.github.com/bootstrap/javascript.html#tabs
1410
1493
  * ========================================================
1411
1494
  * Copyright 2012 Twitter, Inc.
@@ -1432,7 +1515,7 @@
1432
1515
  /* TAB CLASS DEFINITION
1433
1516
  * ==================== */
1434
1517
 
1435
- var Tab = function ( element ) {
1518
+ var Tab = function (element) {
1436
1519
  this.element = $(element)
1437
1520
  }
1438
1521
 
@@ -1539,7 +1622,7 @@
1539
1622
  })
1540
1623
 
1541
1624
  }(window.jQuery);/* =============================================================
1542
- * bootstrap-typeahead.js v2.0.4
1625
+ * bootstrap-typeahead.js v2.1.0
1543
1626
  * http://twitter.github.com/bootstrap/javascript.html#typeahead
1544
1627
  * =============================================================
1545
1628
  * Copyright 2012 Twitter, Inc.
@@ -1617,17 +1700,23 @@
1617
1700
  }
1618
1701
 
1619
1702
  , lookup: function (event) {
1620
- var that = this
1621
- , items
1622
- , q
1703
+ var items
1623
1704
 
1624
1705
  this.query = this.$element.val()
1625
1706
 
1626
- if (!this.query) {
1707
+ if (!this.query || this.query.length < this.options.minLength) {
1627
1708
  return this.shown ? this.hide() : this
1628
1709
  }
1629
1710
 
1630
- items = $.grep(this.source, function (item) {
1711
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
1712
+
1713
+ return items ? this.process(items) : this
1714
+ }
1715
+
1716
+ , process: function (items) {
1717
+ var that = this
1718
+
1719
+ items = $.grep(items, function (item) {
1631
1720
  return that.matcher(item)
1632
1721
  })
1633
1722
 
@@ -1709,7 +1798,7 @@
1709
1798
  .on('keyup', $.proxy(this.keyup, this))
1710
1799
 
1711
1800
  if ($.browser.webkit || $.browser.msie) {
1712
- this.$element.on('keydown', $.proxy(this.keypress, this))
1801
+ this.$element.on('keydown', $.proxy(this.keydown, this))
1713
1802
  }
1714
1803
 
1715
1804
  this.$menu
@@ -1717,6 +1806,40 @@
1717
1806
  .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
1718
1807
  }
1719
1808
 
1809
+ , move: function (e) {
1810
+ if (!this.shown) return
1811
+
1812
+ switch(e.keyCode) {
1813
+ case 9: // tab
1814
+ case 13: // enter
1815
+ case 27: // escape
1816
+ e.preventDefault()
1817
+ break
1818
+
1819
+ case 38: // up arrow
1820
+ e.preventDefault()
1821
+ this.prev()
1822
+ break
1823
+
1824
+ case 40: // down arrow
1825
+ e.preventDefault()
1826
+ this.next()
1827
+ break
1828
+ }
1829
+
1830
+ e.stopPropagation()
1831
+ }
1832
+
1833
+ , keydown: function (e) {
1834
+ this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27])
1835
+ this.move(e)
1836
+ }
1837
+
1838
+ , keypress: function (e) {
1839
+ if (this.suppressKeyPressRepeat) return
1840
+ this.move(e)
1841
+ }
1842
+
1720
1843
  , keyup: function (e) {
1721
1844
  switch(e.keyCode) {
1722
1845
  case 40: // down arrow
@@ -1742,32 +1865,6 @@
1742
1865
  e.preventDefault()
1743
1866
  }
1744
1867
 
1745
- , keypress: function (e) {
1746
- if (!this.shown) return
1747
-
1748
- switch(e.keyCode) {
1749
- case 9: // tab
1750
- case 13: // enter
1751
- case 27: // escape
1752
- e.preventDefault()
1753
- break
1754
-
1755
- case 38: // up arrow
1756
- if (e.type != 'keydown') break
1757
- e.preventDefault()
1758
- this.prev()
1759
- break
1760
-
1761
- case 40: // down arrow
1762
- if (e.type != 'keydown') break
1763
- e.preventDefault()
1764
- this.next()
1765
- break
1766
- }
1767
-
1768
- e.stopPropagation()
1769
- }
1770
-
1771
1868
  , blur: function (e) {
1772
1869
  var that = this
1773
1870
  setTimeout(function () { that.hide() }, 150)
@@ -1805,12 +1902,13 @@
1805
1902
  , items: 8
1806
1903
  , menu: '<ul class="typeahead dropdown-menu"></ul>'
1807
1904
  , item: '<li><a href="#"></a></li>'
1905
+ , minLength: 1
1808
1906
  }
1809
1907
 
1810
1908
  $.fn.typeahead.Constructor = Typeahead
1811
1909
 
1812
1910
 
1813
- /* TYPEAHEAD DATA-API
1911
+ /* TYPEAHEAD DATA-API
1814
1912
  * ================== */
1815
1913
 
1816
1914
  $(function () {
@@ -1822,4 +1920,108 @@
1822
1920
  })
1823
1921
  })
1824
1922
 
1923
+ }(window.jQuery);
1924
+ /* ==========================================================
1925
+ * bootstrap-affix.js v2.1.0
1926
+ * http://twitter.github.com/bootstrap/javascript.html#affix
1927
+ * ==========================================================
1928
+ * Copyright 2012 Twitter, Inc.
1929
+ *
1930
+ * Licensed under the Apache License, Version 2.0 (the "License");
1931
+ * you may not use this file except in compliance with the License.
1932
+ * You may obtain a copy of the License at
1933
+ *
1934
+ * http://www.apache.org/licenses/LICENSE-2.0
1935
+ *
1936
+ * Unless required by applicable law or agreed to in writing, software
1937
+ * distributed under the License is distributed on an "AS IS" BASIS,
1938
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1939
+ * See the License for the specific language governing permissions and
1940
+ * limitations under the License.
1941
+ * ========================================================== */
1942
+
1943
+
1944
+ !function ($) {
1945
+
1946
+ "use strict"; // jshint ;_;
1947
+
1948
+
1949
+ /* AFFIX CLASS DEFINITION
1950
+ * ====================== */
1951
+
1952
+ var Affix = function (element, options) {
1953
+ this.options = $.extend({}, $.fn.affix.defaults, options)
1954
+ this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
1955
+ this.$element = $(element)
1956
+ this.checkPosition()
1957
+ }
1958
+
1959
+ Affix.prototype.checkPosition = function () {
1960
+ if (!this.$element.is(':visible')) return
1961
+
1962
+ var scrollHeight = $(document).height()
1963
+ , scrollTop = this.$window.scrollTop()
1964
+ , position = this.$element.offset()
1965
+ , offset = this.options.offset
1966
+ , offsetBottom = offset.bottom
1967
+ , offsetTop = offset.top
1968
+ , reset = 'affix affix-top affix-bottom'
1969
+ , affix
1970
+
1971
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
1972
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
1973
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
1974
+
1975
+ affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
1976
+ false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
1977
+ 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
1978
+ 'top' : false
1979
+
1980
+ if (this.affixed === affix) return
1981
+
1982
+ this.affixed = affix
1983
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
1984
+
1985
+ this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
1986
+ }
1987
+
1988
+
1989
+ /* AFFIX PLUGIN DEFINITION
1990
+ * ======================= */
1991
+
1992
+ $.fn.affix = function (option) {
1993
+ return this.each(function () {
1994
+ var $this = $(this)
1995
+ , data = $this.data('affix')
1996
+ , options = typeof option == 'object' && option
1997
+ if (!data) $this.data('affix', (data = new Affix(this, options)))
1998
+ if (typeof option == 'string') data[option]()
1999
+ })
2000
+ }
2001
+
2002
+ $.fn.affix.Constructor = Affix
2003
+
2004
+ $.fn.affix.defaults = {
2005
+ offset: 0
2006
+ }
2007
+
2008
+
2009
+ /* AFFIX DATA-API
2010
+ * ============== */
2011
+
2012
+ $(window).on('load', function () {
2013
+ $('[data-spy="affix"]').each(function () {
2014
+ var $spy = $(this)
2015
+ , data = $spy.data()
2016
+
2017
+ data.offset = data.offset || {}
2018
+
2019
+ data.offsetBottom && (data.offset.bottom = data.offsetBottom)
2020
+ data.offsetTop && (data.offset.top = data.offsetTop)
2021
+
2022
+ $spy.affix(data)
2023
+ })
2024
+ })
2025
+
2026
+
1825
2027
  }(window.jQuery);