PageSourceSearch

https://queenslibrary.org/themes/bootstrap/js/popover.js?tl8z8n

js queenslibrary.org collected 2026-09-24 08:47:23 UTC 5,659 bytes, 152 lines download raw bytes

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);

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.