Run Grunt build script
|
@ -71,7 +71,7 @@ module.exports = function(grunt) {
|
|||
files: [
|
||||
'<%= jshint.all %>'
|
||||
],
|
||||
tasks: ['jshint','uglify']
|
||||
tasks: ['uglify']
|
||||
}
|
||||
},
|
||||
clean: {
|
||||
|
|
25
assets/css/main.min.css
vendored
Normal file
|
@ -1,838 +1,3 @@
|
|||
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
|
||||
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
|
||||
|
||||
window.matchMedia = window.matchMedia || (function( doc, undefined ) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var bool,
|
||||
docElem = doc.documentElement,
|
||||
refNode = docElem.firstElementChild || docElem.firstChild,
|
||||
// fakeBody required for <FF4 when executed in <head>
|
||||
fakeBody = doc.createElement( "body" ),
|
||||
div = doc.createElement( "div" );
|
||||
|
||||
div.id = "mq-test-1";
|
||||
div.style.cssText = "position:absolute;top:-100em";
|
||||
fakeBody.style.background = "none";
|
||||
fakeBody.appendChild(div);
|
||||
|
||||
return function(q){
|
||||
|
||||
div.innerHTML = "­<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";
|
||||
|
||||
docElem.insertBefore( fakeBody, refNode );
|
||||
bool = div.offsetWidth === 42;
|
||||
docElem.removeChild( fakeBody );
|
||||
|
||||
return {
|
||||
matches: bool,
|
||||
media: q
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}( document ));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! Respond.js v1.1.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
|
||||
(function( win ){
|
||||
|
||||
"use strict";
|
||||
|
||||
//exposed namespace
|
||||
var respond = {};
|
||||
win.respond = respond;
|
||||
|
||||
//define update even in native-mq-supporting browsers, to avoid errors
|
||||
respond.update = function(){};
|
||||
|
||||
//expose media query support flag for external use
|
||||
respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches;
|
||||
|
||||
//if media queries are supported, exit here
|
||||
if( respond.mediaQueriesSupported ){
|
||||
return;
|
||||
}
|
||||
|
||||
//define vars
|
||||
var doc = win.document,
|
||||
docElem = doc.documentElement,
|
||||
mediastyles = [],
|
||||
rules = [],
|
||||
appendedEls = [],
|
||||
parsedSheets = {},
|
||||
resizeThrottle = 30,
|
||||
head = doc.getElementsByTagName( "head" )[0] || docElem,
|
||||
base = doc.getElementsByTagName( "base" )[0],
|
||||
links = head.getElementsByTagName( "link" ),
|
||||
requestQueue = [],
|
||||
|
||||
//loop stylesheets, send text content to translate
|
||||
ripCSS = function(){
|
||||
|
||||
for( var i = 0; i < links.length; i++ ){
|
||||
var sheet = links[ i ],
|
||||
href = sheet.href,
|
||||
media = sheet.media,
|
||||
isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
|
||||
|
||||
//only links plz and prevent re-parsing
|
||||
if( !!href && isCSS && !parsedSheets[ href ] ){
|
||||
// selectivizr exposes css through the rawCssText expando
|
||||
if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
|
||||
translate( sheet.styleSheet.rawCssText, href, media );
|
||||
parsedSheets[ href ] = true;
|
||||
} else {
|
||||
if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) ||
|
||||
href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
|
||||
requestQueue.push( {
|
||||
href: href,
|
||||
media: media
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
makeRequests();
|
||||
},
|
||||
|
||||
//recurse through request queue, get css text
|
||||
makeRequests = function(){
|
||||
if( requestQueue.length ){
|
||||
var thisRequest = requestQueue.shift();
|
||||
|
||||
ajax( thisRequest.href, function( styles ){
|
||||
translate( styles, thisRequest.href, thisRequest.media );
|
||||
parsedSheets[ thisRequest.href ] = true;
|
||||
|
||||
// by wrapping recursive function call in setTimeout
|
||||
// we prevent "Stack overflow" error in IE7
|
||||
win.setTimeout(function(){ makeRequests(); },0);
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
//find media blocks in css text, convert to style blocks
|
||||
translate = function( styles, href, media ){
|
||||
var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),
|
||||
ql = qs && qs.length || 0;
|
||||
|
||||
//try to get CSS path
|
||||
href = href.substring( 0, href.lastIndexOf( "/" ) );
|
||||
|
||||
var repUrls = function( css ){
|
||||
return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
|
||||
},
|
||||
useMedia = !ql && media;
|
||||
|
||||
//if path exists, tack on trailing slash
|
||||
if( href.length ){ href += "/"; }
|
||||
|
||||
//if no internal queries exist, but media attr does, use that
|
||||
//note: this currently lacks support for situations where a media attr is specified on a link AND
|
||||
//its associated stylesheet has internal CSS media queries.
|
||||
//In those cases, the media attribute will currently be ignored.
|
||||
if( useMedia ){
|
||||
ql = 1;
|
||||
}
|
||||
|
||||
for( var i = 0; i < ql; i++ ){
|
||||
var fullq, thisq, eachq, eql;
|
||||
|
||||
//media attr
|
||||
if( useMedia ){
|
||||
fullq = media;
|
||||
rules.push( repUrls( styles ) );
|
||||
}
|
||||
//parse for styles
|
||||
else{
|
||||
fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
|
||||
rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
|
||||
}
|
||||
|
||||
eachq = fullq.split( "," );
|
||||
eql = eachq.length;
|
||||
|
||||
for( var j = 0; j < eql; j++ ){
|
||||
thisq = eachq[ j ];
|
||||
mediastyles.push( {
|
||||
media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",
|
||||
rules : rules.length - 1,
|
||||
hasquery : thisq.indexOf("(") > -1,
|
||||
minw : thisq.match( /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
|
||||
maxw : thisq.match( /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
applyMedia();
|
||||
},
|
||||
|
||||
lastCall,
|
||||
|
||||
resizeDefer,
|
||||
|
||||
// returns the value of 1em in pixels
|
||||
getEmValue = function() {
|
||||
var ret,
|
||||
div = doc.createElement('div'),
|
||||
body = doc.body,
|
||||
fakeUsed = false;
|
||||
|
||||
div.style.cssText = "position:absolute;font-size:1em;width:1em";
|
||||
|
||||
if( !body ){
|
||||
body = fakeUsed = doc.createElement( "body" );
|
||||
body.style.background = "none";
|
||||
}
|
||||
|
||||
body.appendChild( div );
|
||||
|
||||
docElem.insertBefore( body, docElem.firstChild );
|
||||
|
||||
ret = div.offsetWidth;
|
||||
|
||||
if( fakeUsed ){
|
||||
docElem.removeChild( body );
|
||||
}
|
||||
else {
|
||||
body.removeChild( div );
|
||||
}
|
||||
|
||||
//also update eminpx before returning
|
||||
ret = eminpx = parseFloat(ret);
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
//cached container for 1em value, populated the first time it's needed
|
||||
eminpx,
|
||||
|
||||
//enable/disable styles
|
||||
applyMedia = function( fromResize ){
|
||||
var name = "clientWidth",
|
||||
docElemProp = docElem[ name ],
|
||||
currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
|
||||
styleBlocks = {},
|
||||
lastLink = links[ links.length-1 ],
|
||||
now = (new Date()).getTime();
|
||||
|
||||
//throttle resize calls
|
||||
if( fromResize && lastCall && now - lastCall < resizeThrottle ){
|
||||
win.clearTimeout( resizeDefer );
|
||||
resizeDefer = win.setTimeout( applyMedia, resizeThrottle );
|
||||
return;
|
||||
}
|
||||
else {
|
||||
lastCall = now;
|
||||
}
|
||||
|
||||
for( var i in mediastyles ){
|
||||
if( mediastyles.hasOwnProperty( i ) ){
|
||||
var thisstyle = mediastyles[ i ],
|
||||
min = thisstyle.minw,
|
||||
max = thisstyle.maxw,
|
||||
minnull = min === null,
|
||||
maxnull = max === null,
|
||||
em = "em";
|
||||
|
||||
if( !!min ){
|
||||
min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
|
||||
}
|
||||
if( !!max ){
|
||||
max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
|
||||
}
|
||||
|
||||
// if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
|
||||
if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
|
||||
if( !styleBlocks[ thisstyle.media ] ){
|
||||
styleBlocks[ thisstyle.media ] = [];
|
||||
}
|
||||
styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remove any existing respond style element(s)
|
||||
for( var j in appendedEls ){
|
||||
if( appendedEls.hasOwnProperty( j ) ){
|
||||
if( appendedEls[ j ] && appendedEls[ j ].parentNode === head ){
|
||||
head.removeChild( appendedEls[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//inject active styles, grouped by media type
|
||||
for( var k in styleBlocks ){
|
||||
if( styleBlocks.hasOwnProperty( k ) ){
|
||||
var ss = doc.createElement( "style" ),
|
||||
css = styleBlocks[ k ].join( "\n" );
|
||||
|
||||
ss.type = "text/css";
|
||||
ss.media = k;
|
||||
|
||||
//originally, ss was appended to a documentFragment and sheets were appended in bulk.
|
||||
//this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
|
||||
head.insertBefore( ss, lastLink.nextSibling );
|
||||
|
||||
if ( ss.styleSheet ){
|
||||
ss.styleSheet.cssText = css;
|
||||
}
|
||||
else {
|
||||
ss.appendChild( doc.createTextNode( css ) );
|
||||
}
|
||||
|
||||
//push to appendedEls to track for later removal
|
||||
appendedEls.push( ss );
|
||||
}
|
||||
}
|
||||
},
|
||||
//tweaked Ajax functions from Quirksmode
|
||||
ajax = function( url, callback ) {
|
||||
var req = xmlHttp();
|
||||
if (!req){
|
||||
return;
|
||||
}
|
||||
req.open( "GET", url, true );
|
||||
req.onreadystatechange = function () {
|
||||
if ( req.readyState !== 4 || req.status !== 200 && req.status !== 304 ){
|
||||
return;
|
||||
}
|
||||
callback( req.responseText );
|
||||
};
|
||||
if ( req.readyState === 4 ){
|
||||
return;
|
||||
}
|
||||
req.send( null );
|
||||
},
|
||||
//define ajax obj
|
||||
xmlHttp = (function() {
|
||||
var xmlhttpmethod = false;
|
||||
try {
|
||||
xmlhttpmethod = new win.XMLHttpRequest();
|
||||
}
|
||||
catch( e ){
|
||||
xmlhttpmethod = new win.ActiveXObject( "Microsoft.XMLHTTP" );
|
||||
}
|
||||
return function(){
|
||||
return xmlhttpmethod;
|
||||
};
|
||||
})();
|
||||
|
||||
//translate CSS
|
||||
ripCSS();
|
||||
|
||||
//expose update for re-running respond later on
|
||||
respond.update = ripCSS;
|
||||
|
||||
//adjust on resize
|
||||
function callMedia(){
|
||||
applyMedia( true );
|
||||
}
|
||||
if( win.addEventListener ){
|
||||
win.addEventListener( "resize", callMedia, false );
|
||||
}
|
||||
else if( win.attachEvent ){
|
||||
win.attachEvent( "onresize", callMedia );
|
||||
}
|
||||
})(this);
|
||||
|
||||
/*! responsive-nav.js v1.0.14
|
||||
* https://github.com/viljamis/responsive-nav.js
|
||||
* http://responsive-nav.com
|
||||
*
|
||||
* Copyright (c) 2013 @viljamis
|
||||
* Available under the MIT license
|
||||
*/
|
||||
|
||||
/* jshint strict:false, forin:false, noarg:true, noempty:true, eqeqeq:true,
|
||||
boss:true, bitwise:true, browser:true, devel:true, indent:2 */
|
||||
/* exported responsiveNav */
|
||||
|
||||
var responsiveNav = (function (window, document) {
|
||||
|
||||
var computed = !!window.getComputedStyle;
|
||||
|
||||
// getComputedStyle polyfill
|
||||
if (!window.getComputedStyle) {
|
||||
window.getComputedStyle = function(el) {
|
||||
this.el = el;
|
||||
this.getPropertyValue = function(prop) {
|
||||
var re = /(\-([a-z]){1})/g;
|
||||
if (prop === "float") {
|
||||
prop = "styleFloat";
|
||||
}
|
||||
if (re.test(prop)) {
|
||||
prop = prop.replace(re, function () {
|
||||
return arguments[2].toUpperCase();
|
||||
});
|
||||
}
|
||||
return el.currentStyle[prop] ? el.currentStyle[prop] : null;
|
||||
};
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
var nav,
|
||||
opts,
|
||||
navToggle,
|
||||
docEl = document.documentElement,
|
||||
head = document.getElementsByTagName("head")[0],
|
||||
styleElement = document.createElement("style"),
|
||||
navOpen = false,
|
||||
|
||||
// fn arg can be an object or a function, thanks to handleEvent
|
||||
// read more at: http://www.thecssninja.com/javascript/handleevent
|
||||
addEvent = function (el, evt, fn, bubble) {
|
||||
if ("addEventListener" in el) {
|
||||
// BBOS6 doesn't support handleEvent, catch and polyfill
|
||||
try {
|
||||
el.addEventListener(evt, fn, bubble);
|
||||
} catch (e) {
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.addEventListener(evt, function (e) {
|
||||
// Bind fn as this and set first arg as event object
|
||||
fn.handleEvent.call(fn, e);
|
||||
}, bubble);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else if ("attachEvent" in el) {
|
||||
// check if the callback is an object and contains handleEvent
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.attachEvent("on" + evt, function () {
|
||||
// Bind fn as this
|
||||
fn.handleEvent.call(fn);
|
||||
});
|
||||
} else {
|
||||
el.attachEvent("on" + evt, fn);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removeEvent = function (el, evt, fn, bubble) {
|
||||
if ("removeEventListener" in el) {
|
||||
try {
|
||||
el.removeEventListener(evt, fn, bubble);
|
||||
} catch (e) {
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.removeEventListener(evt, function (e) {
|
||||
fn.handleEvent.call(fn, e);
|
||||
}, bubble);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else if ("detachEvent" in el) {
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.detachEvent("on" + evt, function () {
|
||||
fn.handleEvent.call(fn);
|
||||
});
|
||||
} else {
|
||||
el.detachEvent("on" + evt, fn);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getFirstChild = function (e) {
|
||||
var firstChild = e.firstChild;
|
||||
// skip TextNodes
|
||||
while (firstChild !== null && firstChild.nodeType !== 1) {
|
||||
firstChild = firstChild.nextSibling;
|
||||
}
|
||||
return firstChild;
|
||||
},
|
||||
|
||||
setAttributes = function (el, attrs) {
|
||||
for (var key in attrs) {
|
||||
el.setAttribute(key, attrs[key]);
|
||||
}
|
||||
},
|
||||
|
||||
addClass = function (el, cls) {
|
||||
el.className += " " + cls;
|
||||
el.className = el.className.replace(/(^\s*)|(\s*$)/g,"");
|
||||
},
|
||||
|
||||
removeClass = function (el, cls) {
|
||||
var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
|
||||
el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,"");
|
||||
},
|
||||
|
||||
ResponsiveNav = function (el, options) {
|
||||
var i;
|
||||
|
||||
// Default options
|
||||
this.options = {
|
||||
animate: true, // Boolean: Use CSS3 transitions, true or false
|
||||
transition: 400, // Integer: Speed of the transition, in milliseconds
|
||||
label: "Menu", // String: Label for the navigation toggle
|
||||
insert: "after", // String: Insert the toggle before or after the navigation
|
||||
customToggle: "", // Selector: Specify the ID of a custom toggle
|
||||
openPos: "relative", // String: Position of the opened nav, relative or static
|
||||
jsClass: "js", // String: 'JS enabled' class which is added to <html> el
|
||||
init: function(){}, // Function: Init callback
|
||||
open: function(){}, // Function: Open callback
|
||||
close: function(){} // Function: Close callback
|
||||
};
|
||||
|
||||
// User defined options
|
||||
for (i in options) {
|
||||
this.options[i] = options[i];
|
||||
}
|
||||
|
||||
// Adds "js" class for <html>
|
||||
addClass(docEl, this.options.jsClass);
|
||||
|
||||
// Wrapper
|
||||
this.wrapperEl = el.replace("#", "");
|
||||
if (document.getElementById(this.wrapperEl)) {
|
||||
this.wrapper = document.getElementById(this.wrapperEl);
|
||||
} else {
|
||||
// If el doesn't exists, stop here.
|
||||
throw new Error("The nav element you are trying to select doesn't exist");
|
||||
}
|
||||
|
||||
// Inner wrapper
|
||||
this.wrapper.inner = getFirstChild(this.wrapper);
|
||||
|
||||
// For minification
|
||||
opts = this.options;
|
||||
nav = this.wrapper;
|
||||
|
||||
// Init
|
||||
this._init(this);
|
||||
};
|
||||
|
||||
ResponsiveNav.prototype = {
|
||||
// Public methods
|
||||
destroy: function () {
|
||||
this._removeStyles();
|
||||
removeClass(nav, "closed");
|
||||
removeClass(nav, "opened");
|
||||
nav.removeAttribute("style");
|
||||
nav.removeAttribute("aria-hidden");
|
||||
nav = null;
|
||||
_instance = null;
|
||||
|
||||
removeEvent(window, "load", this, false);
|
||||
removeEvent(window, "resize", this, false);
|
||||
removeEvent(navToggle, "mousedown", this, false);
|
||||
removeEvent(navToggle, "touchstart", this, false);
|
||||
removeEvent(navToggle, "touchend", this, false);
|
||||
removeEvent(navToggle, "keyup", this, false);
|
||||
removeEvent(navToggle, "click", this, false);
|
||||
|
||||
if (!opts.customToggle) {
|
||||
navToggle.parentNode.removeChild(navToggle);
|
||||
} else {
|
||||
navToggle.removeAttribute("aria-hidden");
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
if (!navOpen) {
|
||||
removeClass(nav, "closed");
|
||||
addClass(nav, "opened");
|
||||
nav.style.position = opts.openPos;
|
||||
setAttributes(nav, {"aria-hidden": "false"});
|
||||
|
||||
navOpen = true;
|
||||
opts.open();
|
||||
} else {
|
||||
removeClass(nav, "opened");
|
||||
addClass(nav, "closed");
|
||||
setAttributes(nav, {"aria-hidden": "true"});
|
||||
|
||||
if (opts.animate) {
|
||||
setTimeout(function () {
|
||||
nav.style.position = "relative";
|
||||
}, opts.transition + 10);
|
||||
} else {
|
||||
nav.style.position = "relative";
|
||||
}
|
||||
|
||||
navOpen = false;
|
||||
opts.close();
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function (e) {
|
||||
var evt = e || window.event;
|
||||
|
||||
switch (evt.type) {
|
||||
case "mousedown":
|
||||
this._onmousedown(evt);
|
||||
break;
|
||||
case "touchstart":
|
||||
this._ontouchstart(evt);
|
||||
break;
|
||||
case "touchend":
|
||||
this._ontouchend(evt);
|
||||
break;
|
||||
case "keyup":
|
||||
this._onkeyup(evt);
|
||||
break;
|
||||
case "click":
|
||||
this._onclick(evt);
|
||||
break;
|
||||
case "load":
|
||||
this._transitions(evt);
|
||||
this._resize(evt);
|
||||
break;
|
||||
case "resize":
|
||||
this._resize(evt);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// Private methods
|
||||
_init: function () {
|
||||
addClass(nav, "closed");
|
||||
this._createToggle();
|
||||
|
||||
addEvent(window, "load", this, false);
|
||||
addEvent(window, "resize", this, false);
|
||||
addEvent(navToggle, "mousedown", this, false);
|
||||
addEvent(navToggle, "touchstart", this, false);
|
||||
addEvent(navToggle, "touchend", this, false);
|
||||
addEvent(navToggle, "keyup", this, false);
|
||||
addEvent(navToggle, "click", this, false);
|
||||
},
|
||||
|
||||
_createStyles: function () {
|
||||
if (!styleElement.parentNode) {
|
||||
head.appendChild(styleElement);
|
||||
}
|
||||
},
|
||||
|
||||
_removeStyles: function () {
|
||||
if (styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
}
|
||||
},
|
||||
|
||||
_createToggle: function () {
|
||||
if (!opts.customToggle) {
|
||||
var toggle = document.createElement("a");
|
||||
toggle.innerHTML = opts.label;
|
||||
setAttributes(toggle, {
|
||||
"href": "#",
|
||||
"id": "nav-toggle"
|
||||
});
|
||||
|
||||
if (opts.insert === "after") {
|
||||
nav.parentNode.insertBefore(toggle, nav.nextSibling);
|
||||
} else {
|
||||
nav.parentNode.insertBefore(toggle, nav);
|
||||
}
|
||||
|
||||
navToggle = document.getElementById("nav-toggle");
|
||||
} else {
|
||||
var toggleEl = opts.customToggle.replace("#", "");
|
||||
|
||||
if (document.getElementById(toggleEl)) {
|
||||
navToggle = document.getElementById(toggleEl);
|
||||
} else {
|
||||
throw new Error("The custom nav toggle you are trying to select doesn't exist");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_preventDefault: function(e) {
|
||||
if (e.preventDefault) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
e.returnValue = false;
|
||||
}
|
||||
},
|
||||
|
||||
_onmousedown: function (e) {
|
||||
var evt = e || window.event;
|
||||
// If the user isn't right clicking:
|
||||
if (!(evt.which === 3 || evt.button === 2)) {
|
||||
this._preventDefault(e);
|
||||
this.toggle(e);
|
||||
}
|
||||
},
|
||||
|
||||
_ontouchstart: function (e) {
|
||||
// Touchstart event fires before
|
||||
// the mousedown and can wipe it
|
||||
navToggle.onmousedown = null;
|
||||
this._preventDefault(e);
|
||||
this.toggle(e);
|
||||
},
|
||||
|
||||
_ontouchend: function () {
|
||||
// Prevents ghost click from happening on some Android browsers
|
||||
var that = this;
|
||||
nav.addEventListener("click", that._preventDefault, true);
|
||||
setTimeout(function () {
|
||||
nav.removeEventListener("click", that._preventDefault, true);
|
||||
}, opts.transition);
|
||||
},
|
||||
|
||||
_onkeyup: function (e) {
|
||||
var evt = e || window.event;
|
||||
if (evt.keyCode === 13) {
|
||||
this.toggle(e);
|
||||
}
|
||||
},
|
||||
|
||||
_onclick: function (e) {
|
||||
// For older browsers (looking at IE)
|
||||
this._preventDefault(e);
|
||||
},
|
||||
|
||||
_transitions: function () {
|
||||
if (opts.animate) {
|
||||
var objStyle = nav.style,
|
||||
transition = "max-height " + opts.transition + "ms";
|
||||
|
||||
objStyle.WebkitTransition = transition;
|
||||
objStyle.MozTransition = transition;
|
||||
objStyle.OTransition = transition;
|
||||
objStyle.transition = transition;
|
||||
}
|
||||
},
|
||||
|
||||
_calcHeight: function () {
|
||||
var savedHeight = nav.inner.offsetHeight,
|
||||
innerStyles = "#" + this.wrapperEl + ".opened{max-height:" + savedHeight + "px}";
|
||||
|
||||
// Hide from old IE
|
||||
if (computed) {
|
||||
styleElement.innerHTML = innerStyles;
|
||||
innerStyles = "";
|
||||
}
|
||||
},
|
||||
|
||||
_resize: function () {
|
||||
if (window.getComputedStyle(navToggle, null).getPropertyValue("display") !== "none") {
|
||||
setAttributes(navToggle, {"aria-hidden": "false"});
|
||||
|
||||
// If the navigation is hidden
|
||||
if (nav.className.match(/(^|\s)closed(\s|$)/)) {
|
||||
setAttributes(nav, {"aria-hidden": "true"});
|
||||
nav.style.position = "absolute";
|
||||
}
|
||||
|
||||
this._createStyles();
|
||||
this._calcHeight();
|
||||
} else {
|
||||
setAttributes(navToggle, {"aria-hidden": "true"});
|
||||
setAttributes(nav, {"aria-hidden": "false"});
|
||||
nav.style.position = opts.openPos;
|
||||
this._removeStyles();
|
||||
}
|
||||
|
||||
// Init callback
|
||||
opts.init();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var _instance;
|
||||
function rn (el, options) {
|
||||
if (!_instance) {
|
||||
_instance = new ResponsiveNav(el, options);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
return rn;
|
||||
})(window, document);
|
||||
|
||||
|
||||
/*global jQuery */
|
||||
/*jshint multistr:true browser:true */
|
||||
/*!
|
||||
* FitVids 1.0
|
||||
*
|
||||
* Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
|
||||
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
|
||||
* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
|
||||
*
|
||||
* Date: Thu Sept 01 18:00:00 2011 -0500
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
|
||||
"use strict";
|
||||
|
||||
$.fn.fitVids = function( options ) {
|
||||
var settings = {
|
||||
customSelector: null
|
||||
};
|
||||
|
||||
var div = document.createElement('div'),
|
||||
ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0];
|
||||
|
||||
div.className = 'fit-vids-style';
|
||||
div.innerHTML = '­<style> \
|
||||
.fluid-width-video-wrapper { \
|
||||
width: 100%; \
|
||||
position: relative; \
|
||||
padding: 0; \
|
||||
} \
|
||||
\
|
||||
.fluid-width-video-wrapper iframe, \
|
||||
.fluid-width-video-wrapper object, \
|
||||
.fluid-width-video-wrapper embed { \
|
||||
position: absolute; \
|
||||
top: 0; \
|
||||
left: 0; \
|
||||
width: 100%; \
|
||||
height: 100%; \
|
||||
} \
|
||||
</style>';
|
||||
|
||||
ref.parentNode.insertBefore(div,ref);
|
||||
|
||||
if ( options ) {
|
||||
$.extend( settings, options );
|
||||
}
|
||||
|
||||
return this.each(function(){
|
||||
var selectors = [
|
||||
"iframe[src*='player.vimeo.com']",
|
||||
"iframe[src*='www.youtube.com']",
|
||||
"iframe[src*='www.youtube-nocookie.com']",
|
||||
"iframe[src*='www.kickstarter.com']",
|
||||
"object",
|
||||
"embed"
|
||||
];
|
||||
|
||||
if (settings.customSelector) {
|
||||
selectors.push(settings.customSelector);
|
||||
}
|
||||
|
||||
var $allVideos = $(this).find(selectors.join(','));
|
||||
|
||||
$allVideos.each(function(){
|
||||
var $this = $(this);
|
||||
if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
|
||||
var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
|
||||
width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
|
||||
aspectRatio = height / width;
|
||||
if(!$this.attr('id')){
|
||||
var videoID = 'fitvid' + Math.floor(Math.random()*999999);
|
||||
$this.attr('id', videoID);
|
||||
}
|
||||
$this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%");
|
||||
$this.removeAttr('height').removeAttr('width');
|
||||
});
|
||||
});
|
||||
};
|
||||
})( jQuery );
|
||||
|
||||
/*! Plugin options and other jQuery stuff */
|
||||
|
||||
// Responsive Nav
|
||||
|
|
408
assets/js/plugins/responsive-nav.js
Normal file
|
@ -0,0 +1,408 @@
|
|||
/*! responsive-nav.js v1.0.14
|
||||
* https://github.com/viljamis/responsive-nav.js
|
||||
* http://responsive-nav.com
|
||||
*
|
||||
* Copyright (c) 2013 @viljamis
|
||||
* Available under the MIT license
|
||||
*/
|
||||
|
||||
/* jshint strict:false, forin:false, noarg:true, noempty:true, eqeqeq:true,
|
||||
boss:true, bitwise:true, browser:true, devel:true, indent:2 */
|
||||
/* exported responsiveNav */
|
||||
|
||||
var responsiveNav = (function (window, document) {
|
||||
|
||||
var computed = !!window.getComputedStyle;
|
||||
|
||||
// getComputedStyle polyfill
|
||||
if (!window.getComputedStyle) {
|
||||
window.getComputedStyle = function(el) {
|
||||
this.el = el;
|
||||
this.getPropertyValue = function(prop) {
|
||||
var re = /(\-([a-z]){1})/g;
|
||||
if (prop === "float") {
|
||||
prop = "styleFloat";
|
||||
}
|
||||
if (re.test(prop)) {
|
||||
prop = prop.replace(re, function () {
|
||||
return arguments[2].toUpperCase();
|
||||
});
|
||||
}
|
||||
return el.currentStyle[prop] ? el.currentStyle[prop] : null;
|
||||
};
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
var nav,
|
||||
opts,
|
||||
navToggle,
|
||||
docEl = document.documentElement,
|
||||
head = document.getElementsByTagName("head")[0],
|
||||
styleElement = document.createElement("style"),
|
||||
navOpen = false,
|
||||
|
||||
// fn arg can be an object or a function, thanks to handleEvent
|
||||
// read more at: http://www.thecssninja.com/javascript/handleevent
|
||||
addEvent = function (el, evt, fn, bubble) {
|
||||
if ("addEventListener" in el) {
|
||||
// BBOS6 doesn't support handleEvent, catch and polyfill
|
||||
try {
|
||||
el.addEventListener(evt, fn, bubble);
|
||||
} catch (e) {
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.addEventListener(evt, function (e) {
|
||||
// Bind fn as this and set first arg as event object
|
||||
fn.handleEvent.call(fn, e);
|
||||
}, bubble);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else if ("attachEvent" in el) {
|
||||
// check if the callback is an object and contains handleEvent
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.attachEvent("on" + evt, function () {
|
||||
// Bind fn as this
|
||||
fn.handleEvent.call(fn);
|
||||
});
|
||||
} else {
|
||||
el.attachEvent("on" + evt, fn);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removeEvent = function (el, evt, fn, bubble) {
|
||||
if ("removeEventListener" in el) {
|
||||
try {
|
||||
el.removeEventListener(evt, fn, bubble);
|
||||
} catch (e) {
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.removeEventListener(evt, function (e) {
|
||||
fn.handleEvent.call(fn, e);
|
||||
}, bubble);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else if ("detachEvent" in el) {
|
||||
if (typeof fn === "object" && fn.handleEvent) {
|
||||
el.detachEvent("on" + evt, function () {
|
||||
fn.handleEvent.call(fn);
|
||||
});
|
||||
} else {
|
||||
el.detachEvent("on" + evt, fn);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getFirstChild = function (e) {
|
||||
var firstChild = e.firstChild;
|
||||
// skip TextNodes
|
||||
while (firstChild !== null && firstChild.nodeType !== 1) {
|
||||
firstChild = firstChild.nextSibling;
|
||||
}
|
||||
return firstChild;
|
||||
},
|
||||
|
||||
setAttributes = function (el, attrs) {
|
||||
for (var key in attrs) {
|
||||
el.setAttribute(key, attrs[key]);
|
||||
}
|
||||
},
|
||||
|
||||
addClass = function (el, cls) {
|
||||
el.className += " " + cls;
|
||||
el.className = el.className.replace(/(^\s*)|(\s*$)/g,"");
|
||||
},
|
||||
|
||||
removeClass = function (el, cls) {
|
||||
var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
|
||||
el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,"");
|
||||
},
|
||||
|
||||
ResponsiveNav = function (el, options) {
|
||||
var i;
|
||||
|
||||
// Default options
|
||||
this.options = {
|
||||
animate: true, // Boolean: Use CSS3 transitions, true or false
|
||||
transition: 400, // Integer: Speed of the transition, in milliseconds
|
||||
label: "Menu", // String: Label for the navigation toggle
|
||||
insert: "after", // String: Insert the toggle before or after the navigation
|
||||
customToggle: "", // Selector: Specify the ID of a custom toggle
|
||||
openPos: "relative", // String: Position of the opened nav, relative or static
|
||||
jsClass: "js", // String: 'JS enabled' class which is added to <html> el
|
||||
init: function(){}, // Function: Init callback
|
||||
open: function(){}, // Function: Open callback
|
||||
close: function(){} // Function: Close callback
|
||||
};
|
||||
|
||||
// User defined options
|
||||
for (i in options) {
|
||||
this.options[i] = options[i];
|
||||
}
|
||||
|
||||
// Adds "js" class for <html>
|
||||
addClass(docEl, this.options.jsClass);
|
||||
|
||||
// Wrapper
|
||||
this.wrapperEl = el.replace("#", "");
|
||||
if (document.getElementById(this.wrapperEl)) {
|
||||
this.wrapper = document.getElementById(this.wrapperEl);
|
||||
} else {
|
||||
// If el doesn't exists, stop here.
|
||||
throw new Error("The nav element you are trying to select doesn't exist");
|
||||
}
|
||||
|
||||
// Inner wrapper
|
||||
this.wrapper.inner = getFirstChild(this.wrapper);
|
||||
|
||||
// For minification
|
||||
opts = this.options;
|
||||
nav = this.wrapper;
|
||||
|
||||
// Init
|
||||
this._init(this);
|
||||
};
|
||||
|
||||
ResponsiveNav.prototype = {
|
||||
// Public methods
|
||||
destroy: function () {
|
||||
this._removeStyles();
|
||||
removeClass(nav, "closed");
|
||||
removeClass(nav, "opened");
|
||||
nav.removeAttribute("style");
|
||||
nav.removeAttribute("aria-hidden");
|
||||
nav = null;
|
||||
_instance = null;
|
||||
|
||||
removeEvent(window, "load", this, false);
|
||||
removeEvent(window, "resize", this, false);
|
||||
removeEvent(navToggle, "mousedown", this, false);
|
||||
removeEvent(navToggle, "touchstart", this, false);
|
||||
removeEvent(navToggle, "touchend", this, false);
|
||||
removeEvent(navToggle, "keyup", this, false);
|
||||
removeEvent(navToggle, "click", this, false);
|
||||
|
||||
if (!opts.customToggle) {
|
||||
navToggle.parentNode.removeChild(navToggle);
|
||||
} else {
|
||||
navToggle.removeAttribute("aria-hidden");
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
if (!navOpen) {
|
||||
removeClass(nav, "closed");
|
||||
addClass(nav, "opened");
|
||||
nav.style.position = opts.openPos;
|
||||
setAttributes(nav, {"aria-hidden": "false"});
|
||||
|
||||
navOpen = true;
|
||||
opts.open();
|
||||
} else {
|
||||
removeClass(nav, "opened");
|
||||
addClass(nav, "closed");
|
||||
setAttributes(nav, {"aria-hidden": "true"});
|
||||
|
||||
if (opts.animate) {
|
||||
setTimeout(function () {
|
||||
nav.style.position = "absolute";
|
||||
}, opts.transition + 10);
|
||||
} else {
|
||||
nav.style.position = "absolute";
|
||||
}
|
||||
|
||||
navOpen = false;
|
||||
opts.close();
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function (e) {
|
||||
var evt = e || window.event;
|
||||
|
||||
switch (evt.type) {
|
||||
case "mousedown":
|
||||
this._onmousedown(evt);
|
||||
break;
|
||||
case "touchstart":
|
||||
this._ontouchstart(evt);
|
||||
break;
|
||||
case "touchend":
|
||||
this._ontouchend(evt);
|
||||
break;
|
||||
case "keyup":
|
||||
this._onkeyup(evt);
|
||||
break;
|
||||
case "click":
|
||||
this._onclick(evt);
|
||||
break;
|
||||
case "load":
|
||||
this._transitions(evt);
|
||||
this._resize(evt);
|
||||
break;
|
||||
case "resize":
|
||||
this._resize(evt);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// Private methods
|
||||
_init: function () {
|
||||
addClass(nav, "closed");
|
||||
this._createToggle();
|
||||
|
||||
addEvent(window, "load", this, false);
|
||||
addEvent(window, "resize", this, false);
|
||||
addEvent(navToggle, "mousedown", this, false);
|
||||
addEvent(navToggle, "touchstart", this, false);
|
||||
addEvent(navToggle, "touchend", this, false);
|
||||
addEvent(navToggle, "keyup", this, false);
|
||||
addEvent(navToggle, "click", this, false);
|
||||
},
|
||||
|
||||
_createStyles: function () {
|
||||
if (!styleElement.parentNode) {
|
||||
head.appendChild(styleElement);
|
||||
}
|
||||
},
|
||||
|
||||
_removeStyles: function () {
|
||||
if (styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement);
|
||||
}
|
||||
},
|
||||
|
||||
_createToggle: function () {
|
||||
if (!opts.customToggle) {
|
||||
var toggle = document.createElement("a");
|
||||
toggle.innerHTML = opts.label;
|
||||
setAttributes(toggle, {
|
||||
"href": "#",
|
||||
"id": "nav-toggle"
|
||||
});
|
||||
|
||||
if (opts.insert === "after") {
|
||||
nav.parentNode.insertBefore(toggle, nav.nextSibling);
|
||||
} else {
|
||||
nav.parentNode.insertBefore(toggle, nav);
|
||||
}
|
||||
|
||||
navToggle = document.getElementById("nav-toggle");
|
||||
} else {
|
||||
var toggleEl = opts.customToggle.replace("#", "");
|
||||
|
||||
if (document.getElementById(toggleEl)) {
|
||||
navToggle = document.getElementById(toggleEl);
|
||||
} else {
|
||||
throw new Error("The custom nav toggle you are trying to select doesn't exist");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_preventDefault: function(e) {
|
||||
if (e.preventDefault) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
e.returnValue = false;
|
||||
}
|
||||
},
|
||||
|
||||
_onmousedown: function (e) {
|
||||
var evt = e || window.event;
|
||||
// If the user isn't right clicking:
|
||||
if (!(evt.which === 3 || evt.button === 2)) {
|
||||
this._preventDefault(e);
|
||||
this.toggle(e);
|
||||
}
|
||||
},
|
||||
|
||||
_ontouchstart: function (e) {
|
||||
// Touchstart event fires before
|
||||
// the mousedown and can wipe it
|
||||
navToggle.onmousedown = null;
|
||||
this._preventDefault(e);
|
||||
this.toggle(e);
|
||||
},
|
||||
|
||||
_ontouchend: function () {
|
||||
// Prevents ghost click from happening on some Android browsers
|
||||
var that = this;
|
||||
nav.addEventListener("click", that._preventDefault, true);
|
||||
setTimeout(function () {
|
||||
nav.removeEventListener("click", that._preventDefault, true);
|
||||
}, opts.transition);
|
||||
},
|
||||
|
||||
_onkeyup: function (e) {
|
||||
var evt = e || window.event;
|
||||
if (evt.keyCode === 13) {
|
||||
this.toggle(e);
|
||||
}
|
||||
},
|
||||
|
||||
_onclick: function (e) {
|
||||
// For older browsers (looking at IE)
|
||||
this._preventDefault(e);
|
||||
},
|
||||
|
||||
_transitions: function () {
|
||||
if (opts.animate) {
|
||||
var objStyle = nav.style,
|
||||
transition = "max-height " + opts.transition + "ms";
|
||||
|
||||
objStyle.WebkitTransition = transition;
|
||||
objStyle.MozTransition = transition;
|
||||
objStyle.OTransition = transition;
|
||||
objStyle.transition = transition;
|
||||
}
|
||||
},
|
||||
|
||||
_calcHeight: function () {
|
||||
var savedHeight = nav.inner.offsetHeight,
|
||||
innerStyles = "#" + this.wrapperEl + ".opened{max-height:" + savedHeight + "px}";
|
||||
|
||||
// Hide from old IE
|
||||
if (computed) {
|
||||
styleElement.innerHTML = innerStyles;
|
||||
innerStyles = "";
|
||||
}
|
||||
},
|
||||
|
||||
_resize: function () {
|
||||
if (window.getComputedStyle(navToggle, null).getPropertyValue("display") !== "none") {
|
||||
setAttributes(navToggle, {"aria-hidden": "false"});
|
||||
|
||||
// If the navigation is hidden
|
||||
if (nav.className.match(/(^|\s)closed(\s|$)/)) {
|
||||
setAttributes(nav, {"aria-hidden": "true"});
|
||||
nav.style.position = "absolute";
|
||||
}
|
||||
|
||||
this._createStyles();
|
||||
this._calcHeight();
|
||||
} else {
|
||||
setAttributes(navToggle, {"aria-hidden": "true"});
|
||||
setAttributes(nav, {"aria-hidden": "false"});
|
||||
nav.style.position = opts.openPos;
|
||||
this._removeStyles();
|
||||
}
|
||||
|
||||
// Init callback
|
||||
opts.init();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var _instance;
|
||||
function rn (el, options) {
|
||||
if (!_instance) {
|
||||
_instance = new ResponsiveNav(el, options);
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
return rn;
|
||||
})(window, document);
|
1
assets/js/scripts.min.js
vendored
Normal file
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 148 KiB |
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 173 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 38 KiB |