'use strict'; // JStuff function JStuff(query) { this.nodes = null; if (typeof query === 'string' || query instanceof String) { this.nodes = document.querySelectorAll(query); } else { this.nodes = [ query ]; } this.all = function(func, arg) { var i, result; for (i = 0; i < this.nodes.length; i++) { result = func(this.nodes[i], arg); } return result; }; this.attribute = function(name, value) { return this.all(function(node, attr) { if (attr.v) node.setAttribute(attr.k, attr.v); return node.getAttribute(attr.k); }, {k: name, v: value}); }; this.onClick = function(handler) { this.all(function(n, f) {n.addEventListener('click', f, false)}, handler); return this; }; this.onSubmit = function(handler) { this.all(function(n, f) {n.addEventListener('submit', f, false)}, handler); return this; }; this.addClass = function(className) { this.all(function(node, cn) { if (node.classList) node.classList.add(className); }, className); return this; } this.removeClass = function(className) { this.all(function(node, cn) { if (node.classList) node.classList.remove(className); }, className); return this; } this.replaceClass = function(oldClass, newClass) { this.all(function(node, obj) { if (node.classList) { node.classList.remove(obj.ocl); node.classList.add(obj.ncl); } }, {ocl: oldClass, ncl: newClass}); return this; } this.switchClass = function(className) { this.all(function(node, obj) { if (node.classList) { node.classList.toggle(className); } }, className); return this; } this.hasClass = function(className) { return this.all(function(node, cn) { if (node.classList) { return node.classList.contains(cn); } else { return (node.className.indexOf(cn) != -1); } }, className); } this.value = function(value) { return this.all(function(node, value) { if (node.value) { if (value) node.value = value; return node.value; } return null; }, value); } } window.$ = function(q){return new JStuff(q)}; window.$.main = function(func) { if (window.addEventListener) { addEventListener("load", func, false); } else if (window.attachEvent) { attachEvent("onload", func); } else { onload = func; } } $.create = function(tagName, childNode) { var n = document.createElement(tagName); if (childNode) n.appendChild(childNode); return new JStuff(n); } $.createLabel = function(text) { return new JStuff(document.createTextNode(text)); } // AJAX function JStuffAjax(attr) { var GET = 'GET', POST = 'POST', t = this, query = '', method, r; try { method = (attr.method == POST) ? POST : GET; } catch(e) { method = GET; } this.onReadyStateChange = function() { if (this.request.readyState == 4) { if (this.request.status === 200) { if (typeof (this.attr.load) !== 'undefined') { this.attr.load(this.request.status, this.request.responseText); } } return true; } return false } try { r = new XMLHttpRequest(); } catch(e) { var iev=[ "MSXML2.XmlHttp.5.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.2.0", "Microsoft.XmlHttp" ]; for(var i = 0; i < iev.length; i++) { try { r = new ActiveXObject(iev[i]); break; } catch(e){ // do nothing } } } if (typeof (attr.data) !== 'undefined') { for (var key in attr.data) { if (query != '') query += '&'; query += encodeURIComponent(key)+'='+encodeURIComponent(attr.data[key]); } if (method == GET) { attr.url += '?'+query; query = null; } } if (typeof (attr.sync) === 'undefined') { attr.sync = true; } r.overrideMimeType("text/plain"); r.open(method, attr.url, attr.sync); r.setRequestHeader("Content-type","application/x-www-form-urlencoded"); r.onreadystatechange = function() {t.onReadyStateChange()}; r.send(query); this.request = r; this.attr = attr; } $.ajax = function(attr) {return new JStuffAjax(attr)}; $.log = function(msg, ex) { if (console.log) { if (ex) { msg += ' E('+ex.message+')'; } console.log(msg); } }; // SVG fix /*! code below is based on svg4everybody v2.1.9 * github.com/jonathantneal/svg4everybody */ var LEGACY_SUPPORT = false; function embed(parent, svg, target) { // if the target exists if (target) { // create a document fragment to hold the contents of the target var fragment = document.createDocumentFragment(); // cache the closest matching viewBox var viewBox = !svg.hasAttribute('viewBox') && target.getAttribute('viewBox'); // conditionally set the viewBox on the svg if (viewBox) { svg.setAttribute('viewBox', viewBox); } // clone the target var clone = target.cloneNode(true); // copy the contents of the clone into the fragment while (clone.childNodes.length) { fragment.appendChild(clone.firstChild); } // append the fragment into the svg parent.appendChild(fragment); } } function loadreadystatechange(xhr) { // listen to changes in the request xhr.onreadystatechange = function () { // if the request is ready if (xhr.readyState === 4) { // get the cached html document var cachedDocument = xhr._cachedDocument; // ensure the cached html document based on the xhr response if (!cachedDocument) { cachedDocument = xhr._cachedDocument = document.implementation.createHTMLDocument(''); cachedDocument.body.innerHTML = xhr.responseText; // ensure domains are the same, otherwise we'll have issues appending the // element in IE 11 // cachedDocument.domain = document.domain; xhr._cachedTarget = {}; } // clear the xhr embeds list and embed each item xhr._embeds.splice(0).map(function (item) { // get the cached target var target = xhr._cachedTarget[item.id]; // ensure the cached target if (!target) { target = xhr._cachedTarget[item.id] = cachedDocument.getElementById(item.id); } // embed the target into the svg embed(item.parent, item.svg, target); }); } }; // test the ready state change immediately xhr.onreadystatechange(); } function svg4everybody(rawopts) { var opts = Object(rawopts); // create legacy support variables var nosvg; var fallback; // if running with legacy support if (LEGACY_SUPPORT) { // configure the fallback method fallback = opts.fallback || function (src) { return src.replace(/\?[^#]+/, '').replace('#', '.').replace(/^\./, '') + '.png' + (/\?[^#]+/.exec(src) || [''])[0]; }; // set whether to shiv and elements and use image fallbacks nosvg = 'nosvg' in opts ? opts.nosvg : /\bMSIE [1-8]\b/.test(navigator.userAgent); // conditionally shiv and if (nosvg) { document.createElement('svg'); document.createElement('use'); } } // set whether the polyfill will be activated or not var polyfill; var olderIEUA = /\bMSIE [1-8]\.0\b/; var newerIEUA = /\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/; var webkitUA = /\bAppleWebKit\/(\d+)\b/; var olderEdgeUA = /\bEdge\/12\.(\d+)\b/; var edgeUA = /\bEdge\/.(\d+)\b/; //Checks whether iframed var inIframe = window.top !== window.self; if ('polyfill' in opts) { polyfill = opts.polyfill; } else if (LEGACY_SUPPORT) { polyfill = olderIEUA.test(navigator.userAgent) || newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; } else { polyfill = newerIEUA.test(navigator.userAgent) || (navigator.userAgent.match(olderEdgeUA) || [])[1] < 10547 || (navigator.userAgent.match(webkitUA) || [])[1] < 537 || edgeUA.test(navigator.userAgent) && inIframe; } // create xhr requests object var requests = {}; // use request animation frame or a timeout to search the dom for svgs var requestAnimationFrame = window.requestAnimationFrame || setTimeout; // get a live collection of use elements on the page var uses = document.getElementsByTagName('use'); var numberOfSvgUseElementsToBypass = 0; function oninterval() { // get the cached index var index = 0; // while the index exists in the live collection while (index < uses.length) { // get the current var use = uses[index]; // get the current var parent = use.parentNode; var svg = getSVGAncestor(parent); var src = use.getAttribute('xlink:href') || use.getAttribute('href'); if (!src && opts.attributeName) { src = use.getAttribute(opts.attributeName); } if (svg && src) { // if running with legacy support if (LEGACY_SUPPORT && nosvg) { // create a new fallback image var img = document.createElement('img'); // force display in older IE img.style.cssText = 'display:inline-block;height:100%;width:100%'; // set the fallback size using the svg size img.setAttribute('width', svg.getAttribute('width') || svg.clientWidth); img.setAttribute('height', svg.getAttribute('height') || svg.clientHeight); // set the fallback src img.src = fallback(src, svg, use); // replace the with the fallback image parent.replaceChild(img, use); } else if (polyfill) { if (!opts.validate || opts.validate(src, svg, use)) { // remove the element parent.removeChild(use); // parse the src and get the url and id var srcSplit = src.split('#'); var url = srcSplit.shift(); var id = srcSplit.join('#'); // if the link is external if (url.length) { // get the cached xhr request var xhr = requests[url]; // ensure the xhr request exists if (!xhr) { xhr = requests[url] = new XMLHttpRequest(); xhr.open('GET', url); xhr.send(); xhr._embeds = []; } // add the svg and id as an item to the xhr embeds list xhr._embeds.push({ parent: parent, svg: svg, id: id }); // prepare the xhr ready state change event loadreadystatechange(xhr); } else { // embed the local id into the svg embed(parent, svg, document.getElementById(id)); } } else { // increase the index when the previous value was not "valid" ++index; ++numberOfSvgUseElementsToBypass; } } } else { // increase the index when the previous value was not "valid" ++index; } } // continue the interval if (!uses.length || uses.length - numberOfSvgUseElementsToBypass > 0) { requestAnimationFrame(oninterval, 67); } } // conditionally start the interval if the polyfill is active if (polyfill) { oninterval(); } } function getSVGAncestor(node) { var svg = node; while (svg.nodeName.toLowerCase() !== 'svg') { svg = svg.parentNode; if (!svg) { break; } } return svg; } // Core var gCore = { mod: null }; // Contact function Contact() { var t = this; this.email = $('#feedback__email'); this.msg = $('#feedback__msg'); this.onLoad = function(httpStatus, content) { if (httpStatus == 200) { this.email.value(''); this.msg.value(''); $.log('Success!'); alert("Thank you for your message!"); } else { alert("Your message was not sent!"); $.log('server response: '+httpStatus); } }; this.onSubmit = function(evt) { var t = this; $.ajax({ url: '/hook/feedback/', handler: function(httpStatus, content) {t.onLoad(httpStatus, content)}, data: {email: this.email.value(), msg: this.msg.value()}, method: 'POST' }); $.log('Email: '+this.email.value() +'; MSG: '+this.msg.value()); event.preventDefault(); return false; } $('#feedback__form').onSubmit(function(evt) {return t.onSubmit(evt)}); } // Main $.main(function(){ // initialize menu var sw = $('#menu__switch').onClick(function(evt) { var menu = $('#menu'), targ = $(evt.currentTarget); menu.switchClass('menu--visible'); targ.switchClass('menu__switch--opened'); }); // modules switch($(document.documentElement).attribute('data-view')) { case 'contact': gCore.mod = new Contact(); break; } svg4everybody(); });