Projet

Général

Profil

Paste
Télécharger (9,61 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / themes / bootstrap / js / bootstrap.js @ 5024cef7

1
/**
2
 * @file
3
 * bootstrap.js
4
 *
5
 * Provides general enhancements and fixes to Bootstrap's JS files.
6
 */
7

    
8
var Drupal = Drupal || {};
9

    
10
(function($, Drupal){
11
  "use strict";
12

    
13
  Drupal.behaviors.bootstrap = {
14
    attach: function(context) {
15
      // Provide some Bootstrap tab/Drupal integration.
16
      $(context).find('.tabbable').once('bootstrap-tabs', function () {
17
        var $wrapper = $(this);
18
        var $tabs = $wrapper.find('.nav-tabs');
19
        var $content = $wrapper.find('.tab-content');
20
        var borderRadius = parseInt($content.css('borderBottomRightRadius'), 10);
21
        var bootstrapTabResize = function() {
22
          if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
23
            $content.css('min-height', $tabs.outerHeight());
24
          }
25
        };
26
        // Add min-height on content for left and right tabs.
27
        bootstrapTabResize();
28
        // Detect tab switch.
29
        if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
30
          $tabs.on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
31
            bootstrapTabResize();
32
            if ($wrapper.hasClass('tabs-left')) {
33
              if ($(e.target).parent().is(':first-child')) {
34
                $content.css('borderTopLeftRadius', '0');
35
              }
36
              else {
37
                $content.css('borderTopLeftRadius', borderRadius + 'px');
38
              }
39
            }
40
            else {
41
              if ($(e.target).parent().is(':first-child')) {
42
                $content.css('borderTopRightRadius', '0');
43
              }
44
              else {
45
                $content.css('borderTopRightRadius', borderRadius + 'px');
46
              }
47
            }
48
          });
49
        }
50
      });
51
    }
52
  };
53

    
54
  /**
55
   * Behavior for .
56
   */
57
  Drupal.behaviors.bootstrapFormHasError = {
58
    attach: function (context, settings) {
59
      if (settings.bootstrap && settings.bootstrap.formHasError) {
60
        var $context = $(context);
61
        $context.find('.form-item.has-error:not(.form-type-password.has-feedback)').once('error', function () {
62
          var $formItem = $(this);
63
          var $input = $formItem.find(':input');
64
          $input.on('keyup focus blur', function () {
65
            var value = $input.val() || false;
66
            $formItem[value ? 'removeClass' : 'addClass']('has-error');
67
            $input[value ? 'removeClass' : 'addClass']('error');
68
          });
69
        });
70
      }
71
    }
72
  };
73

    
74
  /**
75
   * Bootstrap Popovers.
76
   */
77
  Drupal.behaviors.bootstrapPopovers = {
78
    attach: function (context, settings) {
79
      // Immediately return if popovers are not available.
80
      if (!settings.bootstrap || !settings.bootstrap.popoverEnabled || !$.fn.popover) {
81
        return;
82
      }
83

    
84
      // Popover autoclose.
85
      if (settings.bootstrap.popoverOptions.triggerAutoclose) {
86
        var $currentPopover = null;
87
        $(document)
88
          .on('show.bs.popover', '[data-toggle=popover]', function () {
89
            var $trigger = $(this);
90
            var popover = $trigger.data('bs.popover');
91

    
92
            // Only keep track of clicked triggers that we're manually handling.
93
            if (popover.options.originalTrigger === 'click') {
94
              if ($currentPopover && !$currentPopover.is($trigger)) {
95
                $currentPopover.popover('hide');
96
              }
97
              $currentPopover = $trigger;
98
            }
99
          })
100
          .on('click', function (e) {
101
            var $target = $(e.target);
102
            var popover = $target.is('[data-toggle=popover]') && $target.data('bs.popover');
103
            if ($currentPopover && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) {
104
              $currentPopover.popover('hide');
105
              $currentPopover = null;
106
            }
107
          })
108
        ;
109
      }
110

    
111
      var elements = $(context).find('[data-toggle=popover]').toArray();
112
      for (var i = 0; i < elements.length; i++) {
113
        var $element = $(elements[i]);
114
        var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, settings.bootstrap.popoverOptions, $element.data());
115

    
116
        // Store the original trigger.
117
        options.originalTrigger = options.trigger;
118

    
119
        // If the trigger is "click", then we'll handle it manually here.
120
        if (options.trigger === 'click') {
121
          options.trigger = 'manual';
122
        }
123

    
124
        // Retrieve content from a target element.
125
        var $target = $(options.target || $element.is('a[href^="#"]') && $element.attr('href')).clone();
126
        if (!options.content && $target[0]) {
127
          $target.removeClass('element-invisible hidden').removeAttr('aria-hidden');
128
          options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || '';
129
        }
130

    
131
        // Initialize the popover.
132
        $element.popover(options);
133

    
134
        // Handle clicks manually.
135
        if (options.originalTrigger === 'click') {
136
          // To ensure the element is bound multiple times, remove any
137
          // previously set event handler before adding another one.
138
          $element
139
            .off('click.drupal.bootstrap.popover')
140
            .on('click.drupal.bootstrap.popover', function (e) {
141
              $(this).popover('toggle');
142
              e.preventDefault();
143
              e.stopPropagation();
144
            })
145
          ;
146
        }
147
      }
148
    },
149
    detach: function (context, settings) {
150
      // Immediately return if popovers are not available.
151
      if (!settings.bootstrap || !settings.bootstrap.popoverEnabled || !$.fn.popover) {
152
        return;
153
      }
154

    
155
      // Destroy all popovers.
156
      $(context).find('[data-toggle="popover"]')
157
        .off('click.drupal.bootstrap.popover')
158
        .popover('destroy')
159
      ;
160
    }
161
  };
162

    
163
  /**
164
   * Bootstrap Tooltips.
165
   */
166
  Drupal.behaviors.bootstrapTooltips = {
167
    attach: function (context, settings) {
168
      if (settings.bootstrap && settings.bootstrap.tooltipEnabled) {
169
        var elements = $(context).find('[data-toggle="tooltip"]').toArray();
170
        for (var i = 0; i < elements.length; i++) {
171
          var $element = $(elements[i]);
172
          var options = $.extend({}, settings.bootstrap.tooltipOptions, $element.data());
173
          $element.tooltip(options);
174
        }
175
      }
176
    }
177
  };
178

    
179
  /**
180
   * Anchor fixes.
181
   */
182
  var $scrollableElement = $();
183
  Drupal.behaviors.bootstrapAnchors = {
184
    attach: function(context, settings) {
185
      var i, elements = ['html', 'body'];
186
      if (!$scrollableElement.length) {
187
        for (i = 0; i < elements.length; i++) {
188
          var $element = $(elements[i]);
189
          if ($element.scrollTop() > 0) {
190
            $scrollableElement = $element;
191
            break;
192
          }
193
          else {
194
            $element.scrollTop(1);
195
            if ($element.scrollTop() > 0) {
196
              $element.scrollTop(0);
197
              $scrollableElement = $element;
198
              break;
199
            }
200
          }
201
        }
202
      }
203
      if (!settings.bootstrap || settings.bootstrap.anchorsFix !== '1') {
204
        return;
205
      }
206
      var anchors = $(context).find('a').toArray();
207
      for (i = 0; i < anchors.length; i++) {
208
        if (!anchors[i].scrollTo) {
209
          this.bootstrapAnchor(anchors[i]);
210
        }
211
      }
212
      $scrollableElement.once('bootstrap-anchors', function () {
213
        $scrollableElement.on('click.bootstrap-anchors', 'a[href*="#"]:not([data-toggle],[data-target],[data-slide])', function(e) {
214
          if (this.scrollTo) {
215
            this.scrollTo(e);
216
          }
217
        });
218
      });
219
    },
220
    bootstrapAnchor: function (element) {
221
      element.validAnchor = element.nodeName === 'A' && (location.hostname === element.hostname || !element.hostname) && (element.hash.replace(/#/,'').length > 0);
222
      element.scrollTo = function(event) {
223
        var attr = 'id';
224
        var $target = $(element.hash);
225
        // Check for anchors that use the name attribute instead.
226
        if (!$target.length) {
227
          attr = 'name';
228
          $target = $('[name="' + element.hash.replace('#', '') + '"]');
229
        }
230
        // Immediately stop if no anchors are found.
231
        if (!this.validAnchor && !$target.length) {
232
          return;
233
        }
234
        // Anchor is valid, continue if there is an offset.
235
        var offset = $target.offset().top - parseInt($scrollableElement.css('paddingTop'), 10) - parseInt($scrollableElement.css('marginTop'), 10);
236
        if (offset > 0) {
237
          if (event) {
238
            event.preventDefault();
239
          }
240
          var $fakeAnchor = $('<div/>')
241
            .addClass('element-invisible')
242
            .attr(attr, $target.attr(attr))
243
            .css({
244
              position: 'absolute',
245
              top: offset + 'px',
246
              zIndex: -1000
247
            })
248
            .appendTo($scrollableElement);
249
          $target.removeAttr(attr);
250
          var complete = function () {
251
            location.hash = element.hash;
252
            $fakeAnchor.remove();
253
            $target.attr(attr, element.hash.replace('#', ''));
254
          };
255
          if (Drupal.settings.bootstrap.anchorsSmoothScrolling) {
256
            $scrollableElement.animate({ scrollTop: offset, avoidTransforms: true }, 400, complete);
257
          }
258
          else {
259
            $scrollableElement.scrollTop(offset);
260
            complete();
261
          }
262
        }
263
      };
264
    }
265
  };
266

    
267
  /**
268
   * Tabledrag theming elements.
269
   */
270
  Drupal.theme.tableDragChangedMarker = function () {
271
    return '<span class="tabledrag-changed glyphicon glyphicon-warning-sign text-warning"></span>';
272
  };
273

    
274
  Drupal.theme.tableDragChangedWarning = function () {
275
    return '<div class="tabledrag-changed-warning alert alert-warning messages warning">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t('Changes made in this table will not be saved until the form is submitted.') + '</div>';
276
  };
277

    
278
})(jQuery, Drupal);