PageSourceSearch

https://www.columbiaortho.org/sites/default/files/js/js_LGLwUURukNDt-7QnIF_eEzHgoatQpr_osd2FrSSMM70.js

js columbiaortho.org collected 2026-10-03 21:01:51 UTC 44,500 bytes, 1,291 lines download raw bytes

1(function ($) {
2
3  Drupal.behaviors.esi = {
4    attach: function (context, settings) {
5      var contextualize_urls = (typeof Drupal.settings.ESI !== 'undefined') && Drupal.settings.ESI.contextualize_URLs;
6      if (contextualize_urls) {
7        $().esiTags().DrupalESIContextualizeURL().handleESI();
8      }
9      else {
10        $().esiTags().handleESI();
11      }
12    }
13  };
14
15  // Add the ESI context from the cookie to the ESI URL.
16  $.fn.DrupalESIContextualizeURL = function() {
17    // Regex to find the ESI context from an ESI src URL.
18    var esi_context_regexp = /\/CACHE%3D([^\/]+)$/;
19
20    $(this).each(function() {
21      src = $(this).attr('src');
22      
23      // Get the context key from the ESI src attribute.
24      // Contexts are provided in the last element: e.g. /CACHE=FOO.
25      if (match = $(this).attr('src').match(esi_context_regexp)) {
26        context_key = match[1];
27        context_val = esi_get_user_context(context_key);
28        new_src = src.replace(esi_context_regexp, '/CACHE=' + context_val);
29        $(this).attr('src', new_src);
30      }
31    });
32    return this;
33  }
34
35  // Attach to ajax request, find block that was created and
36  // attachBehaviours to it.
37  $( document ).ajaxSuccess(function( event, request, settings ) {
38    if (event.target.nodeName.toLowerCase() == 'esi:include') {
39      var returned = $('<div></div>').html($.trim(request.responseText)).contents();
40      if (returned[0] !== undefined) {
41        var elem = $('#' + returned[0].id);
42        if (elem !== undefined) {
43          Drupal.attachBehaviors(elem[0], Drupal.settings);
44        }
45      }
46    }
47  });
48
49})(jQuery);
50
51/**
52 * Get the value of a particular context.
53 */
54function esi_get_user_context(context_key) {
55  // Transform a context string (e.g. 'USER') into the actual cookie name.
56  cookie_name = Drupal.settings.ESI.cookie_prefix + context_key + Drupal.settings.ESI.cookie_suffix;
57  return esi_get_value_from_cookie(cookie_name);
58}
59
60/**
61 * Get the value of a named cookie.
62 */
63function esi_get_value_from_cookie(cookie_name) {
64  var all_cookies = document.cookie.split(';');
65  for (var i=0; i < all_cookies.length; i++) {
66    if (all_cookies[i].indexOf(cookie_name) === 1) {
67      var values = all_cookies[i].split('=');
68      return values[1];
69    }
70  }
71  return '';
72}
73;
74/**
75 * jQuery ESI Plugin v1.0
76 * http://github.com/manarth/jquery_esi
77 *
78 * Dual licensed under the MIT and GPL licenses:
79 *   http://www.opensource.org/licenses/mit-license.php
80 *   http://www.gnu.org/licenses/gpl.html
81 *
82 * Usage:
83 * $().esiTags().handleESI();
84 */
85
86(function ($) {
87
88  // Fetch all ESI tags.
89  $.fn.esiTags = function() {
90    // Initialise a jQuery collection to return.
91    esi_tags = $();
92
93    // The handler can be called as $().esiTags, or $('foo').esiTags().
94    // Ensure we have an iterable collection in either instance.
95    if (this.length == 0) {
96      collection = $('html');
97    }
98    else {
99      collection = this;
100    }
101
102    collection.each(function() {
103      // Retrieve the base DOM element, in order to access the DOM method
104      // getElementsByTagName.
105      base_element = $(this).get(0);
106      // Discover the <esi:include> tags.
107      jQuery.each(base_element.getElementsByTagName('esi:include'), function(i, val) {
108        // Some DOMs fail to recognise that the ESI include tag is self-
109        // closing, so they treat following tags as child nodes.
110        if ($(this).children().length > 0) {
111          // Move the child nodes to become siblings.
112          children = $(this).children().detach();
113          $(this).after(children);
114        }
115        esi_tags = esi_tags.add($(this));
116      });
117      // Discover the <esi:remove> tags.
118      jQuery.each(base_element.getElementsByTagName('esi:remove'), function(i, val) {
119        // ESI remove tags are not self-closing, so no special treatment for
120        // child nodes is needed.
121        esi_tags = esi_tags.add($(this));
122      });
123    });
124    return esi_tags;
125  };
126
127  // Move child nodes to siblings.
128  $.fn.handleESIChildren = function() {
129    $(this).each(function() {
130    });
131    return this;
132  }
133
134  // Handle ESI tags.
135  // Delegates to either .handleESIInclude() or .handleESIRemove() as needed.
136  $.fn.handleESI = function() {
137    $(this).each(function() {
138      switch (this.nodeName.toLowerCase()) {
139        case 'esi:include':
140          $(this).handleESIInclude();
141          break;
142      
143        case 'esi:remove':
144          $(this).handleESIRemove();
145          break;
146      }
147    });
148
149    return this;
150  }
151
152  // Handle a single ESI Include tag.
153  $.fn.handleESIInclude = function() {
154    src = $(this).attr('src');
155    jQuery.ajax({
156      context: this,
157      headers: {
158        'X-ESI-REFERER-ORIGINAL' : document.referrer
159      },
160      url: src,
161      success: function(data, textStatus, jqXHR) {
162        esiElement = $(this);
163        esiElement.replaceWith(data);
164      }
165    });
166  }
167
168  // Handle a single ESI Remove tag.
169  $.fn.handleESIRemove = function() {
170    $(this).replaceWith('');
171  }
172
173})(jQuery);
174;
175/**
176 * @file
177 * Attaches the calendar behavior to all required fields.
178 */
179
180(function ($) {
181  function makeFocusHandler(e) {
182    if (!$(this).hasClass('date-popup-init')) {
183      var datePopup = e.data;
184      // Explicitely filter the methods we accept.
185      switch (datePopup.func) {
186        case 'datepicker':
187          $(this)
188            .datepicker(datePopup.settings)
189            .addClass('date-popup-init')
190            .focus();
191          if (datePopup.settings.syncEndDate) {
192            $('.start-date-wrapper').each(function () {
193              var start_date_wrapper = this;
194              $(this).find('input:eq(0)').change(function () {
195                $(start_date_wrapper).next('.end-date-wrapper').find('input:eq(0)').val($(this).val());
196              });
197            });
198          }
199          break;
200
201        case 'timeEntry':
202          $(this)
203            .timeEntry(datePopup.settings)
204            .addClass('date-popup-init')
205            .focus();
206          break;
207
208        case 'timepicker':
209          // Translate the PHP date format into the style the timepicker uses.
210          datePopup.settings.timeFormat = datePopup.settings.timeFormat
211            // 12-hour, leading zero,
212            .replace('h', 'hh')
213            // 12-hour, no leading zero.
214            .replace('g', 'h')
215            // 24-hour, leading zero.
216            .replace('H', 'HH')
217            // 24-hour, no leading zero.
218            .replace('G', 'H')
219            // AM/PM.
220            .replace('A', 'p')
221            // Minutes with leading zero.
222            .replace('i', 'mm')
223            // Seconds with leading zero.
224            .replace('s', 'ss');
225
226          datePopup.settings.startTime = new Date(datePopup.settings.startTime);
227          $(this)
228            .timepicker(datePopup.settings)
229            .addClass('date-popup-init')
230            .focus();
231          break;
232      }
233    }
234  }
235
236  Drupal.behaviors.date_popup = {
237    attach: function (context) {
238      for (var id in Drupal.settings.datePopup) {
239        $('#' + id).bind('focus', Drupal.settings.datePopup[id], makeFocusHandler);
240      }
241    }
242  };
243
244})(jQuery);
245;
246/**
247 * @file
248 */
249
250(function ($) {
251
252  'use strict';
253
254  Drupal.extlink = Drupal.extlink || {};
255
256  Drupal.extlink.attach = function (context, settings) {
257    if (!settings.hasOwnProperty('extlink')) {
258      return;
259    }
260
261    // Strip the host name down, removing ports, subdomains, or www.
262    var pattern = /^(([^\/:]+?\.)*)([^\.:]{1,})((\.[a-z0-9]{1,253})*)(:[0-9]{1,5})?$/;
263    var host = window.location.host.replace(pattern, '$2$3$6');
264    var subdomain = window.location.host.replace(host, '');
265
266    // Determine what subdomains are considered internal.
267    var subdomains;
268    if (settings.extlink.extSubdomains) {
269      subdomains = '([^/]*\\.)?';
270    }
271    else if (subdomain === 'www.' || subdomain === '') {
272      subdomains = '(www\\.)?';
273    }
274    else {
275      subdomains = subdomain.replace('.', '\\.');
276    }
277
278    // Build regular expressions that define an internal link.
279    var internal_link = new RegExp('^https?://([^@]*@)?' + subdomains + host, 'i');
280
281    // Extra internal link matching.
282    var extInclude = false;
283    if (settings.extlink.extInclude) {
284      extInclude = new RegExp(settings.extlink.extInclude.replace(/\\/, '\\'), 'i');
285    }
286
287    // Extra external link matching.
288    var extExclude = false;
289    if (settings.extlink.extExclude) {
290      extExclude = new RegExp(settings.extlink.extExclude.replace(/\\/, '\\'), 'i');
291    }
292
293    // Extra external link CSS selector exclusion.
294    var extCssExclude = false;
295    if (settings.extlink.extCssExclude) {
296      extCssExclude = settings.extlink.extCssExclude;
297    }
298
299    // Extra external link CSS selector explicit.
300    var extCssExplicit = false;
301    if (settings.extlink.extCssExplicit) {
302      extCssExplicit = settings.extlink.extCssExplicit;
303    }
304
305    // Define the jQuery method (either 'append' or 'prepend') of placing the icon, defaults to 'append'.
306    var extIconPlacement = settings.extlink.extIconPlacement || 'append';
307
308    // Find all links which are NOT internal and begin with http as opposed
309    // to ftp://, javascript:, etc. other kinds of links.
310    // When operating on the 'this' variable, the host has been appended to
311    // all links by the browser, even local ones.
312    // In jQuery 1.1 and higher, we'd use a filter method here, but it is not
313    // available in jQuery 1.0 (Drupal 5 default).
314    var external_links = [];
315    var mailto_links = [];
316    $('a:not([data-extlink]), area:not([data-extlink])', context).each(function (el) {
317      try {
318        var url = '';
319        if (typeof this.href == 'string') {
320          url = this.href.toLowerCase();
321        }
322        // Handle SVG links (xlink:href).
323        else if (typeof this.href == 'object') {
324          url = this.href.baseVal;
325        }
326        if (url.indexOf('http') === 0
327          && ((!url.match(internal_link) && !(extExclude && url.match(extExclude))) || (extInclude && url.match(extInclude)))
328          && !(extCssExclude && $(this).is(extCssExclude))
329          && !(extCssExclude && $(this).parents(extCssExclude).length > 0)
330          && !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
331          external_links.push(this);
332        }
333        // Do not include area tags with begin with mailto: (this prohibits
334        // icons from being added to image-maps).
335        else if (this.tagName !== 'AREA'
336          && url.indexOf('mailto:') === 0
337          && !(extCssExclude && $(this).parents(extCssExclude).length > 0)
338          && !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
339          mailto_links.push(this);
340        }
341      }
342      // IE7 throws errors often when dealing with irregular links, such as:
343      // <a href="node/10"></a> Empty tags.
344      // <a href="http://user:[email protected]">example</a> User:pass syntax.
345      catch (error) {
346        return false;
347      }
348    });
349
350    if (settings.extlink.extClass) {
351      Drupal.extlink.applyClassAndSpan(external_links, settings.extlink.extClass, extIconPlacement);
352    }
353
354    if (settings.extlink.mailtoClass) {
355      Drupal.extlink.applyClassAndSpan(mailto_links, settings.extlink.mailtoClass, extIconPlacement);
356    }
357
358    if (settings.extlink.extTarget) {
359      // Apply the target attribute to all links.
360      $(external_links).attr('target', settings.extlink.extTarget);
361      // Add rel attributes noopener and noreferrer.
362      $(external_links).attr('rel', function (i, val) {
363        // If no rel attribute is present, create one with the values noopener and noreferrer.
364        if (val == null) {
365          return 'noopener noreferrer';
366        }
367        // Check to see if rel contains noopener or noreferrer. Add what doesn't exist.
368        if (val.indexOf('noopener') > -1 || val.indexOf('noreferrer') > -1) {
369          if (val.indexOf('noopener') === -1) {
370            return val + ' noopener';
371          }
372          if (val.indexOf('noreferrer') === -1) {
373            return val + ' noreferrer';
374          }
375          // Both noopener and noreferrer exist. Nothing needs to be added.
376          else {
377            return val;
378          }
379        }
380        // Else, append noopener and noreferrer to val.
381        else {
382          return val + ' noopener noreferrer';
383        }
384      });
385    }
386
387    Drupal.extlink = Drupal.extlink || {};
388
389    // Set up default click function for the external links popup. This should be
390    // overridden by modules wanting to alter the popup.
391    Drupal.extlink.popupClickHandler = Drupal.extlink.popupClickHandler || function () {
392      if (settings.extlink.extAlert) {
393        return confirm(settings.extlink.extAlertText);
394      }
395    };
396
397    $(external_links).click(function (e) {
398      return Drupal.extlink.popupClickHandler(e, this);
399    });
400  };
401
402  /**
403   * Apply a class and a trailing <span> to all links not containing images.
404   *
405   * @param {object[]} links
406   *   An array of DOM elements representing the links.
407   * @param {string} class_name
408   *   The class to apply to the links.
409   * @param {string} icon_placement
410   *   'append' or 'prepend' the icon to the link.
411   */
412  Drupal.extlink.applyClassAndSpan = function (links, class_name, icon_placement) {
413    var $links_to_process;
414    if (Drupal.settings.extlink.extImgClass) {
415      $links_to_process = $(links);
416    }
417    else {
418      var links_with_images = $(links).find('img').parents('a');
419      $links_to_process = $(links).not(links_with_images);
420    }
421    // Add data-extlink attribute.
422    $links_to_process.attr('data-extlink', '');
423    var i;
424    var length = $links_to_process.length;
425    for (i = 0; i < length; i++) {
426      var $link = $($links_to_process[i]);
427      if ($link.css('display') === 'inline' || $link.css('display') === 'inline-block' || $link.css('display') === 'block') {
428        if (Drupal.settings.extlink.extUseFontAwesome) {
429          if (class_name === Drupal.settings.extlink.mailtoClass) {
430            $link[icon_placement]('<span class="fa-' + class_name + ' extlink"><span class="fa fa-envelope-o" title="' + Drupal.settings.extlink.mailtoLabel + '"></span><span class="element-invisible">' + Drupal.settings.extlink.mailtoLabel + '</span></span>');
431          }
432          else {
433            $link[icon_placement]('<span class="fa-' + class_name + ' extlink"><span class="fa fa-external-link" title="' + Drupal.settings.extlink.extLabel + '"></span><span class="element-invisible">' + Drupal.settings.extlink.extLabel + '</span></span>');
434          }
435        }
436        else {
437          if (class_name === Drupal.settings.extlink.mailtoClass) {
438            $link[icon_placement]('<span class="' + class_name + '"><span class="element-invisible">' + Drupal.settings.extlink.mailtoLabel + '</span></span>');
439          }
440          else {
441            $link[icon_placement]('<span class="' + class_name + '"><span class="element-invisible">' + Drupal.settings.extlink.extLabel + '</span></span>');
442          }
443        }
444      }
445    }
446  };
447
448  Drupal.behaviors.extlink = Drupal.behaviors.extlink || {};
449  Drupal.behaviors.extlink.attach = function (context, settings) {
450    // Backwards compatibility, for the benefit of modules overriding extlink
451    // functionality by defining an "extlinkAttach" global function.
452    if (typeof extlinkAttach === 'function') {
453      extlinkAttach(context);
454    }
455    else {
456      Drupal.extlink.attach(context, settings);
457    }
458  };
459
460})(jQuery);
461;
462(function ($) {
463
464/**
465 * A progressbar object. Initialized with the given id. Must be inserted into
466 * the DOM afterwards through progressBar.element.
467 *
468 * method is the function which will perform the HTTP request to get the
469 * progress bar state. Either "GET" or "POST".
470 *
471 * e.g. pb = new progressBar('myProgressBar');
472 *      some_element.appendChild(pb.element);
473 */
474Drupal.progressBar = function (id, updateCallback, method, errorCallback) {
475  var pb = this;
476  this.id = id;
477  this.method = method || 'GET';
478  this.updateCallback = updateCallback;
479  this.errorCallback = errorCallback;
480
481  // The WAI-ARIA setting aria-live="polite" will announce changes after users
482  // have completed their current activity and not interrupt the screen reader.
483  this.element = $('<div class="progress" aria-live="polite"></div>').attr('id', id);
484  this.element.html('<div class="bar"><div class="filled"></div></div>' +
485                    '<div class="percentage"></div>' +
486                    '<div class="message">&nbsp;</div>');
487};
488
489/**
490 * Set the percentage and status message for the progressbar.
491 */
492Drupal.progressBar.prototype.setProgress = function (percentage, message) {
493  if (percentage >= 0 && percentage <= 100) {
494    $('div.filled', this.element).css('width', percentage + '%');
495    $('div.percentage', this.element).html(percentage + '%');
496  }
497  $('div.message', this.element).html(message);
498  if (this.updateCallback) {
499    this.updateCallback(percentage, message, this);
500  }
501};
502
503/**
504 * Start monitoring progress via Ajax.
505 */
506Drupal.progressBar.prototype.startMonitoring = function (uri, delay) {
507  this.delay = delay;
508  this.uri = uri;
509  this.sendPing();
510};
511
512/**
513 * Stop monitoring progress via Ajax.
514 */
515Drupal.progressBar.prototype.stopMonitoring = function () {
516  clearTimeout(this.timer);
517  // This allows monitoring to be stopped from within the callback.
518  this.uri = null;
519};
520
521/**
522 * Request progress data from server.
523 */
524Drupal.progressBar.prototype.sendPing = function () {
525  if (this.timer) {
526    clearTimeout(this.timer);
527  }
528  if (this.uri) {
529    var pb = this;
530    // When doing a post request, you need non-null data. Otherwise a
531    // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
532    $.ajax({
533      type: this.method,
534      url: this.uri,
535      data: '',
536      dataType: 'json',
537      success: function (progress) {
538        // Display errors.
539        if (progress.status == 0) {
540          pb.displayError(progress.data);
541          return;
542        }
543        // Update display.
544        pb.setProgress(progress.percentage, progress.message);
545        // Schedule next timer.
546        pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay);
547      },
548      error: function (xmlhttp) {
549        pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri));
550      }
551    });
552  }
553};
554
555/**
556 * Display errors on the page.
557 */
558Drupal.progressBar.prototype.displayError = function (string) {
559  var error = $('<div class="messages error"></div>').html(string);
560  $(this.element).before(error).hide();
561
562  if (this.errorCallback) {
563    this.errorCallback(this);
564  }
565};
566
567})(jQuery);
568;
569/**
570 * @file
571 *
572 * Implement a modal form.
573 *
574 * @see modal.inc for documentation.
575 *
576 * This javascript relies on the CTools ajax responder.
577 */
578
579(function ($) {
580  // Make sure our objects are defined.
581  Drupal.CTools = Drupal.CTools || {};
582  Drupal.CTools.Modal = Drupal.CTools.Modal || {};
583
584  /**
585   * Display the modal
586   *
587   * @todo -- document the settings.
588   */
589  Drupal.CTools.Modal.show = function(choice) {
590    var opts = {};
591
592    if (choice && typeof choice == 'string' && Drupal.settings[choice]) {
593      // This notation guarantees we are actually copying it.
594      $.extend(true, opts, Drupal.settings[choice]);
595    }
596    else if (choice) {
597      $.extend(true, opts, choice);
598    }
599
600    var defaults = {
601      modalTheme: 'CToolsModalDialog',
602      throbberTheme: 'CToolsModalThrobber',
603      animation: 'show',
604      animationSpeed: 'fast',
605      modalSize: {
606        type: 'scale',
607        width: .8,
608        height: .8,
609        addWidth: 0,
610        addHeight: 0,
611        // How much to remove from the inner content to make space for the
612        // theming.
613        contentRight: 25,
614        contentBottom: 45
615      },
616      modalOptions: {
617        opacity: .55,
618        background: '#fff'
619      },
620      modalClass: 'default'
621    };
622
623    var settings = {};
624    $.extend(true, settings, defaults, Drupal.settings.CToolsModal, opts);
625
626    if (Drupal.CTools.Modal.currentSettings && Drupal.CTools.Modal.currentSettings != settings) {
627      Drupal.CTools.Modal.modal.remove();
628      Drupal.CTools.Modal.modal = null;
629    }
630
631    Drupal.CTools.Modal.currentSettings = settings;
632
633    var resize = function(e) {
634      // When creating the modal, it actually exists only in a theoretical
635      // place that is not in the DOM. But once the modal exists, it is in the
636      // DOM so the context must be set appropriately.
637      var context = e ? document : Drupal.CTools.Modal.modal;
638
639      if (Drupal.CTools.Modal.currentSettings.modalSize.type == 'scale') {
640        var width = $(window).width() * Drupal.CTools.Modal.currentSettings.modalSize.width;
641        var height = $(window).height() * Drupal.CTools.Modal.currentSettings.modalSize.height;
642      }
643      else {
644        var width = Drupal.CTools.Modal.currentSettings.modalSize.width;
645        var height = Drupal.CTools.Modal.currentSettings.modalSize.height;
646      }
647
648      // Use the additionol pixels for creating the width and height.
649      $('div.ctools-modal-content', context).css({
650        'width': width + Drupal.CTools.Modal.currentSettings.modalSize.addWidth + 'px',
651        'height': height + Drupal.CTools.Modal.currentSettings.modalSize.addHeight + 'px'
652      });
653      $('div.ctools-modal-content .modal-content', context).css({
654        'width': (width - Drupal.CTools.Modal.currentSettings.modalSize.contentRight) + 'px',
655        'height': (height - Drupal.CTools.Modal.currentSettings.modalSize.contentBottom) + 'px'
656      });
657    };
658
659    if (!Drupal.CTools.Modal.modal) {
660      Drupal.CTools.Modal.modal = $(Drupal.theme(settings.modalTheme));
661      if (settings.modalSize.type == 'scale') {
662        $(window).bind('resize', resize);
663      }
664    }
665
666    resize();
667
668    $('span.modal-title', Drupal.CTools.Modal.modal).html(Drupal.CTools.Modal.currentSettings.loadingText);
669    Drupal.CTools.Modal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed, settings.modalClass);
670    $('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme)).addClass('ctools-modal-loading');
671
672    // Position autocomplete results based on the scroll position of the modal.
673    $('#modalContent .modal-content').delegate('input.form-autocomplete', 'keyup', function() {
674      $('#autocomplete').css('top', $(this).position().top + $(this).outerHeight() + $(this).offsetParent().filter('#modal-content').scrollTop());
675    });
676  };
677
678  /**
679   * Hide the modal
680   */
681  Drupal.CTools.Modal.dismiss = function() {
682    if (Drupal.CTools.Modal.modal) {
683      Drupal.CTools.Modal.unmodalContent(Drupal.CTools.Modal.modal);
684    }
685  };
686
687  /**
688   * Provide the HTML to create the modal dialog.
689   */
690  Drupal.theme.prototype.CToolsModalDialog = function () {
691    var html = '';
692    html += '<div id="ctools-modal">';
693    html += '  <div class="ctools-modal-content">'; // panels-modal-content
694    html += '    <div class="modal-header">';
695    html += '      <a class="close" href="#">';
696    html +=          Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage;
697    html += '      </a>';
698    html += '      <span id="modal-title" class="modal-title">&nbsp;</span>';
699    html += '    </div>';
700    html += '    <div id="modal-content" class="modal-content">';
701    html += '    </div>';
702    html += '  </div>';
703    html += '</div>';
704
705    return html;
706  };
707
708  /**
709   * Provide the HTML to create the throbber.
710   */
711  Drupal.theme.prototype.CToolsModalThrobber = function () {
712    var html = '';
713    html += '<div id="modal-throbber">';
714    html += '  <div class="modal-throbber-wrapper">';
715    html +=      Drupal.CTools.Modal.currentSettings.throbber;
716    html += '  </div>';
717    html += '</div>';
718
719    return html;
720  };
721
722  /**
723   * Figure out what settings string to use to display a modal.
724   */
725  Drupal.CTools.Modal.getSettings = function (object) {
726    var match = $(object).attr('class').match(/ctools-modal-(\S+)/);
727    if (match) {
728      return match[1];
729    }
730  };
731
732  /**
733   * Click function for modals that can be cached.
734   */
735  Drupal.CTools.Modal.clickAjaxCacheLink = function () {
736    Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this));
737    return Drupal.CTools.AJAX.clickAJAXCacheLink.apply(this);
738  };
739
740  /**
741   * Handler to prepare the modal for the response
742   */
743  Drupal.CTools.Modal.clickAjaxLink = function () {
744    Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this));
745    return false;
746  };
747
748  /**
749   * Submit responder to do an AJAX submit on all modal forms.
750   */
751  Drupal.CTools.Modal.submitAjaxForm = function(e) {
752    var $form = $(this);
753    var url = $form.attr('action');
754
755    setTimeout(function() { Drupal.CTools.AJAX.ajaxSubmit($form, url); }, 1);
756    return false;
757  };
758
759  /**
760   * Bind links that will open modals to the appropriate function.
761   */
762  Drupal.behaviors.ZZCToolsModal = {
763    attach: function(context) {
764      // Bind links
765      // Note that doing so in this order means that the two classes can be
766      // used together safely.
767      /*
768       * @todo remimplement the warm caching feature
769       $('a.ctools-use-modal-cache', context).once('ctools-use-modal', function() {
770         $(this).click(Drupal.CTools.Modal.clickAjaxCacheLink);
771         Drupal.CTools.AJAX.warmCache.apply(this);
772       });
773        */
774
775      $('area.ctools-use-modal, a.ctools-use-modal', context).once('ctools-use-modal', function() {
776        var $this = $(this);
777        $this.click(Drupal.CTools.Modal.clickAjaxLink);
778        // Create a drupal ajax object
779        var element_settings = {};
780        if ($this.attr('href')) {
781          element_settings.url = $this.attr('href');
782          element_settings.event = 'click';
783          element_settings.progress = { type: 'throbber' };
784        }
785        var base = $this.attr('href');
786        Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
787      });
788
789      // Bind buttons
790      $('input.ctools-use-modal, button.ctools-use-modal', context).once('ctools-use-modal', function() {
791        var $this = $(this);
792        $this.click(Drupal.CTools.Modal.clickAjaxLink);
793        var button = this;
794        var element_settings = {};
795
796        // AJAX submits specified in this manner automatically submit to the
797        // normal form action.
798        element_settings.url = Drupal.CTools.Modal.findURL(this);
799        if (element_settings.url == '') {
800          element_settings.url = $(this).closest('form').attr('action');
801        }
802        element_settings.event = 'click';
803        element_settings.setClick = true;
804
805        var base = $this.attr('id');
806        Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
807
808        // Make sure changes to settings are reflected in the URL.
809        $('.' + $(button).attr('id') + '-url').change(function() {
810          Drupal.ajax[base].options.url = Drupal.CTools.Modal.findURL(button);
811        });
812      });
813
814      // Bind our custom event to the form submit
815      $('#modal-content form', context).once('ctools-use-modal', function() {
816        var $this = $(this);
817        var element_settings = {};
818
819        element_settings.url = $this.attr('action');
820        element_settings.event = 'submit';
821        element_settings.progress = { 'type': 'throbber' };
822        var base = $this.attr('id');
823
824        Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
825        Drupal.ajax[base].form = $this;
826
827        $('input[type=submit], button', this).click(function(event) {
828          Drupal.ajax[base].element = this;
829          this.form.clk = this;
830          // Stop autocomplete from submitting.
831          if (Drupal.autocompleteSubmit && !Drupal.autocompleteSubmit()) {
832            return false;
833          }
834          // An empty event means we were triggered via .click() and
835          // in jquery 1.4 this won't trigger a submit.
836          // We also have to check jQuery version to prevent
837          // IE8 + jQuery 1.4.4 to break on other events
838          // bound to the submit button.
839          if (jQuery.fn.jquery.substr(0, 3) === '1.4' && typeof event.bubbles === "undefined") {
840            $(this.form).trigger('submit');
841            return false;
842          }
843        });
844      });
845
846      // Bind a click handler to allow elements with the 'ctools-close-modal'
847      // class to close the modal.
848      $('.ctools-close-modal', context).once('ctools-close-modal')
849        .click(function() {
850          Drupal.CTools.Modal.dismiss();
851          return false;
852        });
853    }
854  };
855
856  // The following are implementations of AJAX responder commands.
857
858  /**
859   * AJAX responder command to place HTML within the modal.
860   */
861  Drupal.CTools.Modal.modal_display = function(ajax, response, status) {
862    var settings = response.settings || ajax.settings || Drupal.settings;
863    // If the modal does not exist yet, create it.
864    if ($('#modalContent').length == 0) {
865      Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(ajax.element));
866    }
867    // If the modal exists run detachBehaviors before removing existing content.
868    else {
869      Drupal.detachBehaviors($('#modalContent'), settings, 'unload');
870    }
871    $('#modal-title').html(response.title);
872    // Simulate an actual page load by scrolling to the top after adding the
873    // content. This is helpful for allowing users to see error messages at the
874    // top of a form, etc.
875    $('#modal-content').html(response.output).scrollTop(0);
876    $(document).trigger('CToolsAttachBehaviors', $('#modalContent'));
877
878    // Attach behaviors within a modal dialog.
879    Drupal.attachBehaviors($('#modalContent'), settings);
880
881    if ($('#modal-content').hasClass('ctools-modal-loading')) {
882      $('#modal-content').removeClass('ctools-modal-loading');
883    }
884    else {
885      // If the modal was already shown, and we are simply replacing its
886      // content, then focus on the first focusable element in the modal.
887      // (When first showing the modal, focus will be placed on the close
888      // button by the show() function called above.)
889      $('#modal-content :focusable:first').focus();
890    }
891
892    // Force all attached animations to finish, and trigger a window resize
893    // event to center te modal after the ajax content has been added.
894    $('#modalContent').stop(true, true);
895    $(window).resize();
896  };
897
898  /**
899   * AJAX responder command to dismiss the modal.
900   */
901  Drupal.CTools.Modal.modal_dismiss = function(command) {
902    Drupal.CTools.Modal.dismiss();
903    $('link.ctools-temporary-css').remove();
904  };
905
906  /**
907   * Display loading
908   */
909  //Drupal.CTools.AJAX.commands.modal_loading = function(command) {
910  Drupal.CTools.Modal.modal_loading = function(command) {
911    Drupal.CTools.Modal.modal_display({
912      output: Drupal.theme(Drupal.CTools.Modal.currentSettings.throbberTheme),
913      title: Drupal.CTools.Modal.currentSettings.loadingText
914    });
915  };
916
917  /**
918   * Find a URL for an AJAX button.
919   *
920   * The URL for this gadget will be composed of the values of items by
921   * taking the ID of this item and adding -url and looking for that
922   * class. They need to be in the form in order since we will
923   * concat them all together using '/'.
924   */
925  Drupal.CTools.Modal.findURL = function(item) {
926    var url = '';
927    var url_class = '.' + $(item).attr('id') + '-url';
928    $(url_class).each(
929      function() {
930        var $this = $(this);
931        if (url && $this.val()) {
932          url += '/';
933        }
934        url += $this.val();
935      });
936    return url;
937  };
938
939
940  /**
941   * modalContent
942   * @param content string to display in the content box
943   * @param css obj of css attributes
944   * @param animation (fadeIn, slideDown, show)
945   * @param speed (valid animation speeds slow, medium, fast or # in ms)
946   * @param modalClass class added to div#modalContent
947   */
948  Drupal.CTools.Modal.modalContent = function(content, css, animation, speed, modalClass) {
949    // If our animation isn't set, make it just show/pop
950    if (!animation) {
951      animation = 'show';
952    }
953    else {
954      // If our animation isn't "fadeIn" or "slideDown" then it always is show
955      if (animation != 'fadeIn' && animation != 'slideDown') {
956        animation = 'show';
957      }
958    }
959
960    if (!speed && 0 !== speed) {
961      speed = 'fast';
962    }
963
964    // Build our base attributes and allow them to be overriden
965    css = jQuery.extend({
966      position: 'absolute',
967      left: '0px',
968      margin: '0px',
969      background: '#000',
970      opacity: '.55'
971    }, css);
972
973    // Add opacity handling for IE.
974    css.filter = 'alpha(opacity=' + (100 * css.opacity) + ')';
975    content.hide();
976
977    // If we already have modalContent, remove it.
978    if ($('#modalBackdrop').length) $('#modalBackdrop').remove();
979    if ($('#modalContent').length) $('#modalContent').remove();
980
981    // position code lifted from http://www.quirksmode.org/viewport/compatibility.html
982    if (self.pageYOffset) { // all except Explorer
983    var wt = self.pageYOffset;
984    } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
985      var wt = document.documentElement.scrollTop;
986    } else if (document.body) { // all other Explorers
987      var wt = document.body.scrollTop;
988    }
989
990    // Get our dimensions
991
992    // Get the docHeight and (ugly hack) add 50 pixels to make sure we dont have a *visible* border below our div
993    var docHeight = $(document).height() + 50;
994    var docWidth = $(document).width();
995    var winHeight = $(window).height();
996    var winWidth = $(window).width();
997    if( docHeight < winHeight ) docHeight = winHeight;
998
999    // Create our divs
1000    $('body').append('<div id="modalBackdrop" class="backdrop-' + modalClass + '" style="z-index: 1000; display: none;"></div><div id="modalContent" class="modal-' + modalClass + '" style="z-index: 1001; position: absolute;">' + $(content).html() + '</div>');
1001
1002    // Get a list of the tabbable elements in the modal content.
1003    var getTabbableElements = function () {
1004      var tabbableElements = $('#modalContent :tabbable'),
1005          radioButtons = tabbableElements.filter('input[type="radio"]');
1006
1007      // The list of tabbable elements from jQuery is *almost* right. The
1008      // exception is with groups of radio buttons. The list from jQuery will
1009      // include all radio buttons, when in fact, only the selected radio button
1010      // is tabbable, and if no radio buttons in a group are selected, then only
1011      // the first is tabbable.
1012      if (radioButtons.length > 0) {
1013        // First, build up an index of which groups have an item selected or not.
1014        var anySelected = {};
1015        radioButtons.each(function () {
1016          var name = this.name;
1017
1018          if (typeof anySelected[name] === 'undefined') {
1019            anySelected[name] = radioButtons.filter('input[name="' + name + '"]:checked').length !== 0;
1020          }
1021        });
1022
1023        // Next filter out the radio buttons that aren't really tabbable.
1024        var found = {};
1025        tabbableElements = tabbableElements.filter(function () {
1026          var keep = true;
1027
1028          if (this.type == 'radio') {
1029            if (anySelected[this.name]) {
1030              // Only keep the selected one.
1031              keep = this.checked;
1032            }
1033            else {
1034              // Only keep the first one.
1035              if (found[this.name]) {
1036                keep = false;
1037              }
1038              found[this.name] = true;
1039            }
1040          }
1041
1042          return keep;
1043        });
1044      }
1045
1046      return tabbableElements.get();
1047    };
1048
1049    // Keyboard and focus event handler ensures only modal elements gain focus.
1050    modalEventHandler = function( event ) {
1051      target = null;
1052      if ( event ) { //Mozilla
1053        target = event.target;
1054      } else { //IE
1055        event = window.event;
1056        target = event.srcElement;
1057      }
1058
1059      var parents = $(target).parents().get();
1060      for (var i = 0; i < parents.length; ++i) {
1061        var position = $(parents[i]).css('position');
1062        if (position == 'absolute' || position == 'fixed') {
1063          return true;
1064        }
1065      }
1066
1067      if ($(target).is('#modalContent, body') || $(target).filter('*:visible').parents('#modalContent').length) {
1068        // Allow the event only if target is a visible child node
1069        // of #modalContent.
1070        return true;
1071      }
1072      else {
1073        getTabbableElements()[0].focus();
1074      }
1075
1076      event.preventDefault();
1077    };
1078    $('body').bind( 'focus', modalEventHandler );
1079    $('body').bind( 'keypress', modalEventHandler );
1080
1081    // Keypress handler Ensures you can only TAB to elements within the modal.
1082    // Based on the psuedo-code from WAI-ARIA 1.0 Authoring Practices section
1083    // 3.3.1 "Trapping Focus".
1084    modalTabTrapHandler = function (evt) {
1085      // We only care about the TAB key.
1086      if (evt.which != 9) {
1087        return true;
1088      }
1089
1090      var tabbableElements = getTabbableElements(),
1091          firstTabbableElement = tabbableElements[0],
1092          lastTabbableElement = tabbableElements[tabbableElements.length - 1],
1093          singleTabbableElement = firstTabbableElement == lastTabbableElement,
1094          node = evt.target;
1095
1096      // If this is the first element and the user wants to go backwards, then
1097      // jump to the last element.
1098      if (node == firstTabbableElement && evt.shiftKey) {
1099        if (!singleTabbableElement) {
1100          lastTabbableElement.focus();
1101        }
1102        return false;
1103      }
1104      // If this is the last element and the user wants to go forwards, then
1105      // jump to the first element.
1106      else if (node == lastTabbableElement && !evt.shiftKey) {
1107        if (!singleTabbableElement) {
1108          firstTabbableElement.focus();
1109        }
1110        return false;
1111      }
1112      // If this element isn't in the dialog at all, then jump to the first
1113      // or last element to get the user into the game.
1114      else if ($.inArray(node, tabbableElements) == -1) {
1115        // Make sure the node isn't in another modal (ie. WYSIWYG modal).
1116        var parents = $(node).parents().get();
1117        for (var i = 0; i < parents.length; ++i) {
1118          var position = $(parents[i]).css('position');
1119          if (position == 'absolute' || position == 'fixed') {
1120            return true;
1121          }
1122        }
1123
1124        if (evt.shiftKey) {
1125          lastTabbableElement.focus();
1126        }
1127        else {
1128          firstTabbableElement.focus();
1129        }
1130      }
1131    };
1132    $('body').bind('keydown', modalTabTrapHandler);
1133
1134    // Create our content div, get the dimensions, and hide it
1135    var modalContent = $('#modalContent').css('top','-1000px');
1136    var $modalHeader = modalContent.find('.modal-header');
1137    var mdcTop = wt + Math.max((winHeight / 2) - (modalContent.outerHeight() / 2), 0);
1138    var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
1139    $('#modalBackdrop').css(css).css('top', 0).css('height', docHeight + 'px').css('width', docWidth + 'px').show();
1140    modalContent.css({top: mdcTop + 'px', left: mdcLeft + 'px'}).hide()[animation](speed);
1141
1142    // Bind a click for closing the modalContent
1143    modalContentClose = function(){close(); return false;};
1144    $('.close', $modalHeader).bind('click', modalContentClose);
1145
1146    // Bind a keypress on escape for closing the modalContent
1147    modalEventEscapeCloseHandler = function(event) {
1148      if (event.keyCode == 27) {
1149        close();
1150        return false;
1151      }
1152    };
1153
1154    $(document).bind('keydown', modalEventEscapeCloseHandler);
1155
1156    // Per WAI-ARIA 1.0 Authoring Practices, initial focus should be on the
1157    // close button, but we should save the original focus to restore it after
1158    // the dialog is closed.
1159    var oldFocus = document.activeElement;
1160    $('.close', $modalHeader).focus();
1161
1162    // Close the open modal content and backdrop
1163    function close() {
1164      // Unbind the events
1165      $(window).unbind('resize',  modalContentResize);
1166      $('body').unbind( 'focus', modalEventHandler);
1167      $('body').unbind( 'keypress', modalEventHandler );
1168      $('body').unbind( 'keydown', modalTabTrapHandler );
1169      $('.close', $modalHeader).unbind('click', modalContentClose);
1170      $(document).unbind('keydown', modalEventEscapeCloseHandler);
1171      $(document).trigger('CToolsCloseModalBehaviors', $('#modalContent'));
1172      $(document).trigger('CToolsDetachBehaviors', $('#modalContent'));
1173
1174      // Closing animation.
1175      switch (animation) {
1176        case 'fadeIn':
1177          modalContent.fadeOut(speed, modalContentRemove);
1178          break;
1179
1180        case 'slideDown':
1181          modalContent.slideUp(speed, modalContentRemove);
1182          break;
1183
1184        case 'show':
1185          modalContent.hide(speed, modalContentRemove);
1186          break;
1187      }
1188    }
1189
1190    // Remove the content.
1191    modalContentRemove = function () {
1192      $('#modalContent').remove();
1193      $('#modalBackdrop').remove();
1194
1195      // Restore focus to where it was before opening the dialog.
1196      $(oldFocus).focus();
1197    };
1198
1199    // Move and resize the modalBackdrop and modalContent on window resize.
1200    modalContentResize = function () {
1201      // Reset the backdrop height/width to get accurate document size.
1202      $('#modalBackdrop').css('height', '').css('width', '');
1203
1204      // Position code lifted from:
1205      // http://www.quirksmode.org/viewport/compatibility.html
1206      if (self.pageYOffset) { // all except Explorer
1207        var wt = self.pageYOffset;
1208      } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
1209        var wt = document.documentElement.scrollTop;
1210      } else if (document.body) { // all other Explorers
1211        var wt = document.body.scrollTop;
1212      }
1213
1214      // Get our heights
1215      var docHeight = $(document).height();
1216      var docWidth = $(document).width();
1217      var winHeight = $(window).height();
1218      var winWidth = $(window).width();
1219      if( docHeight < winHeight ) docHeight = winHeight;
1220
1221      // Get where we should move content to
1222      var modalContent = $('#modalContent');
1223      var mdcTop = wt + Math.max((winHeight / 2) - (modalContent.outerHeight() / 2), 0);
1224      var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
1225
1226      // Apply the changes
1227      $('#modalBackdrop').css('height', docHeight + 'px').css('width', docWidth + 'px').show();
1228      modalContent.css('top', mdcTop + 'px').css('left', mdcLeft + 'px').show();
1229    };
1230    $(window).bind('resize', modalContentResize);
1231  };
1232
1233  /**
1234   * unmodalContent
1235   * @param content (The jQuery object to remove)
1236   * @param animation (fadeOut, slideUp, show)
1237   * @param speed (valid animation speeds slow, medium, fast or # in ms)
1238   */
1239  Drupal.CTools.Modal.unmodalContent = function(content, animation, speed)
1240  {
1241    // If our animation isn't set, make it just show/pop
1242    if (!animation) { var animation = 'show'; } else {
1243      // If our animation isn't "fade" then it always is show
1244      if (( animation != 'fadeOut' ) && ( animation != 'slideUp')) animation = 'show';
1245    }
1246    // Set a speed if we dont have one
1247    if ( !speed ) var speed = 'fast';
1248
1249    // Unbind the events we bound
1250    $(window).unbind('resize', modalContentResize);
1251    $('body').unbind('focus', modalEventHandler);
1252    $('body').unbind('keypress', modalEventHandler);
1253    $('body').unbind( 'keydown', modalTabTrapHandler );
1254    var $modalContent = $('#modalContent');
1255    var $modalHeader = $modalContent.find('.modal-header');
1256    $('.close', $modalHeader).unbind('click', modalContentClose);
1257    $(document).unbind('keydown', modalEventEscapeCloseHandler);
1258    $(document).trigger('CToolsDetachBehaviors', $modalContent);
1259
1260    // jQuery magic loop through the instances and run the animations or removal.
1261    content.each(function(){
1262      if ( animation == 'fade' ) {
1263        $('#modalContent').fadeOut(speed, function() {
1264          $('#modalBackdrop').fadeOut(speed, function() {
1265            $(this).remove();
1266          });
1267          $(this).remove();
1268        });
1269      } else {
1270        if ( animation == 'slide' ) {
1271          $('#modalContent').slideUp(speed,function() {
1272            $('#modalBackdrop').slideUp(speed, function() {
1273              $(this).remove();
1274            });
1275            $(this).remove();
1276          });
1277        } else {
1278          $('#modalContent').remove();
1279          $('#modalBackdrop').remove();
1280        }
1281      }
1282    });
1283  };
1284
1285$(function() {
1286  Drupal.ajax.prototype.commands.modal_display = Drupal.CTools.Modal.modal_display;
1287  Drupal.ajax.prototype.commands.modal_dismiss = Drupal.CTools.Modal.modal_dismiss;
1288});
1289
1290})(jQuery);
1291;

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.