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 html: !!settings.popover_html, 19 placement: settings.popover_placement, 20 selector: settings.popover_selector, 21 trigger: settings.popover_trigger, 22 triggerAutoclose: !!settings.popover_trigger_autoclose, 23 title: settings.popover_title, 24 content: settings.popover_content, 25 delay: parseInt(settings.popover_delay, 10), 26 container: settings.popover_container 27 } 28 }; 29 }); 30 31 /** 32 * Bootstrap Popovers. 33 * 34 * @todo This should really be properly delegated if selector option is set. 35 */ 36 Drupal.behaviors.bootstrapPopovers = { 37 attach: function (context) { 38 39 // Popover autoclose. 40 if ($.fn.popover.Constructor.DEFAULTS.triggerAutoclose) { 41 var $currentPopover = null; 42 $(document) 43 .on('show.bs.popover', '[data-toggle=popover]', function () { 44 var $trigger = $(this); 45 var popover = $trigger.data('bs.popover'); 46 47 // Only keep track of clicked triggers that we're manually handling. 48 if (popover.options.originalTrigger === 'click') { 49 if ($currentPopover && !$currentPopover.is($trigger)) { 50 $currentPopover.popover('hide'); 51 } 52 $currentPopover = $trigger; 53 } 54 }) 55 .on('click', function (e) { 56 var $target = $(e.target); 57 var popover = $target.is('[data-toggle=popover]') && $target.data('bs.popover'); 58 if ($currentPopover && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) { 59 $currentPopover.popover('hide'); 60 $currentPopover = null; 61 } 62 }) 63 ; 64 } 65 66 var elements = $(context).find('[data-toggle=popover]').toArray(); 67 for (var i = 0; i < elements.length; i++) { 68 var $element = $(elements[i]); 69 var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data()); 70 71 // Store the original trigger. 72 options.originalTrigger = options.trigger; 73 74 // If the trigger is "click", then we'll handle it manually here. 75 if (options.trigger === 'click') { 76 options.trigger = 'manual'; 77 } 78 79 // Retrieve content from a target element. 80 var $target = $(options.target || $element.is('a[href^="#"]') && $element.attr('href')).clone(); 81 if (!options.content && $target[0]) { 82 $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden'); 83 options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || ''; 84 } 85 86 // Initialize the popover. 87 $element.popover(options); 88 89 // Handle clicks manually. 90 if (options.originalTrigger === 'click') { 91 // To ensure the element is bound multiple times, remove any 92 // previously set event handler before adding another one. 93 $element 94 .off('click.drupal.bootstrap.popover') 95 .on('click.drupal.bootstrap.popover', function (e) { 96 $(this).popover('toggle'); 97 e.preventDefault(); 98 e.stopPropagation(); 99 }) 100 ; 101 } 102 } 103 }, 104 detach: function (context) { 105 // Destroy all popovers. 106 $(context).find('[data-toggle="popover"]') 107 .off('click.drupal.bootstrap.popover') 108 .popover('destroy') 109 ; 110 } 111 }; 112 113})(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.