var Ajaxloader = function () { 'use strict'; if (!XMLHttpRequest) { // doesn't cut the mustard. return false; } var container = ''; var data = null; var callback = null; var dataencoding = true; var append = false; var ajax = new XMLHttpRequest(); var startUpdating = function () { container.setAttribute('aria-busy', 'true'); }; var stopUpdating = function () { container.setAttribute('aria-busy', 'false'); }; var runScripts = function () { var scripts = container.getElementsByTagName('script'); var total = scripts.length; var elem; var code; var script; var i; for (i = 0; i < total; i = i + 1) { elem = scripts[i]; code = (elem.text || elem.textContent || elem.innerHTML || ''); script = document.createElement('script'); script.type = 'text/javascript'; script.appendChild(document.createTextNode(code)); container.insertBefore(script, container.firstChild); container.removeChild(script); } }; var inject = function (html) { startUpdating(); if (append) { container.insertAdjacentHTML('beforeend', html); } else { container.innerHTML = html; } stopUpdating(); runScripts(); }; var fill = function () { if (isComplete()) { inject(ajax.responseText); if (callback) { callback(); } } }; var isComplete = function() { if (ajax.readyState !== 4) { return false; } if (ajax.status !== 200) { return false; } return true; } this.setTarget = function (element) { container = element; container.setAttribute('aria-live', 'polite'); container.setAttribute('aria-atomic', 'true'); container.setAttribute('aria-busy', 'false'); }; this.setData = function (variables) { data = variables; }; this.sendRawData = function () { dataencoding = false; }; this.appendContent = function () { append = true; }; this.setCallback = function (instruction) { callback = instruction; }; this.update = function (html) { inject(html); }; this.load = function (url) { if (!ajax) { return; } ajax.onreadystatechange = fill; if (data) { ajax.open('POST', url, true); if (dataencoding === true) { ajax.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); } ajax.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest'); ajax.send(data); } else { ajax.open('GET', url, true); ajax.setRequestHeader('X-REQUESTED-WITH', 'XMLHttpRequest'); ajax.send(null); } }; }; /* The Hijax object is a collection of reusable helper methods for Ajax requests */ var Hijax = new function() { this.setFeedback = function (element, text) { var feedback = document.createElement('span'); feedback.setAttribute('role', 'status'); feedback.innerHTML = text; document.querySelector('body').appendChild(feedback); var elementBox = element.getBoundingClientRect(); var feedbackBox = feedback.getBoundingClientRect(); var y = Math.round((elementBox.top + window.scrollY) - feedbackBox.height); var x = Math.round((elementBox.left + window.scrollX + (elementBox.width/2)) - (feedbackBox.width/2)); feedback.style.position = 'absolute'; feedback.style.left = x + 'px'; feedback.style.top = y + 'px'; feedback.style.opacity = 1; feedback.style.transition = 'transform .75s, opacity .75s'; feedback.style.transform = 'translateY(-75px)'; feedback.style.opacity = 0; feedback.addEventListener('transitionend', function () { if (feedback.parentNode) { feedback.parentNode.removeChild(feedback); } }, false); }; this.showLoading = function (element) { var loader = document.createElement('img'); loader.setAttribute('src', '/images/ajax-loader.gif'); loader.setAttribute('alt', config['ui']['loading']); document.querySelector('body').appendChild(loader); var elementBox = element.getBoundingClientRect(); var y = Math.round(elementBox.top + window.scrollY); y = y + Math.round(elementBox.height/2); y = y - 8; var x = Math.round(elementBox.left + window.scrollX); x = x + Math.round(elementBox.width); loader.style.position = 'absolute'; loader.style.left = x + 'px'; loader.style.top = y + 'px'; return loader; }; this.removeLoading = function (element) { element.parentNode.removeChild(element); }; }; (function (win, doc) { 'use strict'; doc.querySelector('body').className += ' hasJS'; }(this, this.document)); (function (win, doc) { 'use strict'; if (!doc.querySelectorAll || !win.addEventListener) { // doesn't cut the mustard. return; } var passwordFields = doc.querySelectorAll('input[type="password"]'); var passwordFieldsTotal = passwordFields.length; var i; for (i = 0; i < passwordFieldsTotal; i = i + 1) { var passwordField = passwordFields[i]; var id = passwordField.getAttribute('id'); var value = passwordField.getAttribute('value'); passwordField.insertAdjacentHTML('afterend', ' '); var textField = passwordField.nextSibling; var checkbox = doc.getElementById(id + '-checkbox'); checkbox.addEventListener('click', function(ev) { if (textField.style.display == 'none') { textField.style.display = 'inline'; passwordField.style.display = 'none'; } else { textField.style.display = 'none'; passwordField.style.display = 'inline'; } }, false); passwordField.addEventListener('keyup', function (ev) { textField.value = passwordField.value; }); textField.addEventListener('keyup', function (ev) { passwordField.value = textField.value; }); } }(this, this.document)); (function (win, doc) { 'use strict'; if (!win.addEventListener) { // doesn't cut the mustard. return; } doc.addEventListener('click', function (ev) { ev = ev || win.event; var target = ev.target; if (target.hasAttribute('readonly')) { target.focus(); target.select(); } }, false); }(this, this.document)); (function (win, doc) { 'use strict'; if (!win.addEventListener || !win.FormData) { // doesn't cut the mustard. return; } doc.addEventListener('click', function (ev) { ev = ev || win.event; var target = ev.target; var container = target.parentNode.parentNode; if (container.classList.contains('networking') && target.tagName == 'BUTTON') { var form = container.querySelector('form'); var loader = Hijax.showLoading(target); var text = target.innerText; var message = config['feedback'][text]; var data = new FormData(form); var url = form.getAttribute('action'); var ajax = new Ajaxloader(); if (ajax) { ajax.setTarget(container); ajax.setData(data); ajax.setCallback(function () { Hijax.removeLoading(loader); Hijax.setFeedback(container, message); }); ajax.sendRawData(); ajax.load(url); ev.preventDefault(); } } }, false); }(this, this.document)); (function (win, doc) { 'use strict'; if (!win.addEventListener) { // doesn't cut the mustard. return; } doc.addEventListener('click', function (ev) { ev = ev || win.event; var target = ev.target; if (target.dataset && target.dataset.ajax) { var container = target.parentNode; var loader = Hijax.showLoading(target); var url = target.getAttribute('href'); var ajax = new Ajaxloader(); if (ajax) { ajax.setTarget(container); ajax.setCallback(Hijax.removeLoading(loader)); ajax.load(url); ev.preventDefault(); } } }, false); }(this, this.document)); (function (win, doc) { 'use strict'; if (!win.addEventListener || !win.FormData) { // doesn't cut the mustard. return; } doc.addEventListener('click', function (ev) { ev = ev || win.event; var target = ev.target; var container = target.parentNode.parentNode; if (container.classList.contains('hentry') && target.tagName == 'BUTTON') { var form = container.querySelector('form'); var loader = Hijax.showLoading(target); var url = form.getAttribute('action'); var data = new FormData(form); var ajax = new Ajaxloader(); if (ajax) { ajax.setTarget(container); ajax.setData(data); ajax.setCallback(Hijax.removeLoading(loader)); ajax.sendRawData(); ajax.load(url); ev.preventDefault(); } } }, false); }(this, this.document)); (function (win, doc) { 'use strict'; if (('standalone' in win.navigator) && win.navigator.standalone && win.addEventListener) { var links = doc.getElementsByTagName('a'), total = links.length, i; for (i = 0; i < total; i = i + 1) { links[i].addEventListener('click', function(ev) { var dest = this.getAttribute('href'); if (!dest.match(/^http(s?)/g)) { ev.preventDefault(); win.location = dest; } }); } } }(this, this.document));