1/** 2 * @file 3 * Bootstrap Popovers. 4 */ 5 6var Drupal = Drupal || {}; 7 8(function ($, Drupal, Bootstrap) { 9 "use strict"; 10 11 /** 12 * Extend the Bootstrap Popover plugin constructor class. 13 */ 14 Bootstrap.extendPlugin('popover', function (settings) { 15 return { 16 DEFAULTS: { 17 animation: !!settings.popover_animation, 18 enabled: settings.popover_enabled, 19 html: !!settings.popover_html, 20 placement: settings.popover_placement, 21 selector: settings.popover_selector, 22 trigger: settings.popover_trigger, 23 triggerAutoclose: !!settings.popover_trigger_autoclose, 24 title: settings.popover_title, 25 content: settings.popover_content, 26 delay: parseInt(settings.popover_delay, 10), 27 container: settings.popover_container 28 } 29 }; 30 }); 31 32 /** 33 * Bootstrap Popovers. 34 * 35 * @todo This should really be properly delegated if selector option is set. 36 */ 37 Drupal.behaviors.bootstrapPopovers = { 38 attach: function (context) { 39 // Immediately return if popovers are not available. 40 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 41 return; 42 } 43 44 // Popover autoclose. 45 if ($.fn.popover.Constructor.DEFAULTS.triggerAutoclose) { 46 var $currentPopover = null; 47 $(document) 48 .on('show.bs.popover', '[data-toggle=popover]', function () { 49 var $trigger = $(this); 50 var popover = $trigger.data('bs.popover'); 51 52 // Only keep track of clicked triggers that we're manually handling. 53 if (popover.options.originalTrigger === 'click') { 54 if ($currentPopover && !$currentPopover.is($trigger)) { 55 $currentPopover.popover('hide'); 56 } 57 $currentPopover = $trigger; 58 } 59 }) 60 .on('click', function (e) { 61 var $target = $(e.target); 62 var popover = $target.is('[data-toggle=popover]') && $target.data('bs.popover'); 63 if ($currentPopover && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) { 64 $currentPopover.popover('hide'); 65 $currentPopover = null; 66 } 67 }) 68 ; 69 } 70 71 var elements = $(context).find('[data-toggle=popover]').toArray(); 72 for (var i = 0; i < elements.length; i++) { 73 var $element = $(elements[i]); 74 var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data()); 75 76 // Store the original trigger. 77 options.originalTrigger = options.trigger; 78 79 // If the trigger is "click", then we'll handle it manually here. 80 if (options.trigger === 'click') { 81 options.trigger = 'manual'; 82 } 83 84 // Retrieve content from a target element. 85 var $target = $(options.target || $element.is('a[href^="#"]') && $element.attr('href')).clone(); 86 if (!options.content && $target[0]) { 87 $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden'); 88 options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || ''; 89 } 90 91 // Initialize the popover. 92 $element.popover(options); 93 94 // Handle clicks manually. 95 if (options.originalTrigger === 'click') { 96 // To ensure the element is bound multiple times, remove any 97 // previously set event handler before adding another one. 98 $element 99 .off('click.drupal.bootstrap.popover') 100 .on('click.drupal.bootstrap.popover', function (e) { 101 $(this).popover('toggle'); 102 e.preventDefault(); 103 e.stopPropagation(); 104 }) 105 ; 106 } 107 } 108 }, 109 detach: function (context) { 110 // Immediately return if popovers are not available. 111 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 112 return; 113 } 114 115 // Destroy all popovers. 116 $(context).find('[data-toggle="popover"]') 117 .off('click.drupal.bootstrap.popover') 118 .popover('destroy') 119 ; 120 } 121 }; 122 123})(window.jQuery, window.Drupal, window.Drupal.bootstrap);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.