PageSourceSearch

https://wadsworth.org/modules/contrib/glightbox/js/glightbox.js?v=11.4.6

js wadsworth.org collected 2026-10-01 09:19:37 UTC 4,102 bytes, 129 lines download raw bytes

1/**
2 * @file
3 * GLightbox JS.
4 */
5
6(function (Drupal, drupalSettings, once) {
7  'use strict';
8
9  // Create glightbox namespace if it doesn't exist.
10  if (!Drupal.hasOwnProperty('glightbox')) {
11    Drupal.glightbox = {};
12  }
13
14  /**
15   * Global function to allow sanitizing captions and control strings.
16   *
17   * @param markup
18   *   String containing potential markup.
19   * @return {string}
20   *   Sanitized string with potentially dangerous markup removed.
21   */
22  Drupal.glightbox.sanitizeMarkup = function(markup) {
23    if (typeof DOMPurify !== 'undefined') {
24      var purifyConfig = {
25        ALLOWED_TAGS: [
26          'a', 'b', 'strong', 'i', 'em', 'u', 'cite', 'code', 'br', 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'span'
27        ],
28        ALLOWED_ATTR: [
29          'href', 'hreflang', 'title', 'target',
30        ]
31      };
32      if (typeof drupalSettings !== 'undefined' && drupalSettings.hasOwnProperty('dompurify_custom_config')) {
33        purifyConfig = drupalSettings.dompurify_custom_config;
34      }
35      return DOMPurify.sanitize(markup, purifyConfig);
36    }
37    else if (typeof Drupal.checkPlain === 'function') {
38      return Drupal.checkPlain(markup);
39    }
40    else {
41      // Fallback: basic escaping.
42      return String(markup).replace(/[&<>"]/g, function (c) {
43        return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c];
44      });
45    }
46  };
47
48  /**
49   * Sanitise a user-supplied href.
50   * - Allows absolute http/https/ftp/ftps only (per SAFE_PROTOCOL_RE).
51   * - Drops *all* relative or protocol-relative URLs (“/foo”, “//cdn…”, “../bar”, …).
52   * - Returns the cleaned, canonicalised URL string, or an empty string when disallowed.
53   */
54  Drupal.glightbox.sanitizeHref = function(rawHref) {
55    if (typeof rawHref !== 'string') return '';
56
57    // Strip obvious obfuscation.
58    const clean = rawHref
59      // Null bytes.
60      .replace(/\u0000/g, '')
61      // Control chars.
62      .replace(/[\t\n\r]/g, '')
63      .trim();
64
65    const SAFE_PROTOCOL_RE = /^(?:(?:(?:f|ht)tps?):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
66    // Fast-fail if protocol isn’t in the allow-list.
67    if (!SAFE_PROTOCOL_RE.test(clean)) return '';
68
69    // Require the string to *explicitly* contain a protocol.
70    // Skip relative / protocol-relative URLs.
71    if (!/^[a-z][a-z0-9+.\-]*:/.test(clean)) return '';
72
73    // Let the URL constructor canonicalise & validate.
74    try {
75      // Absolute URL required.
76      const url = new URL(clean);
77      return url.href;
78    } catch {
79      // Malformed, unreachable, etc.
80      return '';
81    }
82  }
83
84  Drupal.behaviors.initGLightbox = {
85    attach: function (context, settings) {
86      // Sanitize data-title and data-description attributes on all .glightbox elements before GLightbox is initialized.
87      document.querySelectorAll('.glightbox').forEach(el => {
88        el.getAttributeNames()
89          .filter(name => name.startsWith('data-'))
90          .forEach(name => {
91            const rawValue = el.getAttribute(name);
92            let clean = Drupal.glightbox.sanitizeMarkup(rawValue);
93            if (name === 'data-href') {
94              clean = Drupal.glightbox.sanitizeHref(clean);
95            }
96            el.setAttribute(name, clean);
97          });
98      });
99      const options = settings.glightbox || {};
100      const lightbox = GLightbox(options);
101
102      lightbox.on('slide_changed', ({ prev, current }) => {
103        const { slideIndex, slideNode, slideConfig, player } = current;
104
105        // Video autoplay if it's possible.
106        if (player) {
107          if (!player.ready) {
108            // If player is not ready.
109            player.on('ready', (event) => {
110              // Do something when video is ready.
111            });
112          }
113
114          player.on('play', (event) => {
115            // console.log('Started play');
116          });
117
118          player.on('volumechange', (event) => {
119            // console.log('Volume change');
120          });
121
122          player.on('ended', (event) => {
123            // console.log('Video ended');
124          });
125        }
126      });
127    },
128  };
129})(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.