PageSourceSearch

https://oxfordclimatepolicy.org/sites/default/files/advagg_js/js__…CONR4f5e41_3HoIoATNSvftYvALWtbfxC0-iMohM.js

js oxfordclimatepolicy.org collected 2026-10-02 10:13:52 UTC 15,942 bytes, 430 lines download raw bytes

1/**
2 * @file
3 * Simple responsification of menus.
4 */
5(function ($) {
6  /**
7   * Handle clicks & toggling the menu.
8   */
9  var toggler_click = function() {
10    $(this).parent().toggleClass('responsive-toggled');
11  };
12  /**
13   * Unbind other mouse events on the menu items.
14   *
15   * @todo
16   *   Not sure if it works 100%.
17   *   Doesn't restore binds when out-of-responsive (if window dragging).
18   */
19  function remove_mouse_events(menuElement) {
20    // Determine jQuery version and what disable options we have.
21    var jqVersion = $.fn.jquery;
22    if (jqVersion < 1.7) {
23      $(menuElement).die('mouseover mouseout mouseenter mouseleave');
24      $(menuElement + ' li').die('mouseover mouseout mouseenter mouseleave');
25      $(menuElement + ' li a').die('mouseover mouseout mouseenter mouseleave');
26    }
27    else {
28      $(menuElement).off('hover');
29      $(menuElement + ' li').off('hover');
30      $(menuElement + ' li a').off('hover');
31    }
32    $(menuElement).unbind('mouseover mouseout mouseenter mouseleave');
33    $(menuElement + ' li').unbind('mouseover mouseout mouseenter mouseleave');
34    $(menuElement + ' li a').unbind('mouseover mouseout mouseenter mouseleave');
35  }
36
37  /**
38   * Store classes & IDs for restoring later (if window dragging).
39   */
40  function store_classes_ids(menuElement) {
41    if (!$(menuElement).attr('id')) {
42      $(menuElement).attr('id', 'rm-no-id-main');
43    }
44    if (!$(menuElement).attr('class')) {
45      $(menuElement).attr('class', 'rm-no-class');
46    }
47    $(menuElement).data('removeattr', true)
48      .data('rmids', $(menuElement).attr('id'))
49      .data('rmclasses', $(menuElement).attr('class'));
50    // Handle ULs if selector is parent div.
51    var incr = 0;
52    $(menuElement).find('ul').each(function() {
53      incr++;
54      // Prevent error if there is no id.
55      if (!$(this).attr('id')) {
56        $(this).attr('id', 'rm-no-id-' + incr);
57      }
58      // Prevent error if there is no class.
59      if (!$(this).attr('class')) {
60        $(this).attr('class', 'rm-no-class');
61      }
62      $(this).data('removeattr', true)
63        .data('rmids', $(this).attr('id'))
64        .data('rmclasses', $(this).attr('class'));
65    });
66    // Finally, add our class to the parent.
67    $(menuElement).addClass('responsive-menus-simple');
68  }
69
70  /**
71   * Remove classes & IDs from original menu for easier theming.
72   */
73  function remove_classes_ids(menuElement) {
74    // Handle ULs if selector is parent div.
75    $(menuElement).find('ul').each(function() {
76      $(this).attr('class', 'rm-removed').attr('id', 'rm-removed');
77    });
78    // Remove classes/IDs.
79    $(menuElement).attr('class', 'responsive-menus-simple').attr('id', 'rm-removed');
80  }
81
82  // Iterate through selectors, check window sizes, add some classes.
83  Drupal.behaviors.responsive_menus = {
84    attach: function (context, settings) {
85      settings.responsive_menus = settings.responsive_menus || {};
86      $('body').once('responsive-menus-load', function() {
87        // Only doing this themes that don't include a viewport attribute.
88        // e.g. Bartik for testing out-of-the-box... yeah, stupid.
89        if (!$('meta[name=viewport]').length > 0) {
90          $('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0">');
91        }
92        // Window width with legacy browsers.
93        var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
94        $.each(settings.responsive_menus, function(ind, iteration) {
95          if (iteration.responsive_menus_style != 'responsive_menus_simple') {
96            return true;
97          }
98          if (!iteration.selectors.length) {
99            return true;
100          }
101          var $media_unit = iteration.media_unit || 'px';
102          if ($media_unit === 'em') {
103            var $base_font_size = parseFloat($('body').css('font-size'));
104            var $media_size = iteration.media_size * $base_font_size || 768;
105          }
106          else {
107            var $media_size = iteration.media_size || 768;
108          }
109
110          // Handle clicks & toggling.
111          var toggler_class = '';
112          var toggler_text = iteration.toggler_text;
113          // Iterate through our selectors.
114          $.each(iteration.selectors, function(index, value) {
115            // Stop if there is no menu element.
116            if ($(value).length < 1) {
117              return true;
118            }
119            // Handle nested menus.  Make sure we get the first, but not children.
120            if ($(value).length > 1) {
121              $(value).each(function(val_index) {
122                if (!$(this).parents('ul').length) {
123                  if (!$(this).hasClass('responsive-menus-simple')) {
124                    toggler_class = 'responsive-menus-' + ind + '-' + index + '-' + val_index;
125                    // Store classes & IDs before removing.
126                    if (iteration.remove_attributes) {
127                      store_classes_ids(this);
128                    }
129                    $(this).wrap('<div data-mediasize="' + $media_size + '" class="responsive-menus ' + toggler_class + '" />');
130                    $('.' + toggler_class).prepend('<span class="toggler">' + toggler_text + '</span>');
131                    $('.' + toggler_class + ' .toggler').bind('click', toggler_click);
132                    // Unbind other mouse events.
133                    if (iteration.disable_mouse_events) {
134                      //$(this).data('disablemouse', true);
135                      remove_mouse_events(this);
136                    }
137                    // Use absolute positioning.
138                    if (iteration.absolute) {
139                      $('.' + toggler_class).addClass('absolute');
140                    }
141                    // Handle first size check.
142                    if (windowWidth <= $media_size) {
143                      // Remove attributes setting.
144                      if (iteration.remove_attributes) {
145                        remove_classes_ids(this);
146                      }
147                      $('.' + toggler_class).addClass('responsified');
148                    }
149                  }
150                }
151              });
152            }
153            else {
154              // Single level menus.
155              if (!$(value).hasClass('responsive-menus-simple')) {
156                toggler_class = 'responsive-menus-' + ind + '-' + index;
157                // Store classes & IDs before removing.
158                if (iteration.remove_attributes) {
159                  store_classes_ids(value);
160                }
161                $(value).wrap('<div data-mediasize="' + $media_size + '" class="responsive-menus ' + toggler_class + '" />');
162                $('.' + toggler_class).prepend('<span class="toggler">' + toggler_text + '</span>');
163                $('.' + toggler_class + ' .toggler').bind('click', toggler_click);
164                // Unbind other mouse events.
165                if (iteration.disable_mouse_events) {
166                  // @todo For rebinding mouse events.
167                  /*if ($(value + ' li a').data('events')) {
168                    $(value).data('tmpevents', $(value + ' li a').data('events'));
169                  }*/
170                  remove_mouse_events(value);
171                }
172                // Use absolute positioning.
173                if (iteration.absolute) {
174                  $('.' + toggler_class).addClass('absolute');
175                }
176                // Handle first size check.
177                if (windowWidth <= $media_size) {
178                  // Remove attributes setting.
179                  if (iteration.remove_attributes) {
180                    remove_classes_ids(value);
181                  }
182                  $('.' + toggler_class).addClass('responsified');
183                }
184              }
185            }
186          });
187       });
188        // Handle window resizing.
189        $(window).resize(function() {
190          // Window width with legacy browsers.
191          windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
192          $('.responsive-menus').each(function(menuIndex, menuValue) {
193            var mediasize = $(this).data('mediasize') || 768;
194            // Prevent menu from going off the screen.  This only happens in
195            // non-responsive themes (like Bartik default), but it looks bad.
196            if ($(this).width() > windowWidth) {
197              $(this).data('nonresponsive', true);
198              $(this).width(windowWidth);
199            }
200            var menuElement = $(this).find('.responsive-menus-simple');
201            if (windowWidth >= mediasize) {
202              if (menuElement.data('removeattr')) {
203                menuElement.addClass(menuElement.data('rmclasses'));
204                menuElement.attr('id', menuElement.data('rmids'));
205                menuElement.find('ul').each(function() {
206                  $(this).addClass($(this).data('rmclasses'));
207                  $(this).attr('id', $(this).data('rmids'));
208                });
209              }
210              $(this).removeClass('responsified');
211            }
212            if (windowWidth <= mediasize) {
213              // Now fix repercussions for handling non-responsive themes above.
214              // Stretch width back out w/ the screen.
215              if ($(this).data('nonresponsive') && $(this).width() < windowWidth) {
216                $(this).width(windowWidth);
217              }
218              if (menuElement.data('removeattr')) {
219                remove_classes_ids(menuElement);
220              }
221              $(this).addClass('responsified');
222            }
223          });
224        });
225      });
226    }
227  };
228
229}(jQuery));
230
231;/*})'"*/
232;/*})'"*/
233(function ($) {
234
235Drupal.googleanalytics = {};
236
237$(document).ready(function() {
238
239  // Attach mousedown, keyup, touchstart events to document only and catch
240  // clicks on all elements.
241  $(document.body).bind("mousedown keyup touchstart", function(event) {
242
243    // Catch the closest surrounding link of a clicked element.
244    $(event.target).closest("a,area").each(function() {
245
246      // Is the clicked URL internal?
247      if (Drupal.googleanalytics.isInternal(this.href)) {
248        // Skip 'click' tracking, if custom tracking events are bound.
249        if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
250          // Do nothing here. The custom event will handle all tracking.
251          //console.info("Click on .colorbox item has been detected.");
252        }
253        // Is download tracking activated and the file extension configured for download tracking?
254        else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
255          // Download link clicked.
256          ga("send", {
257            "hitType": "event",
258            "eventCategory": "Downloads",
259            "eventAction": Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(),
260            "eventLabel": Drupal.googleanalytics.getPageUrl(this.href),
261            "transport": "beacon"
262          });
263        }
264        else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
265          // Keep the internal URL for Google Analytics website overlay intact.
266          ga("send", {
267            "hitType": "pageview",
268            "page": Drupal.googleanalytics.getPageUrl(this.href),
269            "transport": "beacon"
270          });
271        }
272      }
273      else {
274        if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
275          // Mailto link clicked.
276          ga("send", {
277            "hitType": "event",
278            "eventCategory": "Mails",
279            "eventAction": "Click",
280            "eventLabel": this.href.substring(7),
281            "transport": "beacon"
282          });
283        }
284        else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
285          if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
286            // External link clicked / No top-level cross domain clicked.
287            ga("send", {
288              "hitType": "event",
289              "eventCategory": "Outbound links",
290              "eventAction": "Click",
291              "eventLabel": this.href,
292              "transport": "beacon"
293            });
294          }
295        }
296      }
297    });
298  });
299
300  // Track hash changes as unique pageviews, if this option has been enabled.
301  if (Drupal.settings.googleanalytics.trackUrlFragments) {
302    window.onhashchange = function() {
303      ga("send", {
304        "hitType": "pageview",
305        "page": location.pathname + location.search + location.hash
306      });
307    };
308  }
309
310  // Colorbox: This event triggers when the transition has completed and the
311  // newly loaded content has been revealed.
312  if (Drupal.settings.googleanalytics.trackColorbox) {
313    $(document).bind("cbox_complete", function () {
314      var href = $.colorbox.element().attr("href");
315      if (href) {
316        ga("send", {
317          "hitType": "pageview",
318          "page": Drupal.googleanalytics.getPageUrl(href)
319        });
320      }
321    });
322  }
323
324});
325
326/**
327 * Check whether the hostname is part of the cross domains or not.
328 *
329 * @param string hostname
330 *   The hostname of the clicked URL.
331 * @param array crossDomains
332 *   All cross domain hostnames as JS array.
333 *
334 * @return boolean
335 */
336Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) {
337  /**
338   * jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is
339   * `null` or `undefined`, https://bugs.jquery.com/ticket/10076,
340   * https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
341   *
342   * @todo: Remove/Refactor in D8
343   */
344  if (!crossDomains) {
345    return false;
346  }
347  else {
348    return $.inArray(hostname, crossDomains) > -1 ? true : false;
349  }
350};
351
352/**
353 * Check whether this is a download URL or not.
354 *
355 * @param string url
356 *   The web url to check.
357 *
358 * @return boolean
359 */
360Drupal.googleanalytics.isDownload = function (url) {
361  var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
362  return isDownload.test(url);
363};
364
365/**
366 * Check whether this is an absolute internal URL or not.
367 *
368 * @param string url
369 *   The web url to check.
370 *
371 * @return boolean
372 */
373Drupal.googleanalytics.isInternal = function (url) {
374  var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
375  return isInternal.test(url);
376};
377
378/**
379 * Check whether this is a special URL or not.
380 *
381 * URL types:
382 *  - gotwo.module /go/* links.
383 *
384 * @param string url
385 *   The web url to check.
386 *
387 * @return boolean
388 */
389Drupal.googleanalytics.isInternalSpecial = function (url) {
390  var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
391  return isInternalSpecial.test(url);
392};
393
394/**
395 * Extract the relative internal URL from an absolute internal URL.
396 *
397 * Examples:
398 * - https://mydomain.com/node/1 -> /node/1
399 * - https://example.com/foo/bar -> https://example.com/foo/bar
400 *
401 * @param string url
402 *   The web url to check.
403 *
404 * @return string
405 *   Internal website URL
406 */
407Drupal.googleanalytics.getPageUrl = function (url) {
408  var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i");
409  return url.replace(extractInternalUrl, '');
410};
411
412/**
413 * Extract the download file extension from the URL.
414 *
415 * @param string url
416 *   The web url to check.
417 *
418 * @return string
419 *   The file extension of the passed url. e.g. "zip", "txt"
420 */
421Drupal.googleanalytics.getDownloadExtension = function (url) {
422  var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
423  var extension = extractDownloadextension.exec(url);
424  return (extension === null) ? '' : extension[1];
425};
426
427})(jQuery);
428
429;/*})'"*/
430;/*})'"*/

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.