PageSourceSearch

https://treeoven.com/assets/jquery_ujs-e87806d0cf4489aeb1bb7288016024e8de67fd18db693fe026fe3907581e53cd.js

js treeoven.com collected 2026-10-07 11:51:34 UTC 21,648 bytes, 555 lines download raw bytes

1(function($, undefined) {
2
3/**
4 * Unobtrusive scripting adapter for jQuery
5 * https://github.com/rails/jquery-ujs
6 *
7 * Requires jQuery 1.8.0 or later.
8 *
9 * Released under the MIT license
10 *
11 */
12
13  // Cut down on the number of issues from people inadvertently including jquery_ujs twice
14  // by detecting and raising an error when it happens.
15  'use strict';
16
17  if ( $.rails !== undefined ) {
18    $.error('jquery-ujs has already been loaded!');
19  }
20
21  // Shorthand to make it a little easier to call public rails functions from within rails.js
22  var rails;
23  var $document = $(document);
24
25  $.rails = rails = {
26    // Link elements bound by jquery-ujs
27    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
28
29    // Button elements bound by jquery-ujs
30    buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)',
31
32    // Select elements bound by jquery-ujs
33    inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
34
35    // Form elements bound by jquery-ujs
36    formSubmitSelector: 'form',
37
38    // Form input elements bound by jquery-ujs
39    formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
40
41    // Form input elements disabled during form submission
42    disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
43
44    // Form input elements re-enabled after form submission
45    enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
46
47    // Form required input elements
48    requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])',
49
50    // Form file input elements
51    fileInputSelector: 'input[type=file]:not([disabled])',
52
53    // Link onClick disable selector with possible reenable after remote submission
54    linkDisableSelector: 'a[data-disable-with], a[data-disable]',
55
56    // Button onClick disable selector with possible reenable after remote submission
57    buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',
58
59    // Up-to-date Cross-Site Request Forgery token
60    csrfToken: function() {
61     return $('meta[name=csrf-token]').attr('content');
62    },
63
64    // URL param that must contain the CSRF token
65    csrfParam: function() {
66     return $('meta[name=csrf-param]').attr('content');
67    },
68
69    // Make sure that every Ajax request sends the CSRF token
70    CSRFProtection: function(xhr) {
71      var token = rails.csrfToken();
72      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
73    },
74
75    // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones)
76    refreshCSRFTokens: function(){
77      $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken());
78    },
79
80    // Triggers an event on an element and returns false if the event result is false
81    fire: function(obj, name, data) {
82      var event = $.Event(name);
83      obj.trigger(event, data);
84      return event.result !== false;
85    },
86
87    // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
88    confirm: function(message) {
89      return confirm(message);
90    },
91
92    // Default ajax function, may be overridden with custom function in $.rails.ajax
93    ajax: function(options) {
94      return $.ajax(options);
95    },
96
97    // Default way to get an element's href. May be overridden at $.rails.href.
98    href: function(element) {
99      return element[0].href;
100    },
101
102    // Checks "data-remote" if true to handle the request through a XHR request.
103    isRemote: function(element) {
104      return element.data('remote') !== undefined && element.data('remote') !== false;
105    },
106
107    // Submits "remote" forms and links with ajax
108    handleRemote: function(element) {
109      var method, url, data, withCredentials, dataType, options;
110
111      if (rails.fire(element, 'ajax:before')) {
112        withCredentials = element.data('with-credentials') || null;
113        dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
114
115        if (element.is('form')) {
116          method = element.data('ujs:submit-button-formmethod') || element.attr('method');
117          url = element.data('ujs:submit-button-formaction') || element.attr('action');
118          data = $(element[0]).serializeArray();
119          // memoized value from clicked submit button
120          var button = element.data('ujs:submit-button');
121          if (button) {
122            data.push(button);
123            element.data('ujs:submit-button', null);
124          }
125          element.data('ujs:submit-button-formmethod', null);
126          element.data('ujs:submit-button-formaction', null);
127        } else if (element.is(rails.inputChangeSelector)) {
128          method = element.data('method');
129          url = element.data('url');
130          data = element.serialize();
131          if (element.data('params')) data = data + '&' + element.data('params');
132        } else if (element.is(rails.buttonClickSelector)) {
133          method = element.data('method') || 'get';
134          url = element.data('url');
135          data = element.serialize();
136          if (element.data('params')) data = data + '&' + element.data('params');
137        } else {
138          method = element.data('method');
139          url = rails.href(element);
140          data = element.data('params') || null;
141        }
142
143        options = {
144          type: method || 'GET', data: data, dataType: dataType,
145          // stopping the "ajax:beforeSend" event will cancel the ajax request
146          beforeSend: function(xhr, settings) {
147            if (settings.dataType === undefined) {
148              xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
149            }
150            if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
151              element.trigger('ajax:send', xhr);
152            } else {
153              return false;
154            }
155          },
156          success: function(data, status, xhr) {
157            element.trigger('ajax:success', [data, status, xhr]);
158          },
159          complete: function(xhr, status) {
160            element.trigger('ajax:complete', [xhr, status]);
161          },
162          error: function(xhr, status, error) {
163            element.trigger('ajax:error', [xhr, status, error]);
164          },
165          crossDomain: rails.isCrossDomain(url)
166        };
167
168        // There is no withCredentials for IE6-8 when
169        // "Enable native XMLHTTP support" is disabled
170        if (withCredentials) {
171          options.xhrFields = {
172            withCredentials: withCredentials
173          };
174        }
175
176        // Only pass url to `ajax` options if not blank
177        if (url) { options.url = url; }
178
179        return rails.ajax(options);
180      } else {
181        return false;
182      }
183    },
184
185    // Determines if the request is a cross domain request.
186    isCrossDomain: function(url) {
187      var originAnchor = document.createElement('a');
188      originAnchor.href = location.href;
189      var urlAnchor = document.createElement('a');
190
191      try {
192        urlAnchor.href = url;
193        // This is a workaround to a IE bug.
194        urlAnchor.href = urlAnchor.href;
195
196        // If URL protocol is false or is a string containing a single colon
197        // *and* host are false, assume it is not a cross-domain request
198        // (should only be the case for IE7 and IE compatibility mode).
199        // Otherwise, evaluate protocol and host of the URL against the origin
200        // protocol and host.
201        return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) ||
202          (originAnchor.protocol + '//' + originAnchor.host ===
203            urlAnchor.protocol + '//' + urlAnchor.host));
204      } catch (e) {
205        // If there is an error parsing the URL, assume it is crossDomain.
206        return true;
207      }
208    },
209
210    // Handles "data-method" on links such as:
211    // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
212    handleMethod: function(link) {
213      var href = rails.href(link),
214        method = link.data('method'),
215        target = link.attr('target'),
216        csrfToken = rails.csrfToken(),
217        csrfParam = rails.csrfParam(),
218        form = $('<form method="post" action="' + href + '"></form>'),
219        metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
220
221      if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {
222        metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
223      }
224
225      if (target) { form.attr('target', target); }
226
227      form.hide().append(metadataInput).appendTo('body');
228      form.submit();
229    },
230
231    // Helper function that returns form elements that match the specified CSS selector
232    // If form is actually a "form" element this will return associated elements outside the from that have
233    // the html form attribute set
234    formElements: function(form, selector) {
235      return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector);
236    },
237
238    /* Disables form elements:
239      - Caches element value in 'ujs:enable-with' data store
240      - Replaces element text with value of 'data-disable-with' attribute
241      - Sets disabled property to true
242    */
243    disableFormElements: function(form) {
244      rails.formElements(form, rails.disableSelector).each(function() {
245        rails.disableFormElement($(this));
246      });
247    },
248
249    disableFormElement: function(element) {
250      var method, replacement;
251
252      method = element.is('button') ? 'html' : 'val';
253      replacement = element.data('disable-with');
254
255      if (replacement !== undefined) {
256        element.data('ujs:enable-with', element[method]());
257        element[method](replacement);
258      }
259
260      element.prop('disabled', true);
261      element.data('ujs:disabled', true);
262    },
263
264    /* Re-enables disabled form elements:
265      - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
266      - Sets disabled property to false
267    */
268    enableFormElements: function(form) {
269      rails.formElements(form, rails.enableSelector).each(function() {
270        rails.enableFormElement($(this));
271      });
272    },
273
274    enableFormElement: function(element) {
275      var method = element.is('button') ? 'html' : 'val';
276      if (element.data('ujs:enable-with') !== undefined) {
277        element[method](element.data('ujs:enable-with'));
278        element.removeData('ujs:enable-with'); // clean up cache
279      }
280      element.prop('disabled', false);
281      element.removeData('ujs:disabled');
282    },
283
284   /* For 'data-confirm' attribute:
285      - Fires `confirm` event
286      - Shows the confirmation dialog
287      - Fires the `confirm:complete` event
288
289      Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
290      Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
291      Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
292      return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
293   */
294    allowAction: function(element) {
295      var message = element.data('confirm'),
296          answer = false, callback;
297      if (!message) { return true; }
298
299      if (rails.fire(element, 'confirm')) {
300        try {
301          answer = rails.confirm(message);
302        } catch (e) {
303          (console.error || console.log).call(console, e.stack || e);
304        }
305        callback = rails.fire(element, 'confirm:complete', [answer]);
306      }
307      return answer && callback;
308    },
309
310    // Helper function which checks for blank inputs in a form that match the specified CSS selector
311    blankInputs: function(form, specifiedSelector, nonBlank) {
312      var foundInputs = $(),
313        input,
314        valueToCheck,
315        radiosForNameWithNoneSelected,
316        radioName,
317        selector = specifiedSelector || 'input,textarea',
318        requiredInputs = form.find(selector),
319        checkedRadioButtonNames = {};
320
321      requiredInputs.each(function() {
322        input = $(this);
323        if (input.is('input[type=radio]')) {
324
325          // Don't count unchecked required radio as blank if other radio with same name is checked,
326          // regardless of whether same-name radio input has required attribute or not. The spec
327          // states https://www.w3.org/TR/html5/forms.html#the-required-attribute
328          radioName = input.attr('name');
329
330          // Skip if we've already seen the radio with this name.
331          if (!checkedRadioButtonNames[radioName]) {
332
333            // If none checked
334            if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) {
335              radiosForNameWithNoneSelected = form.find(
336                'input[type=radio][name="' + radioName + '"]');
337              foundInputs = foundInputs.add(radiosForNameWithNoneSelected);
338            }
339
340            // We only need to check each name once.
341            checkedRadioButtonNames[radioName] = radioName;
342          }
343        } else {
344          valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val();
345          if (valueToCheck === nonBlank) {
346            foundInputs = foundInputs.add(input);
347          }
348        }
349      });
350      return foundInputs.length ? foundInputs : false;
351    },
352
353    // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
354    nonBlankInputs: function(form, specifiedSelector) {
355      return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
356    },
357
358    // Helper function, needed to provide consistent behavior in IE
359    stopEverything: function(e) {
360      $(e.target).trigger('ujs:everythingStopped');
361      e.stopImmediatePropagation();
362      return false;
363    },
364
365    //  Replace element's html with the 'data-disable-with' after storing original html
366    //  and prevent clicking on it
367    disableElement: function(element) {
368      var replacement = element.data('disable-with');
369
370      if (replacement !== undefined) {
371        element.data('ujs:enable-with', element.html()); // store enabled state
372        element.html(replacement);
373      }
374
375      element.bind('click.railsDisable', function(e) { // prevent further clicking
376        return rails.stopEverything(e);
377      });
378      element.data('ujs:disabled', true);
379    },
380
381    // Restore element to its original state which was disabled by 'disableElement' above
382    enableElement: function(element) {
383      if (element.data('ujs:enable-with') !== undefined) {
384        element.html(element.data('ujs:enable-with')); // set to old enabled state
385        element.removeData('ujs:enable-with'); // clean up cache
386      }
387      element.unbind('click.railsDisable'); // enable element
388      element.removeData('ujs:disabled');
389    }
390  };
391
392  if (rails.fire($document, 'rails:attachBindings')) {
393
394    $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
395
396    // This event works the same as the load event, except that it fires every
397    // time the page is loaded.
398    //
399    // See https://github.com/rails/jquery-ujs/issues/357
400    // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
401    $(window).on('pageshow.rails', function () {
402      $($.rails.enableSelector).each(function () {
403        var element = $(this);
404
405        if (element.data('ujs:disabled')) {
406          $.rails.enableFormElement(element);
407        }
408      });
409
410      $($.rails.linkDisableSelector).each(function () {
411        var element = $(this);
412
413        if (element.data('ujs:disabled')) {
414          $.rails.enableElement(element);
415        }
416      });
417    });
418
419    $document.delegate(rails.linkDisableSelector, 'ajax:complete', function() {
420        rails.enableElement($(this));
421    });
422
423    $document.delegate(rails.buttonDisableSelector, 'ajax:complete', function() {
424        rails.enableFormElement($(this));
425    });
426
427    $document.delegate(rails.linkClickSelector, 'click.rails', function(e) {
428      var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
429      if (!rails.allowAction(link)) return rails.stopEverything(e);
430
431      if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);
432
433      if (rails.isRemote(link)) {
434        if (metaClick && (!method || method === 'GET') && !data) { return true; }
435
436        var handleRemote = rails.handleRemote(link);
437        // Response from rails.handleRemote() will either be false or a deferred object promise.
438        if (handleRemote === false) {
439          rails.enableElement(link);
440        } else {
441          handleRemote.fail( function() { rails.enableElement(link); } );
442        }
443        return false;
444
445      } else if (method) {
446        rails.handleMethod(link);
447        return false;
448      }
449    });
450
451    $document.delegate(rails.buttonClickSelector, 'click.rails', function(e) {
452      var button = $(this);
453
454      if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e);
455
456      if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button);
457
458      var handleRemote = rails.handleRemote(button);
459      // Response from rails.handleRemote() will either be false or a deferred object promise.
460      if (handleRemote === false) {
461        rails.enableFormElement(button);
462      } else {
463        handleRemote.fail( function() { rails.enableFormElement(button); } );
464      }
465      return false;
466    });
467
468    $document.delegate(rails.inputChangeSelector, 'change.rails', function(e) {
469      var link = $(this);
470      if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e);
471
472      rails.handleRemote(link);
473      return false;
474    });
475
476    $document.delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
477      var form = $(this),
478        remote = rails.isRemote(form),
479        blankRequiredInputs,
480        nonBlankFileInputs;
481
482      if (!rails.allowAction(form)) return rails.stopEverything(e);
483
484      // Skip other logic when required values are missing or file upload is present
485      if (form.attr('novalidate') === undefined) {
486        if (form.data('ujs:formnovalidate-button') === undefined) {
487          blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false);
488          if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
489            return rails.stopEverything(e);
490          }
491        } else {
492          // Clear the formnovalidate in case the next button click is not on a formnovalidate button
493          // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain
494          form.data('ujs:formnovalidate-button', undefined);
495        }
496      }
497
498      if (remote) {
499        nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
500        if (nonBlankFileInputs) {
501          // Slight timeout so that the submit button gets properly serialized
502          // (make it easy for event handler to serialize form without disabled values)
503          setTimeout(function(){ rails.disableFormElements(form); }, 13);
504          var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
505
506          // Re-enable form elements if event bindings return false (canceling normal form submission)
507          if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
508
509          return aborted;
510        }
511
512        rails.handleRemote(form);
513        return false;
514
515      } else {
516        // Slight timeout so that the submit button gets properly serialized
517        setTimeout(function(){ rails.disableFormElements(form); }, 13);
518      }
519    });
520
521    $document.delegate(rails.formInputClickSelector, 'click.rails', function(event) {
522      var button = $(this);
523
524      if (!rails.allowAction(button)) return rails.stopEverything(event);
525
526      // Register the pressed submit button
527      var name = button.attr('name'),
528        data = name ? {name:name, value:button.val()} : null;
529
530      var form = button.closest('form');
531      if (form.length === 0) {
532        form = $('#' + button.attr('form'));
533      }
534      form.data('ujs:submit-button', data);
535
536      // Save attributes from button
537      form.data('ujs:formnovalidate-button', button.attr('formnovalidate'));
538      form.data('ujs:submit-button-formaction', button.attr('formaction'));
539      form.data('ujs:submit-button-formmethod', button.attr('formmethod'));
540    });
541
542    $document.delegate(rails.formSubmitSelector, 'ajax:send.rails', function(event) {
543      if (this === event.target) rails.disableFormElements($(this));
544    });
545
546    $document.delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) {
547      if (this === event.target) rails.enableFormElements($(this));
548    });
549
550    $(function(){
551      rails.refreshCSRFTokens();
552    });
553  }
554
555})( jQuery );

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.