123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- /**
- * @file
- * bootstrap.js
- *
- * Provides general enhancements and fixes to Bootstrap's JS files.
- */
- var Drupal = Drupal || {};
- (function($, Drupal){
- "use strict";
- var $document = $(document);
- Drupal.behaviors.bootstrap = {
- attach: function(context) {
- // Provide some Bootstrap tab/Drupal integration.
- $(context).find('.tabbable').once('bootstrap-tabs', function () {
- var $wrapper = $(this);
- var $tabs = $wrapper.find('.nav-tabs');
- var $content = $wrapper.find('.tab-content');
- var borderRadius = parseInt($content.css('borderBottomRightRadius'), 10);
- var bootstrapTabResize = function() {
- if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
- $content.css('min-height', $tabs.outerHeight());
- }
- };
- // Add min-height on content for left and right tabs.
- bootstrapTabResize();
- // Detect tab switch.
- if ($wrapper.hasClass('tabs-left') || $wrapper.hasClass('tabs-right')) {
- $tabs.on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
- bootstrapTabResize();
- if ($wrapper.hasClass('tabs-left')) {
- if ($(e.target).parent().is(':first-child')) {
- $content.css('borderTopLeftRadius', '0');
- }
- else {
- $content.css('borderTopLeftRadius', borderRadius + 'px');
- }
- }
- else {
- if ($(e.target).parent().is(':first-child')) {
- $content.css('borderTopRightRadius', '0');
- }
- else {
- $content.css('borderTopRightRadius', borderRadius + 'px');
- }
- }
- });
- }
- });
- }
- };
- /**
- * Behavior for .
- */
- Drupal.behaviors.bootstrapFormHasError = {
- attach: function (context, settings) {
- if (settings.bootstrap && settings.bootstrap.formHasError) {
- var $context = $(context);
- $context.find('.form-item.has-error:not(.form-type-password.has-feedback)').once('error', function () {
- var $formItem = $(this);
- var $input = $formItem.find(':input');
- $input.on('keyup focus blur', function () {
- var value = $input.val() || false;
- $formItem[value ? 'removeClass' : 'addClass']('has-error');
- $input[value ? 'removeClass' : 'addClass']('error');
- });
- });
- }
- }
- };
- /**
- * Bootstrap Popovers.
- */
- Drupal.behaviors.bootstrapPopovers = {
- attach: function (context, settings) {
- // Immediately return if popovers are not available.
- if (!settings.bootstrap || !settings.bootstrap.popoverEnabled || !$.fn.popover) {
- return;
- }
- // Popover autoclose.
- if (settings.bootstrap.popoverOptions.triggerAutoclose) {
- var $currentPopover = null;
- $document
- .on('show.bs.popover', '[data-toggle=popover]', function () {
- var $trigger = $(this);
- var popover = $trigger.data('bs.popover');
- // Only keep track of clicked triggers that we're manually handling.
- if (popover.options.originalTrigger === 'click') {
- if ($currentPopover && !$currentPopover.is($trigger)) {
- $currentPopover.popover('hide');
- }
- $currentPopover = $trigger;
- }
- })
- .on('click', function (e) {
- var $target = $(e.target);
- var popover = $target.is('[data-toggle=popover]') && $target.data('bs.popover');
- if ($currentPopover && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) {
- $currentPopover.popover('hide');
- $currentPopover = null;
- }
- })
- ;
- }
- var elements = $(context).find('[data-toggle=popover]').toArray();
- for (var i = 0; i < elements.length; i++) {
- var $element = $(elements[i]);
- var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, settings.bootstrap.popoverOptions, $element.data());
- // Store the original trigger.
- options.originalTrigger = options.trigger;
- // If the trigger is "click", then we'll handle it manually here.
- if (options.trigger === 'click') {
- options.trigger = 'manual';
- }
- // Retrieve content from a target element.
- var target = options.target || $element.is('a[href^="#"]') && $element.attr('href');
- var $target = $document.find(target).clone();
- if (!options.content && $target[0]) {
- $target.removeClass('element-invisible hidden').removeAttr('aria-hidden');
- options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || '';
- }
- // Initialize the popover.
- $element.popover(options);
- // Handle clicks manually.
- if (options.originalTrigger === 'click') {
- // To ensure the element is bound multiple times, remove any
- // previously set event handler before adding another one.
- $element
- .off('click.drupal.bootstrap.popover')
- .on('click.drupal.bootstrap.popover', function (e) {
- $(this).popover('toggle');
- e.preventDefault();
- e.stopPropagation();
- })
- ;
- }
- }
- },
- detach: function (context, settings) {
- // Immediately return if popovers are not available.
- if (!settings.bootstrap || !settings.bootstrap.popoverEnabled || !$.fn.popover) {
- return;
- }
- // Destroy all popovers.
- $(context).find('[data-toggle="popover"]')
- .off('click.drupal.bootstrap.popover')
- .popover('destroy')
- ;
- }
- };
- /**
- * Bootstrap Tooltips.
- */
- Drupal.behaviors.bootstrapTooltips = {
- attach: function (context, settings) {
- if (settings.bootstrap && settings.bootstrap.tooltipEnabled) {
- var elements = $(context).find('[data-toggle="tooltip"]').toArray();
- for (var i = 0; i < elements.length; i++) {
- var $element = $(elements[i]);
- var options = $.extend({}, settings.bootstrap.tooltipOptions, $element.data());
- $element.tooltip(options);
- }
- }
- }
- };
- /**
- * Anchor fixes.
- */
- var $scrollableElement = $();
- Drupal.behaviors.bootstrapAnchors = {
- attach: function(context, settings) {
- var i, elements = ['html', 'body'];
- if (!$scrollableElement.length) {
- for (i = 0; i < elements.length; i++) {
- var $element = $(elements[i]);
- if ($element.scrollTop() > 0) {
- $scrollableElement = $element;
- break;
- }
- else {
- $element.scrollTop(1);
- if ($element.scrollTop() > 0) {
- $element.scrollTop(0);
- $scrollableElement = $element;
- break;
- }
- }
- }
- }
- if (!settings.bootstrap || settings.bootstrap.anchorsFix !== '1') {
- return;
- }
- var anchors = $(context).find('a').toArray();
- for (i = 0; i < anchors.length; i++) {
- if (!anchors[i].scrollTo) {
- this.bootstrapAnchor(anchors[i]);
- }
- }
- $scrollableElement.once('bootstrap-anchors', function () {
- $scrollableElement.on('click.bootstrap-anchors', 'a[href*="#"]:not([data-toggle],[data-target],[data-slide])', function(e) {
- if (this.scrollTo) {
- this.scrollTo(e);
- }
- });
- });
- },
- bootstrapAnchor: function (element) {
- element.validAnchor = element.nodeName === 'A' && (location.hostname === element.hostname || !element.hostname) && (element.hash.replace(/#/,'').length > 0);
- element.scrollTo = function(event) {
- var attr = 'id';
- var $target = $(element.hash);
- // Check for anchors that use the name attribute instead.
- if (!$target.length) {
- attr = 'name';
- $target = $('[name="' + element.hash.replace('#', '') + '"]');
- }
- // Immediately stop if no anchors are found.
- if (!this.validAnchor && !$target.length) {
- return;
- }
- // Anchor is valid, continue if there is an offset.
- var offset = $target.offset().top - parseInt($scrollableElement.css('paddingTop'), 10) - parseInt($scrollableElement.css('marginTop'), 10);
- if (offset > 0) {
- if (event) {
- event.preventDefault();
- }
- var $fakeAnchor = $('<div/>')
- .addClass('element-invisible')
- .attr(attr, $target.attr(attr))
- .css({
- position: 'absolute',
- top: offset + 'px',
- zIndex: -1000
- })
- .appendTo($scrollableElement);
- $target.removeAttr(attr);
- var complete = function () {
- location.hash = element.hash;
- $fakeAnchor.remove();
- $target.attr(attr, element.hash.replace('#', ''));
- };
- if (Drupal.settings.bootstrap.anchorsSmoothScrolling) {
- $scrollableElement.animate({ scrollTop: offset, avoidTransforms: true }, 400, complete);
- }
- else {
- $scrollableElement.scrollTop(offset);
- complete();
- }
- }
- };
- }
- };
- /**
- * Tabledrag theming elements.
- */
- Drupal.theme.tableDragChangedMarker = function () {
- return '<span class="tabledrag-changed glyphicon glyphicon-warning-sign text-warning"></span>';
- };
- Drupal.theme.tableDragChangedWarning = function () {
- 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>';
- };
- })(jQuery, Drupal);
|