PageSourceSearch

https://www.iabuk.com/modules/contrib/colorbox/js/colorbox.js?v=11.3.14

js iabuk.com collected 2026-09-24 08:25:27 UTC 6,425 bytes, 197 lines download raw bytes

1/**
2 * @file
3 * Colorbox JS.
4 */
5
6(function ($, Drupal, drupalSettings, once) {
7
8  'use strict';
9
10  Drupal.behaviors.initColorbox = {
11    attach: function (context, settings) {
12      if (typeof $.colorbox !== 'function' || typeof settings.colorbox === 'undefined') {
13        return;
14      }
15
16      if (settings.colorbox.mobiledetect && window.matchMedia) {
17        // Disable Colorbox for small screens.
18        var mq = window.matchMedia('(max-device-width: ' + settings.colorbox.mobiledevicewidth + ')');
19        if (mq.matches) {
20          $.colorbox.remove();
21          return;
22        }
23      }
24
25      settings.colorbox.rel = function () {
26        return $(this).data('colorbox-gallery');
27      };
28
29      settings.colorbox.html = function () {
30        var $modalContent = $(this).find('> .modal-content');
31        return $modalContent.length ? $(this).find('> .modal-content').children().clone() : false;
32      };
33
34      $(once('init-colorbox', '.colorbox', context))
35        .each(function() {
36        // Only images are supported for the "colorbox" class.
37        // The "photo" setting forces the href attribute to be treated as an image.
38        var extendParams = {
39          photo: true
40        };
41        // If a title attribute is supplied, sanitize it.
42        var title = $(this).attr('title');
43        if (typeof title === 'undefined') {
44          title = this.dataset.cboxTitle;
45        }
46        if (title) {
47          extendParams.title = Drupal.colorbox.sanitizeMarkup(title);
48        }
49        $(this).colorbox($.extend({}, settings.colorbox, extendParams));
50
51        // Only allow http or https protocol in hrefs.
52        var href = $(this).attr('href');
53        var protocolRegex = /^(https?)/;
54        if (href && href.substring(0, 1) !== '/') {
55          var protocol = href.split(':')[0];
56          // Use a regex to match http or https protocol.
57          if (!protocolRegex.test(protocol)) {
58            $(this).removeAttr('href');
59          }
60        }
61        var dataHref = this.dataset.cboxHref;
62        if (dataHref && dataHref.substring(0, 1) !== '/') {
63          var dataProtocol = dataHref.split(':')[0];
64          if (!protocolRegex.test(dataProtocol)) {
65            delete this.dataset.cboxHref;
66          }
67        }
68
69        // Since the sanitized title has been passed to colorbox settings,
70        // delete the unsanitized data-cbox-title attribute.
71        delete this.dataset.cboxTitle;
72
73        // Disallow dangerous data attributes.
74        delete this.dataset.cboxIframeAttrs;
75        delete this.dataset.cboxCreateiframe;
76        delete this.dataset.cboxCreateimg;
77
78        // If cboxImgAttrs is used, limit attributes to avoid rendering HTML.
79        let imgAttrs = this.dataset.cboxImgAttrs;
80        if (imgAttrs) {
81          const allowedAttrs = [
82            'alt',
83            'width',
84            'height',
85            'title',
86            'loading',
87            'decoding',
88            'referrerpolicy',
89            'usemap',
90            'longdesc',
91            'role',
92          ];
93          const ariaPattern = /^aria-[a-z-]+$/;
94          try {
95            imgAttrs = JSON.parse(imgAttrs);
96            if (typeof imgAttrs === 'object') {
97              // Limit attributes to allow list and aria-* attributes.
98              for (const attr in imgAttrs) {
99                const lowerAttr = attr.toLowerCase();
100                if (!allowedAttrs.includes(lowerAttr) && !ariaPattern.test(lowerAttr)) {
101                  delete imgAttrs[attr];
102                }
103              }
104              this.dataset.cboxImgAttrs = JSON.stringify(imgAttrs);
105            }
106            else {
107              delete this.dataset.cboxImgAttrs;
108            }
109          }
110          catch (e) {
111            // Improper value.
112            delete this.dataset.cboxImgAttrs;
113          }
114        }
115
116
117        // Sanitize other data attributes.
118        var sanitizeDataList = ['cboxNext', 'cboxPrevious', 'cboxCurrent',
119          'cboxClose', 'cboxSlideshowstop', 'cboxSlideshowstart',
120          'cboxXhrError', 'cboxImgerror', 'cboxHtml'
121        ];
122        for (var a of sanitizeDataList) {
123          if (this.dataset.hasOwnProperty(a)) {
124            this.dataset[a] = Drupal.colorbox.sanitizeMarkup(this.dataset[a]);
125          }
126        }
127      });
128
129      $('.colorbox', context).colorbox({
130        onComplete: function (e) {
131          var focus = $('#cboxContent').find('#cboxPrevious').css('display') !== 'none' ? $('#cboxContent').find('#cboxPrevious') : $('#cboxContent').find('#cboxClose');
132          focus.focus();
133
134          $('#cboxContent').on('keydown', function (e) {
135            var keyCode = e.keyCode || e.which;
136            var firstElement = $('#cboxContent').find('#cboxPrevious').last().is(':focus');
137            var lastElement = $('#cboxContent').find('#cboxClose').first().is(':focus');
138            if (keyCode === 9 && !e.shiftKey && lastElement) {
139              e.preventDefault();
140              $('#cboxContent').find('#cboxPrevious').first().focus();
141            }
142            else if (keyCode === 9 && e.shiftKey && firstElement) {
143              e.preventDefault();
144              $('#cboxContent').find('#cboxClose').first().focus();
145            }
146          });
147        }
148      });
149    }
150  };
151
152  // Create colorbox namespace if it doesn't exist.
153  if (!Drupal.hasOwnProperty('colorbox')) {
154    Drupal.colorbox = {};
155  }
156
157  /**
158   * Global function to allow sanitizing captions and control strings.
159   *
160   * @param markup
161   *   String containing potential markup.
162   * @return @string
163   *  Sanitized string with potentially dangerous markup removed.
164   */
165  Drupal.colorbox.sanitizeMarkup = function(markup) {
166    // If DOMPurify installed, allow some HTML. Otherwise, treat as plain text.
167    if (typeof DOMPurify !== 'undefined') {
168      var purifyConfig = {
169        ALLOWED_TAGS: [
170          'a',
171          'b',
172          'strong',
173          'i',
174          'em',
175          'u',
176          'cite',
177          'code',
178          'br'
179        ],
180        ALLOWED_ATTR: [
181          'href',
182          'hreflang',
183          'title',
184          'target'
185        ]
186      }
187      if (drupalSettings.hasOwnProperty('dompurify_custom_config')) {
188        purifyConfig = drupalSettings.dompurify_custom_config;
189      }
190      return DOMPurify.sanitize(markup, purifyConfig);
191    }
192    else {
193      return Drupal.checkPlain(markup);
194    }
195  }
196
197})(jQuery, Drupal, drupalSettings, once);

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.