1 /** 2 * @file 3 * Bootstrap Popovers. 4 */ 5 6var Drupal = Drupal || {}; 7 8(function ($, Drupal, Bootstrap) { 9 "use strict"; 10 11 var $document = $(document); 12 13 /** 14 * Extend the Bootstrap Popover plugin constructor class. 15 */ 16 Bootstrap.extendPlugin('popover', function (settings) { 17 return { 18 DEFAULTS: { 19 animation: !!settings.popover_animation, 20 autoClose: !!settings.popover_auto_close, 21 enabled: settings.popover_enabled, 22 html: !!settings.popover_html, 23 placement: settings.popover_placement, 24 selector: settings.popover_selector, 25 trigger: settings.popover_trigger, 26 title: settings.popover_title, 27 content: settings.popover_content, 28 delay: parseInt(settings.popover_delay, 10), 29 container: settings.popover_container 30 } 31 }; 32 }); 33 34 /** 35 * Bootstrap Popovers. 36 * 37 * @todo This should really be properly delegated if selector option is set. 38 */ 39 Drupal.behaviors.bootstrapPopovers = { 40 $activePopover: null, 41 attach: function (context) { 42 // Immediately return if popovers are not available. 43 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 44 return; 45 } 46 47 var _this = this; 48 49 $document 50 .on('show.bs.popover', '[data-toggle=popover]', function () { 51 var $trigger = $(this); 52 var popover = $trigger.data('bs.popover'); 53 54 // Only keep track of clicked triggers that we're manually handling. 55 if (popover.options.originalTrigger === 'click') { 56 if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($trigger)) { 57 _this.$activePopover.popover('hide'); 58 } 59 _this.$activePopover = $trigger; 60 } 61 }) 62 // Unfortunately, :focusable is only made available when using jQuery 63 // UI. While this would be the most semantic pseudo selector to use 64 // here, jQuery UI may not always be loaded. Instead, just use :visible 65 // here as this just needs some sort of selector here. This activates 66 // delegate binding to elements in jQuery so it can work it's bubbling 67 // focus magic since elements don't really propagate their focus events. 68 // @see https://www.drupal.org/project/bootstrap/issues/3013236 69 .on('focus.bs.popover', ':visible', function (e) { 70 var $target = $(e.target); 71 if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($target) && !$target.closest('.popover.in')[0]) { 72 _this.$activePopover.popover('hide'); 73 _this.$activePopover = null; 74 } 75 }) 76 .on('click.bs.popover', function (e) { 77 var $target = $(e.target); 78 if (_this.$activePopover && _this.getOption('autoClose') && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) { 79 _this.$activePopover.popover('hide'); 80 _this.$activePopover = null; 81 } 82 }) 83 .on('keyup.bs.popover', function (e) { 84 if (_this.$activePopover && _this.getOption('autoClose') && e.which === 27) { 85 _this.$activePopover.popover('hide'); 86 _this.$activePopover = null; 87 } 88 }) 89 ; 90 91 var elements = $(context).find('[data-toggle=popover]').toArray(); 92 for (var i = 0; i < elements.length; i++) { 93 var $element = $(elements[i]); 94 var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data()); 95 96 // Store the original trigger. 97 options.originalTrigger = options.trigger; 98 99 // If the trigger is "click", then we'll handle it manually here. 100 if (options.trigger === 'click') { 101 options.trigger = 'manual'; 102 } 103 104 // Retrieve content from a target element. 105 var target = options.target || $element.is('a[href^="#"]') && $element.attr('href'); 106 var $target = $document.find(target).clone(); 107 if (!options.content && $target[0]) { 108 $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden'); 109 options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || ''; 110 } 111 112 // Initialize the popover. 113 $element.popover(options); 114 115 // Handle clicks manually. 116 if (options.originalTrigger === 'click') { 117 // To ensure the element is bound multiple times, remove any 118 // previously set event handler before adding another one. 119 $element 120 .off('click.drupal.bootstrap.popover') 121 .on('click.drupal.bootstrap.popover', function (e) { 122 $(this).popover('toggle'); 123 e.preventDefault(); 124 e.stopPropagation(); 125 }) 126 ; 127 } 128 } 129 }, 130 detach: function (context) { 131 // Immediately return if popovers are not available. 132 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 133 return; 134 } 135 136 // Destroy all popovers. 137 $(context).find('[data-toggle="popover"]') 138 .off('click.drupal.bootstrap.popover') 139 .popover('destroy') 140 ; 141 }, 142 getOption: function(name, defaultValue, element) { 143 var $element = element ? $(element) : this.$activePopover; 144 var options = $.extend(true, {}, $.fn.popover.Constructor.DEFAULTS, ($element && $element.data('bs.popover') || {}).options); 145 if (options[name] !== void 0) { 146 return options[name]; 147 } 148 return defaultValue !== void 0 ? defaultValue : void 0; 149 } 150 }; 151 152})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 153; 154/** 155 * @file 156 * Bootstrap Tooltips. 157 */ 158 159var Drupal = Drupal || {}; 160 161(function ($, Drupal, Bootstrap) { 162 "use strict"; 163 164 /** 165 * Extend the Bootstrap Tooltip plugin constructor class. 166 */ 167 Bootstrap.extendPlugin('tooltip', function (settings) { 168 return { 169 DEFAULTS: { 170 animation: !!settings.tooltip_animation, 171 enabled: settings.tooltip_enabled, 172 html: !!settings.tooltip_html, 173 placement: settings.tooltip_placement, 174 selector: settings.tooltip_selector, 175 trigger: settings.tooltip_trigger, 176 delay: parseInt(settings.tooltip_delay, 10), 177 container: settings.tooltip_container 178 } 179 }; 180 }); 181 182 /** 183 * Bootstrap Tooltips. 184 * 185 * @todo This should really be properly delegated if selector option is set. 186 */ 187 Drupal.behaviors.bootstrapTooltips = { 188 attach: function (context) { 189 // Immediately return if tooltips are not available. 190 if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) { 191 return; 192 } 193 194 var elements = $(context).find('[data-toggle="tooltip"]').toArray(); 195 for (var i = 0; i < elements.length; i++) { 196 var $element = $(elements[i]); 197 var options = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, $element.data()); 198 $element.tooltip(options); 199 } 200 }, 201 detach: function (context) { 202 // Immediately return if tooltips are not available. 203 if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) { 204 return; 205 } 206 207 // Destroy all tooltips. 208 $(context).find('[data-toggle="tooltip"]').tooltip('destroy'); 209 } 210 }; 211 212})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 213;
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.