2015-10-01 16:00:26 +02:00
/ *
* Foundation Responsive Library
* http : //foundation.zurb.com
2018-02-09 03:02:47 +01:00
* Copyright 2015 , ZURB
2015-10-01 16:00:26 +02:00
* Free to use under the MIT license .
* http : //www.opensource.org/licenses/mit-license.php
* /
( function ( $ , window , document , undefined ) {
'use strict' ;
var header _helpers = function ( class _array ) {
var head = $ ( 'head' ) ;
2018-02-09 03:02:47 +01:00
head . prepend ( $ . map ( class _array , function ( class _name ) {
if ( head . has ( '.' + class _name ) . length === 0 ) {
return '<meta class="' + class _name + '" />' ;
2015-10-01 16:00:26 +02:00
}
2018-02-09 03:02:47 +01:00
} ) ) ;
2015-10-01 16:00:26 +02:00
} ;
header _helpers ( [
'foundation-mq-small' ,
'foundation-mq-small-only' ,
'foundation-mq-medium' ,
'foundation-mq-medium-only' ,
'foundation-mq-large' ,
'foundation-mq-large-only' ,
'foundation-mq-xlarge' ,
'foundation-mq-xlarge-only' ,
'foundation-mq-xxlarge' ,
'foundation-data-attribute-namespace' ] ) ;
// Enable FastClick if present
$ ( function ( ) {
if ( typeof FastClick !== 'undefined' ) {
// Don't attach to body if undefined
if ( typeof document . body !== 'undefined' ) {
FastClick . attach ( document . body ) ;
}
}
} ) ;
// private Fast Selector wrapper,
// returns jQuery object. Only use where
// getElementById is not available.
var S = function ( selector , context ) {
if ( typeof selector === 'string' ) {
if ( context ) {
var cont ;
if ( context . jquery ) {
cont = context [ 0 ] ;
if ( ! cont ) {
return context ;
}
} else {
cont = context ;
}
return $ ( cont . querySelectorAll ( selector ) ) ;
}
return $ ( document . querySelectorAll ( selector ) ) ;
}
return $ ( selector , context ) ;
} ;
// Namespace functions.
var attr _name = function ( init ) {
var arr = [ ] ;
if ( ! init ) {
arr . push ( 'data' ) ;
}
if ( this . namespace . length > 0 ) {
arr . push ( this . namespace ) ;
}
arr . push ( this . name ) ;
return arr . join ( '-' ) ;
} ;
var add _namespace = function ( str ) {
var parts = str . split ( '-' ) ,
i = parts . length ,
arr = [ ] ;
while ( i -- ) {
if ( i !== 0 ) {
arr . push ( parts [ i ] ) ;
} else {
if ( this . namespace . length > 0 ) {
arr . push ( this . namespace , parts [ i ] ) ;
} else {
arr . push ( parts [ i ] ) ;
}
}
}
return arr . reverse ( ) . join ( '-' ) ;
} ;
// Event binding and data-options updating.
var bindings = function ( method , options ) {
var self = this ,
bind = function ( ) {
var $this = S ( this ) ,
2018-02-15 18:42:07 +01:00
should _bind _events = ! S ( self ) . data ( self . attr _name ( true ) + '-init' ) ;
2015-10-01 16:00:26 +02:00
$this . data ( self . attr _name ( true ) + '-init' , $ . extend ( { } , self . settings , ( options || method ) , self . data _options ( $this ) ) ) ;
if ( should _bind _events ) {
self . events ( this ) ;
}
} ;
if ( S ( this . scope ) . is ( '[' + this . attr _name ( ) + ']' ) ) {
bind . call ( this . scope ) ;
} else {
S ( '[' + this . attr _name ( ) + ']' , this . scope ) . each ( bind ) ;
}
// # Patch to fix #5043 to move this *after* the if/else clause in order for Backbone and similar frameworks to have improved control over event binding and data-options updating.
if ( typeof method === 'string' ) {
return this [ method ] . call ( this , options ) ;
}
} ;
var single _image _loaded = function ( image , callback ) {
function loaded ( ) {
callback ( image [ 0 ] ) ;
}
function bindLoad ( ) {
this . one ( 'load' , loaded ) ;
if ( /MSIE (\d+\.\d+);/ . test ( navigator . userAgent ) ) {
var src = this . attr ( 'src' ) ,
param = src . match ( /\?/ ) ? '&' : '?' ;
param += 'random=' + ( new Date ( ) ) . getTime ( ) ;
this . attr ( 'src' , src + param ) ;
}
}
if ( ! image . attr ( 'src' ) ) {
loaded ( ) ;
return ;
}
if ( image [ 0 ] . complete || image [ 0 ] . readyState === 4 ) {
loaded ( ) ;
} else {
bindLoad . call ( image ) ;
}
} ;
/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
window . matchMedia || ( window . matchMedia = function ( ) {
"use strict" ;
// For browsers that support matchMedium api such as IE 9 and webkit
var styleMedia = ( window . styleMedia || window . media ) ;
// For those that don't support matchMedium
if ( ! styleMedia ) {
var style = document . createElement ( 'style' ) ,
script = document . getElementsByTagName ( 'script' ) [ 0 ] ,
info = null ;
style . type = 'text/css' ;
style . id = 'matchmediajs-test' ;
script . parentNode . insertBefore ( style , script ) ;
// 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
info = ( 'getComputedStyle' in window ) && window . getComputedStyle ( style , null ) || style . currentStyle ;
styleMedia = {
matchMedium : function ( media ) {
var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }' ;
// 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
if ( style . styleSheet ) {
style . styleSheet . cssText = text ;
} else {
style . textContent = text ;
}
// Test if media query is true or false
return info . width === '1px' ;
}
} ;
}
return function ( media ) {
return {
matches : styleMedia . matchMedium ( media || 'all' ) ,
media : media || 'all'
} ;
} ;
} ( ) ) ;
/ *
* jquery . requestAnimationFrame
* https : //github.com/gnarf37/jquery-requestAnimationFrame
* Requires jQuery 1.8 +
*
* Copyright ( c ) 2012 Corey Frang
* Licensed under the MIT license .
* /
( function ( jQuery ) {
// requestAnimationFrame polyfill adapted from Erik Möller
// fixes from Paul Irish and Tino Zijdel
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
var animating ,
lastTime = 0 ,
vendors = [ 'webkit' , 'moz' ] ,
requestAnimationFrame = window . requestAnimationFrame ,
cancelAnimationFrame = window . cancelAnimationFrame ,
jqueryFxAvailable = 'undefined' !== typeof jQuery . fx ;
for ( ; lastTime < vendors . length && ! requestAnimationFrame ; lastTime ++ ) {
requestAnimationFrame = window [ vendors [ lastTime ] + 'RequestAnimationFrame' ] ;
cancelAnimationFrame = cancelAnimationFrame ||
window [ vendors [ lastTime ] + 'CancelAnimationFrame' ] ||
window [ vendors [ lastTime ] + 'CancelRequestAnimationFrame' ] ;
}
function raf ( ) {
if ( animating ) {
requestAnimationFrame ( raf ) ;
if ( jqueryFxAvailable ) {
jQuery . fx . tick ( ) ;
}
}
}
if ( requestAnimationFrame ) {
// use rAF
window . requestAnimationFrame = requestAnimationFrame ;
window . cancelAnimationFrame = cancelAnimationFrame ;
if ( jqueryFxAvailable ) {
jQuery . fx . timer = function ( timer ) {
if ( timer ( ) && jQuery . timers . push ( timer ) && ! animating ) {
animating = true ;
raf ( ) ;
}
} ;
jQuery . fx . stop = function ( ) {
animating = false ;
} ;
}
} else {
// polyfill
window . requestAnimationFrame = function ( callback ) {
var currTime = new Date ( ) . getTime ( ) ,
timeToCall = Math . max ( 0 , 16 - ( currTime - lastTime ) ) ,
id = window . setTimeout ( function ( ) {
callback ( currTime + timeToCall ) ;
} , timeToCall ) ;
lastTime = currTime + timeToCall ;
return id ;
} ;
window . cancelAnimationFrame = function ( id ) {
clearTimeout ( id ) ;
} ;
}
} ( $ ) ) ;
function removeQuotes ( string ) {
if ( typeof string === 'string' || string instanceof String ) {
string = string . replace ( /^['\\/"]+|(;\s?})+|['\\/"]+$/g , '' ) ;
}
return string ;
}
2018-02-09 03:02:47 +01:00
function MediaQuery ( selector ) {
this . selector = selector ;
this . query = '' ;
}
MediaQuery . prototype . toString = function ( ) {
return this . query || ( this . query = S ( this . selector ) . css ( 'font-family' ) . replace ( /^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g , '' ) ) ;
} ;
2015-10-01 16:00:26 +02:00
window . Foundation = {
name : 'Foundation' ,
2018-02-15 18:42:07 +01:00
version : '{{VERSION}}' ,
2015-10-01 16:00:26 +02:00
media _queries : {
2018-02-09 03:02:47 +01:00
'small' : new MediaQuery ( '.foundation-mq-small' ) ,
'small-only' : new MediaQuery ( '.foundation-mq-small-only' ) ,
'medium' : new MediaQuery ( '.foundation-mq-medium' ) ,
'medium-only' : new MediaQuery ( '.foundation-mq-medium-only' ) ,
'large' : new MediaQuery ( '.foundation-mq-large' ) ,
'large-only' : new MediaQuery ( '.foundation-mq-large-only' ) ,
'xlarge' : new MediaQuery ( '.foundation-mq-xlarge' ) ,
'xlarge-only' : new MediaQuery ( '.foundation-mq-xlarge-only' ) ,
'xxlarge' : new MediaQuery ( '.foundation-mq-xxlarge' )
2015-10-01 16:00:26 +02:00
} ,
stylesheet : $ ( '<style></style>' ) . appendTo ( 'head' ) [ 0 ] . sheet ,
global : {
namespace : undefined
} ,
init : function ( scope , libraries , method , options , response ) {
var args = [ scope , method , options , response ] ,
responses = [ ] ;
// check RTL
this . rtl = /rtl/i . test ( S ( 'html' ) . attr ( 'dir' ) ) ;
// set foundation global scope
this . scope = scope || this . scope ;
this . set _namespace ( ) ;
if ( libraries && typeof libraries === 'string' && ! /reflow/i . test ( libraries ) ) {
if ( this . libs . hasOwnProperty ( libraries ) ) {
responses . push ( this . init _lib ( libraries , args ) ) ;
}
} else {
for ( var lib in this . libs ) {
responses . push ( this . init _lib ( lib , libraries ) ) ;
}
}
2018-02-15 18:42:07 +01:00
S ( window ) . on ( 'load' , function ( ) {
2015-10-01 16:00:26 +02:00
S ( window )
. trigger ( 'resize.fndtn.clearing' )
. trigger ( 'resize.fndtn.dropdown' )
. trigger ( 'resize.fndtn.equalizer' )
. trigger ( 'resize.fndtn.interchange' )
. trigger ( 'resize.fndtn.joyride' )
. trigger ( 'resize.fndtn.magellan' )
. trigger ( 'resize.fndtn.topbar' )
. trigger ( 'resize.fndtn.slider' ) ;
} ) ;
return scope ;
} ,
init _lib : function ( lib , args ) {
if ( this . libs . hasOwnProperty ( lib ) ) {
this . patch ( this . libs [ lib ] ) ;
if ( args && args . hasOwnProperty ( lib ) ) {
if ( typeof this . libs [ lib ] . settings !== 'undefined' ) {
$ . extend ( true , this . libs [ lib ] . settings , args [ lib ] ) ;
} else if ( typeof this . libs [ lib ] . defaults !== 'undefined' ) {
$ . extend ( true , this . libs [ lib ] . defaults , args [ lib ] ) ;
}
return this . libs [ lib ] . init . apply ( this . libs [ lib ] , [ this . scope , args [ lib ] ] ) ;
}
args = args instanceof Array ? args : new Array ( args ) ;
return this . libs [ lib ] . init . apply ( this . libs [ lib ] , args ) ;
}
return function ( ) { } ;
} ,
patch : function ( lib ) {
lib . scope = this . scope ;
lib . namespace = this . global . namespace ;
lib . rtl = this . rtl ;
lib [ 'data_options' ] = this . utils . data _options ;
lib [ 'attr_name' ] = attr _name ;
lib [ 'add_namespace' ] = add _namespace ;
lib [ 'bindings' ] = bindings ;
lib [ 'S' ] = this . utils . S ;
} ,
inherit : function ( scope , methods ) {
var methods _arr = methods . split ( ' ' ) ,
i = methods _arr . length ;
while ( i -- ) {
if ( this . utils . hasOwnProperty ( methods _arr [ i ] ) ) {
scope [ methods _arr [ i ] ] = this . utils [ methods _arr [ i ] ] ;
}
}
} ,
set _namespace : function ( ) {
// Description:
// Don't bother reading the namespace out of the meta tag
// if the namespace has been set globally in javascript
//
// Example:
// Foundation.global.namespace = 'my-namespace';
// or make it an empty string:
// Foundation.global.namespace = '';
//
//
// If the namespace has not been set (is undefined), try to read it out of the meta element.
// Otherwise use the globally defined namespace, even if it's empty ('')
var namespace = ( this . global . namespace === undefined ) ? $ ( '.foundation-data-attribute-namespace' ) . css ( 'font-family' ) : this . global . namespace ;
// Finally, if the namsepace is either undefined or false, set it to an empty string.
// Otherwise use the namespace value.
this . global . namespace = ( namespace === undefined || /false/i . test ( namespace ) ) ? '' : namespace ;
} ,
libs : { } ,
// methods that can be inherited in libraries
utils : {
// Description:
// Fast Selector wrapper returns jQuery object. Only use where getElementById
// is not available.
//
// Arguments:
// Selector (String): CSS selector describing the element(s) to be
// returned as a jQuery object.
//
// Scope (String): CSS selector describing the area to be searched. Default
// is document.
//
// Returns:
// Element (jQuery Object): jQuery object containing elements matching the
// selector within the scope.
S : S ,
// Description:
// Executes a function a max of once every n milliseconds
//
// Arguments:
// Func (Function): Function to be throttled.
//
// Delay (Integer): Function execution threshold in milliseconds.
//
// Returns:
// Lazy_function (Function): Function with throttling applied.
throttle : function ( func , delay ) {
var timer = null ;
return function ( ) {
var context = this , args = arguments ;
if ( timer == null ) {
timer = setTimeout ( function ( ) {
func . apply ( context , args ) ;
timer = null ;
} , delay ) ;
}
} ;
} ,
// Description:
// Executes a function when it stops being invoked for n seconds
// Modified version of _.debounce() http://underscorejs.org
//
// Arguments:
// Func (Function): Function to be debounced.
//
// Delay (Integer): Function execution threshold in milliseconds.
//
// Immediate (Bool): Whether the function should be called at the beginning
// of the delay instead of the end. Default is false.
//
// Returns:
// Lazy_function (Function): Function with debouncing applied.
debounce : function ( func , delay , immediate ) {
var timeout , result ;
return function ( ) {
var context = this , args = arguments ;
var later = function ( ) {
timeout = null ;
if ( ! immediate ) {
result = func . apply ( context , args ) ;
}
} ;
var callNow = immediate && ! timeout ;
clearTimeout ( timeout ) ;
timeout = setTimeout ( later , delay ) ;
if ( callNow ) {
result = func . apply ( context , args ) ;
}
return result ;
} ;
} ,
// Description:
// Parses data-options attribute
//
// Arguments:
// El (jQuery Object): Element to be parsed.
//
// Returns:
// Options (Javascript Object): Contents of the element's data-options
// attribute.
data _options : function ( el , data _attr _name ) {
data _attr _name = data _attr _name || 'options' ;
var opts = { } , ii , p , opts _arr ,
data _options = function ( el ) {
var namespace = Foundation . global . namespace ;
if ( namespace . length > 0 ) {
return el . data ( namespace + '-' + data _attr _name ) ;
}
return el . data ( data _attr _name ) ;
} ;
var cached _options = data _options ( el ) ;
if ( typeof cached _options === 'object' ) {
return cached _options ;
}
opts _arr = ( cached _options || ':' ) . split ( ';' ) ;
ii = opts _arr . length ;
function isNumber ( o ) {
return ! isNaN ( o - 0 ) && o !== null && o !== '' && o !== false && o !== true ;
}
function trim ( str ) {
if ( typeof str === 'string' ) {
return $ . trim ( str ) ;
}
return str ;
}
while ( ii -- ) {
p = opts _arr [ ii ] . split ( ':' ) ;
p = [ p [ 0 ] , p . slice ( 1 ) . join ( ':' ) ] ;
if ( /true/i . test ( p [ 1 ] ) ) {
p [ 1 ] = true ;
}
if ( /false/i . test ( p [ 1 ] ) ) {
p [ 1 ] = false ;
}
if ( isNumber ( p [ 1 ] ) ) {
if ( p [ 1 ] . indexOf ( '.' ) === - 1 ) {
p [ 1 ] = parseInt ( p [ 1 ] , 10 ) ;
} else {
p [ 1 ] = parseFloat ( p [ 1 ] ) ;
}
}
if ( p . length === 2 && p [ 0 ] . length > 0 ) {
opts [ trim ( p [ 0 ] ) ] = trim ( p [ 1 ] ) ;
}
}
return opts ;
} ,
// Description:
// Adds JS-recognizable media queries
//
// Arguments:
// Media (String): Key string for the media query to be stored as in
// Foundation.media_queries
//
// Class (String): Class name for the generated <meta> tag
register _media : function ( media , media _class ) {
if ( Foundation . media _queries [ media ] === undefined ) {
$ ( 'head' ) . append ( '<meta class="' + media _class + '"/>' ) ;
Foundation . media _queries [ media ] = removeQuotes ( $ ( '.' + media _class ) . css ( 'font-family' ) ) ;
}
} ,
// Description:
// Add custom CSS within a JS-defined media query
//
// Arguments:
// Rule (String): CSS rule to be appended to the document.
//
// Media (String): Optional media query string for the CSS rule to be
// nested under.
add _custom _rule : function ( rule , media ) {
if ( media === undefined && Foundation . stylesheet ) {
Foundation . stylesheet . insertRule ( rule , Foundation . stylesheet . cssRules . length ) ;
} else {
var query = Foundation . media _queries [ media ] ;
if ( query !== undefined ) {
Foundation . stylesheet . insertRule ( '@media ' +
Foundation . media _queries [ media ] + '{ ' + rule + ' }' , Foundation . stylesheet . cssRules . length ) ;
}
}
} ,
// Description:
// Performs a callback function when an image is fully loaded
//
// Arguments:
// Image (jQuery Object): Image(s) to check if loaded.
//
// Callback (Function): Function to execute when image is fully loaded.
image _loaded : function ( images , callback ) {
var self = this ,
unloaded = images . length ;
function pictures _has _height ( images ) {
var pictures _number = images . length ;
for ( var i = pictures _number - 1 ; i >= 0 ; i -- ) {
if ( images . attr ( 'height' ) === undefined ) {
return false ;
} ;
} ;
return true ;
}
if ( unloaded === 0 || pictures _has _height ( images ) ) {
callback ( images ) ;
}
images . each ( function ( ) {
single _image _loaded ( self . S ( this ) , function ( ) {
unloaded -= 1 ;
if ( unloaded === 0 ) {
callback ( images ) ;
}
} ) ;
} ) ;
} ,
// Description:
// Returns a random, alphanumeric string
//
// Arguments:
// Length (Integer): Length of string to be generated. Defaults to random
// integer.
//
// Returns:
// Rand (String): Pseudo-random, alphanumeric string.
random _str : function ( ) {
if ( ! this . fidx ) {
this . fidx = 0 ;
}
this . prefix = this . prefix || [ ( this . name || 'F' ) , ( + new Date ) . toString ( 36 ) ] . join ( '-' ) ;
return this . prefix + ( this . fidx ++ ) . toString ( 36 ) ;
} ,
// Description:
// Helper for window.matchMedia
//
// Arguments:
// mq (String): Media query
//
// Returns:
// (Boolean): Whether the media query passes or not
match : function ( mq ) {
return window . matchMedia ( mq ) . matches ;
} ,
// Description:
// Helpers for checking Foundation default media queries with JS
//
// Returns:
// (Boolean): Whether the media query passes or not
is _small _up : function ( ) {
return this . match ( Foundation . media _queries . small ) ;
} ,
is _medium _up : function ( ) {
return this . match ( Foundation . media _queries . medium ) ;
} ,
is _large _up : function ( ) {
return this . match ( Foundation . media _queries . large ) ;
} ,
is _xlarge _up : function ( ) {
return this . match ( Foundation . media _queries . xlarge ) ;
} ,
is _xxlarge _up : function ( ) {
return this . match ( Foundation . media _queries . xxlarge ) ;
} ,
is _small _only : function ( ) {
return ! this . is _medium _up ( ) && ! this . is _large _up ( ) && ! this . is _xlarge _up ( ) && ! this . is _xxlarge _up ( ) ;
} ,
is _medium _only : function ( ) {
return this . is _medium _up ( ) && ! this . is _large _up ( ) && ! this . is _xlarge _up ( ) && ! this . is _xxlarge _up ( ) ;
} ,
is _large _only : function ( ) {
return this . is _medium _up ( ) && this . is _large _up ( ) && ! this . is _xlarge _up ( ) && ! this . is _xxlarge _up ( ) ;
} ,
is _xlarge _only : function ( ) {
return this . is _medium _up ( ) && this . is _large _up ( ) && this . is _xlarge _up ( ) && ! this . is _xxlarge _up ( ) ;
} ,
is _xxlarge _only : function ( ) {
return this . is _medium _up ( ) && this . is _large _up ( ) && this . is _xlarge _up ( ) && this . is _xxlarge _up ( ) ;
}
}
} ;
$ . fn . foundation = function ( ) {
var args = Array . prototype . slice . call ( arguments , 0 ) ;
return this . each ( function ( ) {
Foundation . init . apply ( Foundation , [ this ] . concat ( args ) ) ;
return this ;
} ) ;
} ;
} ( jQuery , window , window . document ) ) ;