/* Unobtrusive JavaScript https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts Released under the MIT license */ (function() { var context = this; (function() { (function() { this.Rails = { linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]', buttonClickSelector: { selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])', exclude: 'form button' }, inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]', formSubmitSelector: 'form', 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])', formDisableSelector: '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', formEnableSelector: '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', fileInputSelector: 'input[name][type=file]:not([disabled])', linkDisableSelector: 'a[data-disable-with], a[data-disable]', buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]' }; }).call(this); }).call(context); var Rails = context.Rails; (function() { (function() { var expando, m; m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector; Rails.matches = function(element, selector) { if (selector.exclude != null) { return m.call(element, selector.selector) && !m.call(element, selector.exclude); } else { return m.call(element, selector); } }; expando = '_ujsData'; Rails.getData = function(element, key) { var ref; return (ref = element[expando]) != null ? ref[key] : void 0; }; Rails.setData = function(element, key, value) { if (element[expando] == null) { element[expando] = {}; } return element[expando][key] = value; }; Rails.$ = function(selector) { return Array.prototype.slice.call(document.querySelectorAll(selector)); }; }).call(this); (function() { var $, csrfParam, csrfToken; $ = Rails.$; csrfToken = Rails.csrfToken = function() { var meta; meta = document.querySelector('meta[name=csrf-token]'); return meta && meta.content; }; csrfParam = Rails.csrfParam = function() { var meta; meta = document.querySelector('meta[name=csrf-param]'); return meta && meta.content; }; Rails.CSRFProtection = function(xhr) { var token; token = csrfToken(); if (token != null) { return xhr.setRequestHeader('X-CSRF-Token', token); } }; Rails.refreshCSRFTokens = function() { var param, token; token = csrfToken(); param = csrfParam(); if ((token != null) && (param != null)) { return $('form input[name="' + param + '"]').forEach(function(input) { return input.value = token; }); } }; }).call(this); (function() { var CustomEvent, fire, matches; matches = Rails.matches; CustomEvent = window.CustomEvent; if (typeof CustomEvent !== 'function') { CustomEvent = function(event, params) { var evt; evt = document.createEvent('CustomEvent'); evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); return evt; }; CustomEvent.prototype = window.Event.prototype; } fire = Rails.fire = function(obj, name, data) { var event; event = new CustomEvent(name, { bubbles: true, cancelable: true, detail: data }); obj.dispatchEvent(event); return !event.defaultPrevented; }; Rails.stopEverything = function(e) { fire(e.target, 'ujs:everythingStopped'); e.preventDefault(); e.stopPropagation(); return e.stopImmediatePropagation(); }; Rails.delegate = function(element, selector, eventType, handler) { return element.addEventListener(eventType, function(e) { var target; target = e.target; while (!(!(target instanceof Element) || matches(target, selector))) { target = target.parentNode; } if (target instanceof Element && handler.call(target, e) === false) { e.preventDefault(); return e.stopPropagation(); } }); }; }).call(this); (function() { var AcceptHeaders, CSRFProtection, createXHR, fire, prepareOptions, processResponse; CSRFProtection = Rails.CSRFProtection, fire = Rails.fire; AcceptHeaders = { '*': '*/*', text: 'text/plain', html: 'text/html', xml: 'application/xml, text/xml', json: 'application/json, text/javascript', script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript' }; Rails.ajax = function(options) { var xhr; options = prepareOptions(options); xhr = createXHR(options, function() { var response; response = processResponse(xhr.response, xhr.getResponseHeader('Content-Type')); if (Math.floor(xhr.status / 100) === 2) { if (typeof options.success === "function") { options.success(response, xhr.statusText, xhr); } } else { if (typeof options.error === "function") { options.error(response, xhr.statusText, xhr); } } return typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : void 0; }); if (!(typeof options.beforeSend === "function" ? options.beforeSend(xhr, options) : void 0)) { return false; } if (xhr.readyState === XMLHttpRequest.OPENED) { return xhr.send(options.data); } }; prepareOptions = function(options) { options.url = options.url || location.href; options.type = options.type.toUpperCase(); if (options.type === 'GET' && options.data) { if (options.url.indexOf('?') < 0) { options.url += '?' + options.data; } else { options.url += '&' + options.data; } } if (AcceptHeaders[options.dataType] == null) { options.dataType = '*'; } options.accept = AcceptHeaders[options.dataType]; if (options.dataType !== '*') { options.accept += ', */*; q=0.01'; } return options; }; createXHR = function(options, done) { var xhr; xhr = new XMLHttpRequest(); xhr.open(options.type, options.url, true); xhr.setRequestHeader('Accept', options.accept); if (typeof options.data === 'string') { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); } if (!options.crossDomain) { xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); } CSRFProtection(xhr); xhr.withCredentials = !!options.withCredentials; xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.DONE) { return done(xhr); } }; return xhr; }; processResponse = function(response, type) { var parser, script; if (typeof response === 'string' && typeof type === 'string') { if (type.match(/\bjson\b/)) { try { response = JSON.parse(response); } catch (error) {} } else if (type.match(/\b(?:java|ecma)script\b/)) { script = document.createElement('script'); script.text = response; document.head.appendChild(script).parentNode.removeChild(script); } else if (type.match(/\b(xml|html|svg)\b/)) { parser = new DOMParser(); type = type.replace(/;.+/, ''); try { response = parser.parseFromString(response, type); } catch (error) {} } } return response; }; Rails.href = function(element) { return element.href; }; Rails.isCrossDomain = function(url) { var e, originAnchor, urlAnchor; originAnchor = document.createElement('a'); originAnchor.href = location.href; urlAnchor = document.createElement('a'); try { urlAnchor.href = url; return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) || (originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host)); } catch (error) { e = error; return true; } }; }).call(this); (function() { var matches, toArray; matches = Rails.matches; toArray = function(e) { return Array.prototype.slice.call(e); }; Rails.serializeElement = function(element, additionalParam) { var inputs, params; inputs = [element]; if (matches(element, 'form')) { inputs = toArray(element.elements); } params = []; inputs.forEach(function(input) { if (!input.name || input.disabled) { return; } if (matches(input, 'select')) { return toArray(input.options).forEach(function(option) { if (option.selected) { return params.push({ name: input.name, value: option.value }); } }); } else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) { return params.push({ name: input.name, value: input.value }); } }); if (additionalParam) { params.push(additionalParam); } return params.map(function(param) { if (param.name != null) { return (encodeURIComponent(param.name)) + "=" + (encodeURIComponent(param.value)); } else { return param; } }).join('&'); }; Rails.formElements = function(form, selector) { if (matches(form, 'form')) { return toArray(form.elements).filter(function(el) { return matches(el, selector); }); } else { return toArray(form.querySelectorAll(selector)); } }; }).call(this); (function() { var allowAction, fire, stopEverything; fire = Rails.fire, stopEverything = Rails.stopEverything; Rails.handleConfirm = function(e) { if (!allowAction(this)) { return stopEverything(e); } }; allowAction = function(element) { var answer, callback, message; message = element.getAttribute('data-confirm'); if (!message) { return true; } answer = false; if (fire(element, 'confirm')) { try { answer = confirm(message); } catch (error) {} callback = fire(element, 'confirm:complete', [answer]); } return answer && callback; }; }).call(this); (function() { var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, matches, setData, stopEverything; matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements; Rails.handleDisabledElement = function(e) { var element; element = this; if (element.disabled) { return stopEverything(e); } }; Rails.enableElement = function(e) { var element; element = e instanceof Event ? e.target : e; if (matches(element, Rails.linkDisableSelector)) { return enableLinkElement(element); } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) { return enableFormElement(element); } else if (matches(element, Rails.formSubmitSelector)) { return enableFormElements(element); } }; Rails.disableElement = function(e) { var element; element = e instanceof Event ? e.target : e; if (matches(element, Rails.linkDisableSelector)) { return disableLinkElement(element); } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) { return disableFormElement(element); } else if (matches(element, Rails.formSubmitSelector)) { return disableFormElements(element); } }; disableLinkElement = function(element) { var replacement; replacement = element.getAttribute('data-disable-with'); if (replacement != null) { setData(element, 'ujs:enable-with', element.innerHTML); element.innerHTML = replacement; } element.addEventListener('click', stopEverything); return setData(element, 'ujs:disabled', true); }; enableLinkElement = function(element) { var originalText; originalText = getData(element, 'ujs:enable-with'); if (originalText != null) { element.innerHTML = originalText; setData(element, 'ujs:enable-with', null); } element.removeEventListener('click', stopEverything); return setData(element, 'ujs:disabled', null); }; disableFormElements = function(form) { return formElements(form, Rails.formDisableSelector).forEach(disableFormElement); }; disableFormElement = function(element) { var replacement; replacement = element.getAttribute('data-disable-with'); if (replacement != null) { if (matches(element, 'button')) { setData(element, 'ujs:enable-with', element.innerHTML); element.innerHTML = replacement; } else { setData(element, 'ujs:enable-with', element.value); element.value = replacement; } } element.disabled = true; return setData(element, 'ujs:disabled', true); }; enableFormElements = function(form) { return formElements(form, Rails.formEnableSelector).forEach(enableFormElement); }; enableFormElement = function(element) { var originalText; originalText = getData(element, 'ujs:enable-with'); if (originalText != null) { if (matches(element, 'button')) { element.innerHTML = originalText; } else { element.value = originalText; } setData(element, 'ujs:enable-with', null); } element.disabled = false; return setData(element, 'ujs:disabled', null); }; }).call(this); (function() { var stopEverything; stopEverything = Rails.stopEverything; Rails.handleMethod = function(e) { var csrfParam, csrfToken, form, formContent, href, link, method; link = this; method = link.getAttribute('data-method'); if (!method) { return; } href = Rails.href(link); csrfToken = Rails.csrfToken(); csrfParam = Rails.csrfParam(); form = document.createElement('form'); formContent = ""; if ((csrfParam != null) && (csrfToken != null) && !Rails.isCrossDomain(href)) { formContent += ""; } formContent += ''; form.method = 'post'; form.action = href; form.target = link.target; form.innerHTML = formContent; form.style.display = 'none'; document.body.appendChild(form); form.querySelector('[type="submit"]').click(); return stopEverything(e); }; }).call(this); (function() { var ajax, fire, getData, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything, slice = [].slice; matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement; isRemote = function(element) { var value; value = element.getAttribute('data-remote'); return (value != null) && value !== 'false'; }; Rails.handleRemote = function(e) { var button, data, dataType, element, method, url, withCredentials; element = this; if (!isRemote(element)) { return true; } if (!fire(element, 'ajax:before')) { fire(element, 'ajax:stopped'); return false; } withCredentials = element.getAttribute('data-with-credentials'); dataType = element.getAttribute('data-type') || 'script'; if (matches(element, Rails.formSubmitSelector)) { button = getData(element, 'ujs:submit-button'); method = getData(element, 'ujs:submit-button-formmethod') || element.method; url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href; if (method.toUpperCase() === 'GET') { url = url.replace(/\?.*$/, ''); } if (element.enctype === 'multipart/form-data') { data = new FormData(element); if (button != null) { data.append(button.name, button.value); } } else { data = serializeElement(element, button); } setData(element, 'ujs:submit-button', null); setData(element, 'ujs:submit-button-formmethod', null); setData(element, 'ujs:submit-button-formaction', null); } else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) { method = element.getAttribute('data-method'); url = element.getAttribute('data-url'); data = serializeElement(element, element.getAttribute('data-params')); } else { method = element.getAttribute('data-method'); url = Rails.href(element); data = element.getAttribute('data-params'); } ajax({ type: method || 'GET', url: url, data: data, dataType: dataType, beforeSend: function(xhr, options) { if (fire(element, 'ajax:beforeSend', [xhr, options])) { return fire(element, 'ajax:send', [xhr]); } else { fire(element, 'ajax:stopped'); return false; } }, success: function() { var args; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; return fire(element, 'ajax:success', args); }, error: function() { var args; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; return fire(element, 'ajax:error', args); }, complete: function() { var args; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; return fire(element, 'ajax:complete', args); }, crossDomain: isCrossDomain(url), withCredentials: (withCredentials != null) && withCredentials !== 'false' }); return stopEverything(e); }; Rails.formSubmitButtonClick = function(e) { var button, form; button = this; form = button.form; if (!form) { return; } if (button.name) { setData(form, 'ujs:submit-button', { name: button.name, value: button.value }); } setData(form, 'ujs:formnovalidate-button', button.formNoValidate); setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction')); return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod')); }; Rails.handleMetaClick = function(e) { var data, link, metaClick, method; link = this; method = (link.getAttribute('data-method') || 'GET').toUpperCase(); data = link.getAttribute('data-params'); metaClick = e.metaKey || e.ctrlKey; if (metaClick && method === 'GET' && !data) { return e.stopImmediatePropagation(); } }; }).call(this); (function() { var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMetaClick, handleMethod, handleRemote, refreshCSRFTokens; fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMetaClick = Rails.handleMetaClick, handleMethod = Rails.handleMethod; if ((typeof jQuery !== "undefined" && jQuery !== null) && (jQuery.ajax != null) && !jQuery.rails) { jQuery.rails = Rails; jQuery.ajaxPrefilter(function(options, originalOptions, xhr) { if (!options.crossDomain) { return CSRFProtection(xhr); } }); } Rails.start = function() { if (window._rails_loaded) { throw new Error('rails-ujs has already been loaded!'); } window.addEventListener('pageshow', function() { $(Rails.formEnableSelector).forEach(function(el) { if (getData(el, 'ujs:disabled')) { return enableElement(el); } }); return $(Rails.linkDisableSelector).forEach(function(el) { if (getData(el, 'ujs:disabled')) { return enableElement(el); } }); }); delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement); delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement); delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement); delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement); delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement); delegate(document, Rails.linkClickSelector, 'click', handleConfirm); delegate(document, Rails.linkClickSelector, 'click', handleMetaClick); delegate(document, Rails.linkClickSelector, 'click', disableElement); delegate(document, Rails.linkClickSelector, 'click', handleRemote); delegate(document, Rails.linkClickSelector, 'click', handleMethod); delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement); delegate(document, Rails.buttonClickSelector, 'click', handleConfirm); delegate(document, Rails.buttonClickSelector, 'click', disableElement); delegate(document, Rails.buttonClickSelector, 'click', handleRemote); delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement); delegate(document, Rails.inputChangeSelector, 'change', handleConfirm); delegate(document, Rails.inputChangeSelector, 'change', handleRemote); delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement); delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm); delegate(document, Rails.formSubmitSelector, 'submit', handleRemote); delegate(document, Rails.formSubmitSelector, 'submit', function(e) { return setTimeout((function() { return disableElement(e); }), 13); }); delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement); delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement); delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement); delegate(document, Rails.formInputClickSelector, 'click', handleConfirm); delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick); document.addEventListener('DOMContentLoaded', refreshCSRFTokens); return window._rails_loaded = true; }; if (window.Rails === Rails && fire(document, 'rails:attachBindings')) { Rails.start(); } }).call(this); }).call(this); if (typeof module === "object" && module.exports) { module.exports = Rails; } else if (typeof define === "function" && define.amd) { define(Rails); } }).call(this);