Conflicts:
	index.php
	mod/setup.php
This commit is contained in:
redmatrix 2015-05-24 15:50:05 -07:00
commit 851f2f64df
29 changed files with 19946 additions and 800 deletions

View File

@ -170,17 +170,12 @@ function comanche_block($s, $class = '') {
if($r) { if($r) {
$o .= (($var['wrap'] == 'none') ? '' : '<div class="' . $class . '">'); $o .= (($var['wrap'] == 'none') ? '' : '<div class="' . $class . '">');
if($r[0]['title'] && trim($r[0]['title']) != '$content') { if($r[0]['title'] && trim($r[0]['body']) != '$content') {
$o .= '<h3>' . $r[0]['title'] . '</h3>'; $o .= '<h3>' . $r[0]['title'] . '</h3>';
} }
if($r[0]['title'] && trim($r[0]['title']) === '$content' && get_app()->data['webpage'][0]['title']) {
$o .= '<h3>' . get_app()->data['webpage'][0]['title'] . '</h3>';
}
if(trim($r[0]['body']) === '$content') { if(trim($r[0]['body']) === '$content') {
$o .= prepare_text(get_app()->data['webpage'][0]['body'], get_app()->data['webpage'][0]['mimetype']); $o .= get_app()->page['content'];
} }
else { else {
$o .= prepare_text($r[0]['body'], $r[0]['mimetype']); $o .= prepare_text($r[0]['body'], $r[0]['mimetype']);
@ -202,9 +197,17 @@ function comanche_js($s) {
case 'bootstrap': case 'bootstrap':
$path = 'library/bootstrap/js/bootstrap.min.js'; $path = 'library/bootstrap/js/bootstrap.min.js';
break; break;
case 'foundation':
$path = 'library/foundation/js/foundation.min.js';
$init = "\r\n" . '<script>$(document).ready(function() { $(document).foundation(); });</script>';
break;
} }
return '<script src="' . z_root() . '/' . $path . '" ></script>'; $ret = '<script src="' . z_root() . '/' . $path . '" ></script>';
if($init)
$ret .= $init;
return $ret;
} }
@ -214,9 +217,14 @@ function comanche_css($s) {
case 'bootstrap': case 'bootstrap':
$path = 'library/bootstrap/css/bootstrap.min.css'; $path = 'library/bootstrap/css/bootstrap.min.css';
break; break;
case 'foundation':
$path = 'library/foundation/css/foundation.min.css';
break;
} }
return '<link rel="stylesheet" href="' . z_root() . '/' . $path . '" type="text/css" media="screen">'; $ret = '<link rel="stylesheet" href="' . z_root() . '/' . $path . '" type="text/css" media="screen">';
return $ret;
} }

View File

@ -425,10 +425,13 @@ function local_dir_update($uid, $force) {
); );
} }
$arr = array('channel_id' => $uid, 'hash' => $hash, 'profile' => $profile);
call_hooks('local_dir_update', $arr);
$address = $p[0]['channel_address'] . '@' . get_app()->get_hostname(); $address = $p[0]['channel_address'] . '@' . get_app()->get_hostname();
if (perm_is_allowed($uid, '', 'view_profile')) { if (perm_is_allowed($uid, '', 'view_profile')) {
import_directory_profile($hash, $profile, $address, 0); import_directory_profile($hash, $arr['profile'], $address, 0);
} else { } else {
// they may have made it private // they may have made it private
$r = q("delete from xprof where xprof_hash = '%s'", $r = q("delete from xprof where xprof_hash = '%s'",

View File

@ -954,7 +954,7 @@ function import_author_diaspora($x) {
); );
if($r) { if($r) {
logger('in_cache: ' . $x['address'], LOGGER_DATA); logger('in_cache: ' . $x['address'], LOGGER_DATA);
return $r[0]['chan_hash']; return $r[0]['xchan_hash'];
} }
if(discover_by_webbie($x['address'])) { if(discover_by_webbie($x['address'])) {
@ -4349,8 +4349,6 @@ function zot_feed($uid,$observer_hash,$arr) {
$mindate = null; $mindate = null;
$message_id = null; $message_id = null;
require_once('include/security.php');
if(array_key_exists('mindate',$arr)) { if(array_key_exists('mindate',$arr)) {
$mindate = datetime_convert('UTC','UTC',$arr['mindate']); $mindate = datetime_convert('UTC','UTC',$arr['mindate']);
} }
@ -4364,7 +4362,7 @@ function zot_feed($uid,$observer_hash,$arr) {
$mindate = dbesc($mindate); $mindate = dbesc($mindate);
logger('zot_feed: requested for uid ' . $uid . ' from observer ' . $observer_xchan, LOGGER_DEBUG); logger('zot_feed: requested for uid ' . $uid . ' from observer ' . $observer_hash, LOGGER_DEBUG);
if($message_id) if($message_id)
logger('message_id: ' . $message_id,LOGGER_DEBUG); logger('message_id: ' . $message_id,LOGGER_DEBUG);

View File

@ -75,12 +75,12 @@ class FKOAuthDataStore extends OAuthDataStore {
$k = $consumer; $k = $consumer;
} }
$r = q("INSERT INTO tokens (id, secret, client_id, scope, expires) VALUES ('%s','%s','%s','%s', UNIX_TIMESTAMP()+%d)", $r = q("INSERT INTO tokens (id, secret, client_id, scope, expires) VALUES ('%s','%s','%s','%s', %d)",
dbesc($key), dbesc($key),
dbesc($sec), dbesc($sec),
dbesc($k), dbesc($k),
'request', 'request',
intval(REQUEST_TOKEN_DURATION)); time()+intval(REQUEST_TOKEN_DURATION));
if (!$r) return null; if (!$r) return null;
return new OAuthToken($key,$sec); return new OAuthToken($key,$sec);
@ -104,12 +104,12 @@ class FKOAuthDataStore extends OAuthDataStore {
$key = $this->gen_token(); $key = $this->gen_token();
$sec = $this->gen_token(); $sec = $this->gen_token();
$r = q("INSERT INTO tokens (id, secret, client_id, scope, expires, uid) VALUES ('%s','%s','%s','%s', UNIX_TIMESTAMP()+%d, %d)", $r = q("INSERT INTO tokens (id, secret, client_id, scope, expires, uid) VALUES ('%s','%s','%s','%s', %d, %d)",
dbesc($key), dbesc($key),
dbesc($sec), dbesc($sec),
dbesc($consumer->key), dbesc($consumer->key),
'access', 'access',
intval(ACCESS_TOKEN_DURATION), time()+intval(ACCESS_TOKEN_DURATION),
intval($uverifier)); intval($uverifier));
if ($r) if ($r)

127
index.php
View File

@ -1,47 +1,42 @@
<?php /** @file */ <?php
/** /**
* @file index.php
* *
* Hubzilla * @brief The main entry point to the application.
* *
* Bootstrap the application, load configuration, load modules, load theme, etc.
*/ */
/** /*
*
* bootstrap the application * bootstrap the application
*
*/ */
require_once('boot.php'); require_once('boot.php');
// our global App object
$a = new App; $a = new App;
/** /*
*
* Load the configuration file which contains our DB credentials. * Load the configuration file which contains our DB credentials.
* Ignore errors. If the file doesn't exist or is empty, we are running in installation mode.' * Ignore errors. If the file doesn't exist or is empty, we are running in
* * installation mode.
*/ */
$a->install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false : true); $a->install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false : true);
@include(".htconfig.php"); @include('.htconfig.php');
$a->timezone = ((x($default_timezone)) ? $default_timezone : 'UTC'); $a->timezone = ((x($default_timezone)) ? $default_timezone : 'UTC');
date_default_timezone_set($a->timezone); date_default_timezone_set($a->timezone);
/** /*
*
* Try to open the database; * Try to open the database;
*
*/ */
require_once("include/dba/dba_driver.php"); require_once('include/dba/dba_driver.php');
if(! $a->install) { if(! $a->install) {
$db = dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type, $a->install); $db = dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type, $a->install);
unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type); unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type);
/** /**
* Load configs from db. Overwrite configs from .htconfig.php * Load configs from db. Overwrite configs from .htconfig.php
@ -51,10 +46,10 @@ if(! $a->install) {
load_config('system'); load_config('system');
load_config('feature'); load_config('feature');
require_once("include/session.php"); require_once('include/session.php');
load_hooks(); load_hooks();
call_hooks('init_1'); call_hooks('init_1');
$a->language = get_best_language(); $a->language = get_best_language();
load_translation_table($a->language); load_translation_table($a->language);
// Force the cookie to be secure (https only) if this site is SSL enabled. Must be done before session_start(). // Force the cookie to be secure (https only) if this site is SSL enabled. Must be done before session_start().
@ -82,7 +77,7 @@ else {
* *
* The order of these may be important so use caution if you think they're all * The order of these may be important so use caution if you think they're all
* intertwingled with no logical order and decide to sort it out. Some of the * intertwingled with no logical order and decide to sort it out. Some of the
* dependencies have changed, but at least at one time in the recent past - the * dependencies have changed, but at least at one time in the recent past - the
* order was critical to everything working properly * order was critical to everything working properly
* *
*/ */
@ -100,7 +95,7 @@ if(array_key_exists('system_language',$_POST)) {
else else
unset($_SESSION['language']); unset($_SESSION['language']);
} }
if((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) { if((x($_SESSION, 'language')) && ($_SESSION['language'] !== $lang)) {
$a->language = $_SESSION['language']; $a->language = $_SESSION['language'];
load_translation_table($a->language); load_translation_table($a->language);
} }
@ -113,20 +108,19 @@ if((x($_GET,'zid')) && (! $a->install)) {
} }
} }
if((x($_SESSION,'authenticated')) || (x($_POST,'auth-params')) || ($a->module === 'login')) if((x($_SESSION, 'authenticated')) || (x($_POST, 'auth-params')) || ($a->module === 'login'))
require("include/auth.php"); require('include/auth.php');
if(! x($_SESSION, 'sysmsg'))
if(! x($_SESSION,'sysmsg'))
$_SESSION['sysmsg'] = array(); $_SESSION['sysmsg'] = array();
if(! x($_SESSION,'sysmsg_info')) if(! x($_SESSION, 'sysmsg_info'))
$_SESSION['sysmsg_info'] = array(); $_SESSION['sysmsg_info'] = array();
/* /*
* check_config() is responsible for running update scripts. These automatically * check_config() is responsible for running update scripts. These automatically
* update the DB schema whenever we push a new one out. It also checks to see if * update the DB schema whenever we push a new one out. It also checks to see if
* any plugins have been added or removed and reacts accordingly. * any plugins have been added or removed and reacts accordingly.
*/ */
@ -154,23 +148,22 @@ $a->set_apps($arr['app_menu']);
* and use it for handling our URL request. * and use it for handling our URL request.
* The module file contains a few functions that we call in various circumstances * The module file contains a few functions that we call in various circumstances
* and in the following order: * and in the following order:
* *
* "module"_init * "module"_init
* "module"_post (only called if there are $_POST variables) * "module"_post (only called if there are $_POST variables)
* "module"_aside * "module"_aside
* $theme_$module_aside (and $extends_$module_aside) are run first if either exist * $theme_$module_aside (and $extends_$module_aside) are run first if either exist
* if either of these return false, module_aside is not called * if either of these return false, module_aside is not called
* This allows a theme to over-ride the sidebar layout completely. * This allows a theme to over-ride the sidebar layout completely.
* "module"_content - the string return of this function contains our page body * "module"_content - the string return of this function contains our page body
* *
* Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do * Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do
* so within the module init and/or post functions and then invoke killme() to terminate * so within the module init and/or post functions and then invoke killme() to terminate
* further processing. * further processing.
*/ */
if(strlen($a->module)) { if(strlen($a->module)) {
/** /**
* *
* We will always have a module name. * We will always have a module name.
@ -184,7 +177,6 @@ if(strlen($a->module)) {
$a->module_loaded = true; $a->module_loaded = true;
} }
if((strpos($a->module,'admin') === 0) && (! is_site_admin())) { if((strpos($a->module,'admin') === 0) && (! is_site_admin())) {
$a->module_loaded = false; $a->module_loaded = false;
notice( t('Permission denied.') . EOL); notice( t('Permission denied.') . EOL);
@ -197,7 +189,6 @@ if(strlen($a->module)) {
*/ */
if(! $a->module_loaded) { if(! $a->module_loaded) {
if(file_exists("mod/site/{$a->module}.php")) { if(file_exists("mod/site/{$a->module}.php")) {
include_once("mod/site/{$a->module}.php"); include_once("mod/site/{$a->module}.php");
$a->module_loaded = true; $a->module_loaded = true;
@ -210,37 +201,36 @@ if(strlen($a->module)) {
/** /**
*
* The URL provided does not resolve to a valid module. * The URL provided does not resolve to a valid module.
* *
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'. * On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
* We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic - * We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
* we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page * we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
* this will often succeed and eventually do the right thing. * this will often succeed and eventually do the right thing.
* *
* Otherwise we are going to emit a 404 not found. * Otherwise we are going to emit a 404 not found.
*
*/ */
if(! $a->module_loaded) { if(! $a->module_loaded) {
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit. // Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
if((x($_SERVER,'QUERY_STRING')) && preg_match('/{[0-9]}/',$_SERVER['QUERY_STRING']) !== 0) { if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
killme(); killme();
} }
if((x($_SERVER,'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) { if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']); logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
goaway($a->get_baseurl() . $_SERVER['REQUEST_URI']); goaway($a->get_baseurl() . $_SERVER['REQUEST_URI']);
} }
logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG); logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG);
header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . t('Not Found')); header($_SERVER['SERVER_PROTOCOL'] . ' 404 ' . t('Not Found'));
$tpl = get_markup_template("404.tpl"); $tpl = get_markup_template('404.tpl');
$a->page['content'] = replace_macros($tpl, array( $a->page['content'] = replace_macros($tpl, array(
'$message' => t('Page not found.' ) '$message' => t('Page not found.')
)); ));
// pretend this is a module so it will initialise the theme.
// pretend this is a module so it will initialise the theme
$a->module = '404'; $a->module = '404';
$a->module_loaded = true; $a->module_loaded = true;
} }
@ -249,11 +239,10 @@ if(strlen($a->module)) {
/* initialise content region */ /* initialise content region */
if(! x($a->page,'content')) if(! x($a->page, 'content'))
$a->page['content'] = ''; $a->page['content'] = '';
if(! ($a->module === 'setup')) { if(! ($a->module === 'setup')) {
/* set JS cookie */ /* set JS cookie */
if($_COOKIE['jsAvailable'] != 1) { if($_COOKIE['jsAvailable'] != 1) {
@ -263,9 +252,9 @@ if(! ($a->module === 'setup')) {
$_COOKIE['jsAvailable'] = 1; $_COOKIE['jsAvailable'] = 1;
} }
} }
call_hooks('page_content_top',$a->page['content']);
}
call_hooks('page_content_top', $a->page['content']);
}
@ -282,7 +271,7 @@ if($a->module_loaded) {
* For this reason, please restrict the use of templates to those which * For this reason, please restrict the use of templates to those which
* do not provide any presentation details - as themes will not be able * do not provide any presentation details - as themes will not be able
* to over-ride them. * to over-ride them.
*/ */
if(function_exists($a->module . '_init')) { if(function_exists($a->module . '_init')) {
call_hooks($a->module . '_mod_init', $placeholder); call_hooks($a->module . '_mod_init', $placeholder);
@ -310,32 +299,31 @@ if($a->module_loaded) {
* load current theme info * load current theme info
*/ */
$theme_info_file = "view/theme/".current_theme()."/php/theme.php"; $theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php';
if (file_exists($theme_info_file)){ if (file_exists($theme_info_file)){
require_once($theme_info_file); require_once($theme_info_file);
} }
if(function_exists(str_replace('-','_',current_theme()) . '_init')) { if(function_exists(str_replace('-', '_', current_theme()) . '_init')) {
$func = str_replace('-','_',current_theme()) . '_init'; $func = str_replace('-', '_', current_theme()) . '_init';
$func($a); $func($a);
} }
elseif (x($a->theme_info,"extends") && file_exists("view/theme/".$a->theme_info["extends"]."/php/theme.php")) { elseif (x($a->theme_info, 'extends') && file_exists('view/theme/' . $a->theme_info['extends'] . '/php/theme.php')) {
require_once("view/theme/".$a->theme_info["extends"]."/php/theme.php"); require_once('view/theme/' . $a->theme_info['extends'] . '/php/theme.php');
if(function_exists(str_replace('-','_',$a->theme_info["extends"]) . '_init')) { if(function_exists(str_replace('-', '_', $a->theme_info['extends']) . '_init')) {
$func = str_replace('-','_',$a->theme_info["extends"]) . '_init'; $func = str_replace('-', '_', $a->theme_info['extends']) . '_init';
$func($a); $func($a);
} }
} }
if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error) if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error)
&& (function_exists($a->module . '_post')) && (function_exists($a->module . '_post'))
&& (! x($_POST,'auth-params'))) { && (! x($_POST, 'auth-params'))) {
call_hooks($a->module . '_mod_post', $_POST); call_hooks($a->module . '_mod_post', $_POST);
$func = $a->module . '_post'; $func = $a->module . '_post';
$func($a); $func($a);
} }
if(! $a->error) { if(! $a->error) {
// If a theme has defined an _aside() function, run that first // If a theme has defined an _aside() function, run that first
// //
@ -353,9 +341,9 @@ if($a->module_loaded) {
$func = str_replace('-','_',current_theme()) . '_' . $a->module . '_aside'; $func = str_replace('-','_',current_theme()) . '_' . $a->module . '_aside';
$aside_default = $func($a); $aside_default = $func($a);
} }
elseif($aside_default && x($a->theme_info,"extends") elseif($aside_default && x($a->theme_info, "extends")
&& (function_exists(str_replace('-','_',$a->theme_info["extends"]) . '_' . $a->module . '_aside'))) { && (function_exists(str_replace('-', '_',$a->theme_info["extends"]) . '_' . $a->module . '_aside'))) {
$func = str_replace('-','_',$a->theme_info["extends"]) . '_' . $a->module . '_aside'; $func = str_replace('-', '_', $a->theme_info["extends"]) . '_' . $a->module . '_aside';
$aside_default = $func($a); $aside_default = $func($a);
} }
if($aside_default && function_exists($a->module . '_aside')) { if($aside_default && function_exists($a->module . '_aside')) {
@ -373,24 +361,25 @@ if($a->module_loaded) {
call_hooks($a->module . '_mod_aftercontent', $arr); call_hooks($a->module . '_mod_aftercontent', $arr);
$a->page['content'] .= $arr['content']; $a->page['content'] .= $arr['content'];
} }
} }
// If you're just visiting, let javascript take you home // If you're just visiting, let javascript take you home
if(x($_SESSION,'visitor_home')) if(x($_SESSION, 'visitor_home')) {
$homebase = $_SESSION['visitor_home']; $homebase = $_SESSION['visitor_home'];
elseif(local_channel()) } elseif(local_channel()) {
$homebase = $a->get_baseurl() . '/channel/' . $a->channel['channel_address']; $homebase = $a->get_baseurl() . '/channel/' . $a->channel['channel_address'];
}
if(isset($homebase)) if(isset($homebase)) {
$a->page['content'] .= '<script>var homebase="' . $homebase . '" ; </script>'; $a->page['content'] .= '<script>var homebase = "' . $homebase . '";</script>';
}
// now that we've been through the module content, see if the page reported // now that we've been through the module content, see if the page reported
// a permission problem and if so, a 403 response would seem to be in order. // a permission problem and if so, a 403 response would seem to be in order.
if(stristr( implode("",$_SESSION['sysmsg']), t('Permission denied'))) { if(stristr(implode("", $_SESSION['sysmsg']), t('Permission denied'))) {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 ' . t('Permission denied.')); header($_SERVER['SERVER_PROTOCOL'] . ' 403 ' . t('Permission denied.'));
} }

6324
library/foundation/css/foundation.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

6376
library/foundation/js/foundation.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,408 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.abide = {
name : 'abide',
version : '5.5.2',
settings : {
live_validate : true,
validate_on_blur : true,
// validate_on: 'tab', // tab (when user tabs between fields), change (input changes), manual (call custom events)
focus_on_invalid : true,
error_labels : true, // labels with a for="inputId" will recieve an `error` class
error_class : 'error',
timeout : 1000,
patterns : {
alpha : /^[a-zA-Z]+$/,
alpha_numeric : /^[a-zA-Z0-9]+$/,
integer : /^[-+]?\d+$/,
number : /^[-+]?\d*(?:[\.\,]\d+)?$/,
// amex, visa, diners
card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
cvv : /^([0-9]){3,4}$/,
// http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,
// http://blogs.lse.ac.uk/lti/2008/04/23/a-regular-expression-to-match-any-url/
url: /^(https?|ftp|file|ssh):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+~%\/\.\w]+)?\??([-\+=&;%@\.\w]+)?#?([\w]+)?)?/,
// abc.de
domain : /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/,
datetime : /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/,
// YYYY-MM-DD
date : /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/,
// HH:MM:SS
time : /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/,
dateISO : /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/,
// MM/DD/YYYY
month_day_year : /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/,
// DD/MM/YYYY
day_month_year : /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/,
// #FFF or #FFFFFF
color : /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
},
validators : {
equalTo : function (el, required, parent) {
var from = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value,
to = el.value,
valid = (from === to);
return valid;
}
}
},
timer : null,
init : function (scope, method, options) {
this.bindings(method, options);
},
events : function (scope) {
var self = this,
form = self.S(scope).attr('novalidate', 'novalidate'),
settings = form.data(this.attr_name(true) + '-init') || {};
this.invalid_attr = this.add_namespace('data-invalid');
function validate(originalSelf, e) {
clearTimeout(self.timer);
self.timer = setTimeout(function () {
self.validate([originalSelf], e);
}.bind(originalSelf), settings.timeout);
}
form
.off('.abide')
.on('submit.fndtn.abide', function (e) {
var is_ajax = /ajax/i.test(self.S(this).attr(self.attr_name()));
return self.validate(self.S(this).find('input, textarea, select').not(":hidden, [data-abide-ignore]").get(), e, is_ajax);
})
.on('validate.fndtn.abide', function (e) {
if (settings.validate_on === 'manual') {
self.validate([e.target], e);
}
})
.on('reset', function (e) {
return self.reset($(this), e);
})
.find('input, textarea, select').not(":hidden, [data-abide-ignore]")
.off('.abide')
.on('blur.fndtn.abide change.fndtn.abide', function (e) {
// old settings fallback
// will be deprecated with F6 release
if (settings.validate_on_blur && settings.validate_on_blur === true) {
validate(this, e);
}
// new settings combining validate options into one setting
if (settings.validate_on === 'change') {
validate(this, e);
}
})
.on('keydown.fndtn.abide', function (e) {
// old settings fallback
// will be deprecated with F6 release
if (settings.live_validate && settings.live_validate === true && e.which != 9) {
validate(this, e);
}
// new settings combining validate options into one setting
if (settings.validate_on === 'tab' && e.which === 9) {
validate(this, e);
}
else if (settings.validate_on === 'change') {
validate(this, e);
}
})
.on('focus', function (e) {
if (navigator.userAgent.match(/iPad|iPhone|Android|BlackBerry|Windows Phone|webOS/i)) {
$('html, body').animate({
scrollTop: $(e.target).offset().top
}, 100);
}
});
},
reset : function (form, e) {
var self = this;
form.removeAttr(self.invalid_attr);
$('[' + self.invalid_attr + ']', form).removeAttr(self.invalid_attr);
$('.' + self.settings.error_class, form).not('small').removeClass(self.settings.error_class);
$(':input', form).not(':button, :submit, :reset, :hidden, [data-abide-ignore]').val('').removeAttr(self.invalid_attr);
},
validate : function (els, e, is_ajax) {
var validations = this.parse_patterns(els),
validation_count = validations.length,
form = this.S(els[0]).closest('form'),
submit_event = /submit/.test(e.type);
// Has to count up to make sure the focus gets applied to the top error
for (var i = 0; i < validation_count; i++) {
if (!validations[i] && (submit_event || is_ajax)) {
if (this.settings.focus_on_invalid) {
els[i].focus();
}
form.trigger('invalid.fndtn.abide');
this.S(els[i]).closest('form').attr(this.invalid_attr, '');
return false;
}
}
if (submit_event || is_ajax) {
form.trigger('valid.fndtn.abide');
}
form.removeAttr(this.invalid_attr);
if (is_ajax) {
return false;
}
return true;
},
parse_patterns : function (els) {
var i = els.length,
el_patterns = [];
while (i--) {
el_patterns.push(this.pattern(els[i]));
}
return this.check_validation_and_apply_styles(el_patterns);
},
pattern : function (el) {
var type = el.getAttribute('type'),
required = typeof el.getAttribute('required') === 'string';
var pattern = el.getAttribute('pattern') || '';
if (this.settings.patterns.hasOwnProperty(pattern) && pattern.length > 0) {
return [el, this.settings.patterns[pattern], required];
} else if (pattern.length > 0) {
return [el, new RegExp(pattern), required];
}
if (this.settings.patterns.hasOwnProperty(type)) {
return [el, this.settings.patterns[type], required];
}
pattern = /.*/;
return [el, pattern, required];
},
// TODO: Break this up into smaller methods, getting hard to read.
check_validation_and_apply_styles : function (el_patterns) {
var i = el_patterns.length,
validations = [],
form = this.S(el_patterns[0][0]).closest('[data-' + this.attr_name(true) + ']'),
settings = form.data(this.attr_name(true) + '-init') || {};
while (i--) {
var el = el_patterns[i][0],
required = el_patterns[i][2],
value = el.value.trim(),
direct_parent = this.S(el).parent(),
validator = el.getAttribute(this.add_namespace('data-abide-validator')),
is_radio = el.type === 'radio',
is_checkbox = el.type === 'checkbox',
label = this.S('label[for="' + el.getAttribute('id') + '"]'),
valid_length = (required) ? (el.value.length > 0) : true,
el_validations = [];
var parent, valid;
// support old way to do equalTo validations
if (el.getAttribute(this.add_namespace('data-equalto'))) { validator = 'equalTo' }
if (!direct_parent.is('label')) {
parent = direct_parent;
} else {
parent = direct_parent.parent();
}
if (is_radio && required) {
el_validations.push(this.valid_radio(el, required));
} else if (is_checkbox && required) {
el_validations.push(this.valid_checkbox(el, required));
} else if (validator) {
// Validate using each of the specified (space-delimited) validators.
var validators = validator.split(' ');
var last_valid = true, all_valid = true;
for (var iv = 0; iv < validators.length; iv++) {
valid = this.settings.validators[validators[iv]].apply(this, [el, required, parent])
el_validations.push(valid);
all_valid = valid && last_valid;
last_valid = valid;
}
if (all_valid) {
this.S(el).removeAttr(this.invalid_attr);
parent.removeClass('error');
if (label.length > 0 && this.settings.error_labels) {
label.removeClass(this.settings.error_class).removeAttr('role');
}
$(el).triggerHandler('valid');
} else {
this.S(el).attr(this.invalid_attr, '');
parent.addClass('error');
if (label.length > 0 && this.settings.error_labels) {
label.addClass(this.settings.error_class).attr('role', 'alert');
}
$(el).triggerHandler('invalid');
}
} else {
if (el_patterns[i][1].test(value) && valid_length ||
!required && el.value.length < 1 || $(el).attr('disabled')) {
el_validations.push(true);
} else {
el_validations.push(false);
}
el_validations = [el_validations.every(function (valid) {return valid;})];
if (el_validations[0]) {
this.S(el).removeAttr(this.invalid_attr);
el.setAttribute('aria-invalid', 'false');
el.removeAttribute('aria-describedby');
parent.removeClass(this.settings.error_class);
if (label.length > 0 && this.settings.error_labels) {
label.removeClass(this.settings.error_class).removeAttr('role');
}
$(el).triggerHandler('valid');
} else {
this.S(el).attr(this.invalid_attr, '');
el.setAttribute('aria-invalid', 'true');
// Try to find the error associated with the input
var errorElem = parent.find('small.' + this.settings.error_class, 'span.' + this.settings.error_class);
var errorID = errorElem.length > 0 ? errorElem[0].id : '';
if (errorID.length > 0) {
el.setAttribute('aria-describedby', errorID);
}
// el.setAttribute('aria-describedby', $(el).find('.error')[0].id);
parent.addClass(this.settings.error_class);
if (label.length > 0 && this.settings.error_labels) {
label.addClass(this.settings.error_class).attr('role', 'alert');
}
$(el).triggerHandler('invalid');
}
}
validations = validations.concat(el_validations);
}
return validations;
},
valid_checkbox : function (el, required) {
var el = this.S(el),
valid = (el.is(':checked') || !required || el.get(0).getAttribute('disabled'));
if (valid) {
el.removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class);
$(el).triggerHandler('valid');
} else {
el.attr(this.invalid_attr, '').parent().addClass(this.settings.error_class);
$(el).triggerHandler('invalid');
}
return valid;
},
valid_radio : function (el, required) {
var name = el.getAttribute('name'),
group = this.S(el).closest('[data-' + this.attr_name(true) + ']').find("[name='" + name + "']"),
count = group.length,
valid = false,
disabled = false;
// Has to count up to make sure the focus gets applied to the top error
for (var i=0; i < count; i++) {
if( group[i].getAttribute('disabled') ){
disabled=true;
valid=true;
} else {
if (group[i].checked){
valid = true;
} else {
if( disabled ){
valid = false;
}
}
}
}
// Has to count up to make sure the focus gets applied to the top error
for (var i = 0; i < count; i++) {
if (valid) {
this.S(group[i]).removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class);
$(group[i]).triggerHandler('valid');
} else {
this.S(group[i]).attr(this.invalid_attr, '').parent().addClass(this.settings.error_class);
$(group[i]).triggerHandler('invalid');
}
}
return valid;
},
valid_equal : function (el, required, parent) {
var from = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value,
to = el.value,
valid = (from === to);
if (valid) {
this.S(el).removeAttr(this.invalid_attr);
parent.removeClass(this.settings.error_class);
if (label.length > 0 && settings.error_labels) {
label.removeClass(this.settings.error_class);
}
} else {
this.S(el).attr(this.invalid_attr, '');
parent.addClass(this.settings.error_class);
if (label.length > 0 && settings.error_labels) {
label.addClass(this.settings.error_class);
}
}
return valid;
},
valid_oneof : function (el, required, parent, doNotValidateOthers) {
var el = this.S(el),
others = this.S('[' + this.add_namespace('data-oneof') + ']'),
valid = others.filter(':checked').length > 0;
if (valid) {
el.removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class);
} else {
el.attr(this.invalid_attr, '').parent().addClass(this.settings.error_class);
}
if (!doNotValidateOthers) {
var _this = this;
others.each(function () {
_this.valid_oneof.call(_this, this, null, null, true);
});
}
return valid;
},
reflow : function(scope, options) {
var self = this,
form = self.S('[' + this.attr_name() + ']').attr('novalidate', 'novalidate');
self.S(form).each(function (idx, el) {
self.events(el);
});
}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,88 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.accordion = {
name : 'accordion',
version : '5.5.2',
settings : {
content_class : 'content',
active_class : 'active',
multi_expand : false,
toggleable : true,
callback : function () {}
},
init : function (scope, method, options) {
this.bindings(method, options);
},
events : function (instance) {
var self = this;
var S = this.S;
self.create(this.S(instance));
S(this.scope)
.off('.fndtn.accordion')
.on('click.fndtn.accordion', '[' + this.attr_name() + '] > dd > a, [' + this.attr_name() + '] > li > a', function (e) {
var accordion = S(this).closest('[' + self.attr_name() + ']'),
groupSelector = self.attr_name() + '=' + accordion.attr(self.attr_name()),
settings = accordion.data(self.attr_name(true) + '-init') || self.settings,
target = S('#' + this.href.split('#')[1]),
aunts = $('> dd, > li', accordion),
siblings = aunts.children('.' + settings.content_class),
active_content = siblings.filter('.' + settings.active_class);
e.preventDefault();
if (accordion.attr(self.attr_name())) {
siblings = siblings.add('[' + groupSelector + '] dd > ' + '.' + settings.content_class + ', [' + groupSelector + '] li > ' + '.' + settings.content_class);
aunts = aunts.add('[' + groupSelector + '] dd, [' + groupSelector + '] li');
}
if (settings.toggleable && target.is(active_content)) {
target.parent('dd, li').toggleClass(settings.active_class, false);
target.toggleClass(settings.active_class, false);
S(this).attr('aria-expanded', function(i, attr){
return attr === 'true' ? 'false' : 'true';
});
settings.callback(target);
target.triggerHandler('toggled', [accordion]);
accordion.triggerHandler('toggled', [target]);
return;
}
if (!settings.multi_expand) {
siblings.removeClass(settings.active_class);
aunts.removeClass(settings.active_class);
aunts.children('a').attr('aria-expanded','false');
}
target.addClass(settings.active_class).parent().addClass(settings.active_class);
settings.callback(target);
target.triggerHandler('toggled', [accordion]);
accordion.triggerHandler('toggled', [target]);
S(this).attr('aria-expanded','true');
});
},
create: function($instance) {
var self = this,
accordion = $instance,
aunts = $('> .accordion-navigation', accordion),
settings = accordion.data(self.attr_name(true) + '-init') || self.settings;
aunts.children('a').attr('aria-expanded','false');
aunts.has('.' + settings.content_class + '.' + settings.active_class).children('a').attr('aria-expanded','true');
if (settings.multi_expand) {
$instance.attr('aria-multiselectable','true');
}
},
off : function () {},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,43 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.alert = {
name : 'alert',
version : '5.5.2',
settings : {
callback : function () {}
},
init : function (scope, method, options) {
this.bindings(method, options);
},
events : function () {
var self = this,
S = this.S;
$(this.scope).off('.alert').on('click.fndtn.alert', '[' + this.attr_name() + '] .close', function (e) {
var alertBox = S(this).closest('[' + self.attr_name() + ']'),
settings = alertBox.data(self.attr_name(true) + '-init') || self.settings;
e.preventDefault();
if (Modernizr.csstransitions) {
alertBox.addClass('alert-close');
alertBox.on('transitionend webkitTransitionEnd oTransitionEnd', function (e) {
S(this).trigger('close.fndtn.alert').remove();
settings.callback();
});
} else {
alertBox.fadeOut(300, function () {
S(this).trigger('close.fndtn.alert').remove();
settings.callback();
});
}
});
},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,586 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.clearing = {
name : 'clearing',
version : '5.5.2',
settings : {
templates : {
viewing : '<a href="#" class="clearing-close">&times;</a>' +
'<div class="visible-img" style="display: none"><div class="clearing-touch-label"></div><img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' +
'<p class="clearing-caption"></p><a href="#" class="clearing-main-prev"><span></span></a>' +
'<a href="#" class="clearing-main-next"><span></span></a></div>' +
'<img class="clearing-preload-next" style="display: none" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' +
'<img class="clearing-preload-prev" style="display: none" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />'
},
// comma delimited list of selectors that, on click, will close clearing,
// add 'div.clearing-blackout, div.visible-img' to close on background click
close_selectors : '.clearing-close, div.clearing-blackout',
// Default to the entire li element.
open_selectors : '',
// Image will be skipped in carousel.
skip_selector : '',
touch_label : '',
// event initializers and locks
init : false,
locked : false
},
init : function (scope, method, options) {
var self = this;
Foundation.inherit(this, 'throttle image_loaded');
this.bindings(method, options);
if (self.S(this.scope).is('[' + this.attr_name() + ']')) {
this.assemble(self.S('li', this.scope));
} else {
self.S('[' + this.attr_name() + ']', this.scope).each(function () {
self.assemble(self.S('li', this));
});
}
},
events : function (scope) {
var self = this,
S = self.S,
$scroll_container = $('.scroll-container');
if ($scroll_container.length > 0) {
this.scope = $scroll_container;
}
S(this.scope)
.off('.clearing')
.on('click.fndtn.clearing', 'ul[' + this.attr_name() + '] li ' + this.settings.open_selectors,
function (e, current, target) {
var current = current || S(this),
target = target || current,
next = current.next('li'),
settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'),
image = S(e.target);
e.preventDefault();
if (!settings) {
self.init();
settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
}
// if clearing is open and the current image is
// clicked, go to the next image in sequence
if (target.hasClass('visible') &&
current[0] === target[0] &&
next.length > 0 && self.is_open(current)) {
target = next;
image = S('img', target);
}
// set current and target to the clicked li if not otherwise defined.
self.open(image, current, target);
self.update_paddles(target);
})
.on('click.fndtn.clearing', '.clearing-main-next',
function (e) { self.nav(e, 'next') })
.on('click.fndtn.clearing', '.clearing-main-prev',
function (e) { self.nav(e, 'prev') })
.on('click.fndtn.clearing', this.settings.close_selectors,
function (e) { Foundation.libs.clearing.close(e, this) });
$(document).on('keydown.fndtn.clearing',
function (e) { self.keydown(e) });
S(window).off('.clearing').on('resize.fndtn.clearing',
function () { self.resize() });
this.swipe_events(scope);
},
swipe_events : function (scope) {
var self = this,
S = self.S;
S(this.scope)
.on('touchstart.fndtn.clearing', '.visible-img', function (e) {
if (!e.touches) { e = e.originalEvent; }
var data = {
start_page_x : e.touches[0].pageX,
start_page_y : e.touches[0].pageY,
start_time : (new Date()).getTime(),
delta_x : 0,
is_scrolling : undefined
};
S(this).data('swipe-transition', data);
e.stopPropagation();
})
.on('touchmove.fndtn.clearing', '.visible-img', function (e) {
if (!e.touches) {
e = e.originalEvent;
}
// Ignore pinch/zoom events
if (e.touches.length > 1 || e.scale && e.scale !== 1) {
return;
}
var data = S(this).data('swipe-transition');
if (typeof data === 'undefined') {
data = {};
}
data.delta_x = e.touches[0].pageX - data.start_page_x;
if (Foundation.rtl) {
data.delta_x = -data.delta_x;
}
if (typeof data.is_scrolling === 'undefined') {
data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
}
if (!data.is_scrolling && !data.active) {
e.preventDefault();
var direction = (data.delta_x < 0) ? 'next' : 'prev';
data.active = true;
self.nav(e, direction);
}
})
.on('touchend.fndtn.clearing', '.visible-img', function (e) {
S(this).data('swipe-transition', {});
e.stopPropagation();
});
},
assemble : function ($li) {
var $el = $li.parent();
if ($el.parent().hasClass('carousel')) {
return;
}
$el.after('<div id="foundationClearingHolder"></div>');
var grid = $el.detach(),
grid_outerHTML = '';
if (grid[0] == null) {
return;
} else {
grid_outerHTML = grid[0].outerHTML;
}
var holder = this.S('#foundationClearingHolder'),
settings = $el.data(this.attr_name(true) + '-init'),
data = {
grid : '<div class="carousel">' + grid_outerHTML + '</div>',
viewing : settings.templates.viewing
},
wrapper = '<div class="clearing-assembled"><div>' + data.viewing +
data.grid + '</div></div>',
touch_label = this.settings.touch_label;
if (Modernizr.touch) {
wrapper = $(wrapper).find('.clearing-touch-label').html(touch_label).end();
}
holder.after(wrapper).remove();
},
open : function ($image, current, target) {
var self = this,
body = $(document.body),
root = target.closest('.clearing-assembled'),
container = self.S('div', root).first(),
visible_image = self.S('.visible-img', container),
image = self.S('img', visible_image).not($image),
label = self.S('.clearing-touch-label', container),
error = false,
loaded = {};
// Event to disable scrolling on touch devices when Clearing is activated
$('body').on('touchmove', function (e) {
e.preventDefault();
});
image.error(function () {
error = true;
});
function startLoad() {
setTimeout(function () {
this.image_loaded(image, function () {
if (image.outerWidth() === 1 && !error) {
startLoad.call(this);
} else {
cb.call(this, image);
}
}.bind(this));
}.bind(this), 100);
}
function cb (image) {
var $image = $(image);
$image.css('visibility', 'visible');
$image.trigger('imageVisible');
// toggle the gallery
body.css('overflow', 'hidden');
root.addClass('clearing-blackout');
container.addClass('clearing-container');
visible_image.show();
this.fix_height(target)
.caption(self.S('.clearing-caption', visible_image), self.S('img', target))
.center_and_label(image, label)
.shift(current, target, function () {
target.closest('li').siblings().removeClass('visible');
target.closest('li').addClass('visible');
});
visible_image.trigger('opened.fndtn.clearing')
}
if (!this.locked()) {
visible_image.trigger('open.fndtn.clearing');
// set the image to the selected thumbnail
loaded = this.load($image);
if (loaded.interchange) {
image
.attr('data-interchange', loaded.interchange)
.foundation('interchange', 'reflow');
} else {
image
.attr('src', loaded.src)
.attr('data-interchange', '');
}
image.css('visibility', 'hidden');
startLoad.call(this);
}
},
close : function (e, el) {
e.preventDefault();
var root = (function (target) {
if (/blackout/.test(target.selector)) {
return target;
} else {
return target.closest('.clearing-blackout');
}
}($(el))),
body = $(document.body), container, visible_image;
if (el === e.target && root) {
body.css('overflow', '');
container = $('div', root).first();
visible_image = $('.visible-img', container);
visible_image.trigger('close.fndtn.clearing');
this.settings.prev_index = 0;
$('ul[' + this.attr_name() + ']', root)
.attr('style', '').closest('.clearing-blackout')
.removeClass('clearing-blackout');
container.removeClass('clearing-container');
visible_image.hide();
visible_image.trigger('closed.fndtn.clearing');
}
// Event to re-enable scrolling on touch devices
$('body').off('touchmove');
return false;
},
is_open : function (current) {
return current.parent().prop('style').length > 0;
},
keydown : function (e) {
var clearing = $('.clearing-blackout ul[' + this.attr_name() + ']'),
NEXT_KEY = this.rtl ? 37 : 39,
PREV_KEY = this.rtl ? 39 : 37,
ESC_KEY = 27;
if (e.which === NEXT_KEY) {
this.go(clearing, 'next');
}
if (e.which === PREV_KEY) {
this.go(clearing, 'prev');
}
if (e.which === ESC_KEY) {
this.S('a.clearing-close').trigger('click.fndtn.clearing');
}
},
nav : function (e, direction) {
var clearing = $('ul[' + this.attr_name() + ']', '.clearing-blackout');
e.preventDefault();
this.go(clearing, direction);
},
resize : function () {
var image = $('img', '.clearing-blackout .visible-img'),
label = $('.clearing-touch-label', '.clearing-blackout');
if (image.length) {
this.center_and_label(image, label);
image.trigger('resized.fndtn.clearing')
}
},
// visual adjustments
fix_height : function (target) {
var lis = target.parent().children(),
self = this;
lis.each(function () {
var li = self.S(this),
image = li.find('img');
if (li.height() > image.outerHeight()) {
li.addClass('fix-height');
}
})
.closest('ul')
.width(lis.length * 100 + '%');
return this;
},
update_paddles : function (target) {
target = target.closest('li');
var visible_image = target
.closest('.carousel')
.siblings('.visible-img');
if (target.next().length > 0) {
this.S('.clearing-main-next', visible_image).removeClass('disabled');
} else {
this.S('.clearing-main-next', visible_image).addClass('disabled');
}
if (target.prev().length > 0) {
this.S('.clearing-main-prev', visible_image).removeClass('disabled');
} else {
this.S('.clearing-main-prev', visible_image).addClass('disabled');
}
},
center_and_label : function (target, label) {
if (!this.rtl && label.length > 0) {
label.css({
marginLeft : -(label.outerWidth() / 2),
marginTop : -(target.outerHeight() / 2)-label.outerHeight()-10
});
} else {
label.css({
marginRight : -(label.outerWidth() / 2),
marginTop : -(target.outerHeight() / 2)-label.outerHeight()-10,
left: 'auto',
right: '50%'
});
}
return this;
},
// image loading and preloading
load : function ($image) {
var href,
interchange,
closest_a;
if ($image[0].nodeName === 'A') {
href = $image.attr('href');
interchange = $image.data('clearing-interchange');
} else {
closest_a = $image.closest('a');
href = closest_a.attr('href');
interchange = closest_a.data('clearing-interchange');
}
this.preload($image);
return {
'src': href ? href : $image.attr('src'),
'interchange': href ? interchange : $image.data('clearing-interchange')
}
},
preload : function ($image) {
this
.img($image.closest('li').next(), 'next')
.img($image.closest('li').prev(), 'prev');
},
img : function (img, sibling_type) {
if (img.length) {
var preload_img = $('.clearing-preload-' + sibling_type),
new_a = this.S('a', img),
src,
interchange,
image;
if (new_a.length) {
src = new_a.attr('href');
interchange = new_a.data('clearing-interchange');
} else {
image = this.S('img', img);
src = image.attr('src');
interchange = image.data('clearing-interchange');
}
if (interchange) {
preload_img.attr('data-interchange', interchange);
} else {
preload_img.attr('src', src);
preload_img.attr('data-interchange', '');
}
}
return this;
},
// image caption
caption : function (container, $image) {
var caption = $image.attr('data-caption');
if (caption) {
container
.html(caption)
.show();
} else {
container
.text('')
.hide();
}
return this;
},
// directional methods
go : function ($ul, direction) {
var current = this.S('.visible', $ul),
target = current[direction]();
// Check for skip selector.
if (this.settings.skip_selector && target.find(this.settings.skip_selector).length != 0) {
target = target[direction]();
}
if (target.length) {
this.S('img', target)
.trigger('click.fndtn.clearing', [current, target])
.trigger('change.fndtn.clearing');
}
},
shift : function (current, target, callback) {
var clearing = target.parent(),
old_index = this.settings.prev_index || target.index(),
direction = this.direction(clearing, current, target),
dir = this.rtl ? 'right' : 'left',
left = parseInt(clearing.css('left'), 10),
width = target.outerWidth(),
skip_shift;
var dir_obj = {};
// we use jQuery animate instead of CSS transitions because we
// need a callback to unlock the next animation
// needs support for RTL **
if (target.index() !== old_index && !/skip/.test(direction)) {
if (/left/.test(direction)) {
this.lock();
dir_obj[dir] = left + width;
clearing.animate(dir_obj, 300, this.unlock());
} else if (/right/.test(direction)) {
this.lock();
dir_obj[dir] = left - width;
clearing.animate(dir_obj, 300, this.unlock());
}
} else if (/skip/.test(direction)) {
// the target image is not adjacent to the current image, so
// do we scroll right or not
skip_shift = target.index() - this.settings.up_count;
this.lock();
if (skip_shift > 0) {
dir_obj[dir] = -(skip_shift * width);
clearing.animate(dir_obj, 300, this.unlock());
} else {
dir_obj[dir] = 0;
clearing.animate(dir_obj, 300, this.unlock());
}
}
callback();
},
direction : function ($el, current, target) {
var lis = this.S('li', $el),
li_width = lis.outerWidth() + (lis.outerWidth() / 4),
up_count = Math.floor(this.S('.clearing-container').outerWidth() / li_width) - 1,
target_index = lis.index(target),
response;
this.settings.up_count = up_count;
if (this.adjacent(this.settings.prev_index, target_index)) {
if ((target_index > up_count) && target_index > this.settings.prev_index) {
response = 'right';
} else if ((target_index > up_count - 1) && target_index <= this.settings.prev_index) {
response = 'left';
} else {
response = false;
}
} else {
response = 'skip';
}
this.settings.prev_index = target_index;
return response;
},
adjacent : function (current_index, target_index) {
for (var i = target_index + 1; i >= target_index - 1; i--) {
if (i === current_index) {
return true;
}
}
return false;
},
// lock management
lock : function () {
this.settings.locked = true;
},
unlock : function () {
this.settings.locked = false;
},
locked : function () {
return this.settings.locked;
},
off : function () {
this.S(this.scope).off('.fndtn.clearing');
this.S(window).off('.fndtn.clearing');
},
reflow : function () {
this.init();
}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,463 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.dropdown = {
name : 'dropdown',
version : '5.5.2',
settings : {
active_class : 'open',
disabled_class : 'disabled',
mega_class : 'mega',
align : 'bottom',
is_hover : false,
hover_timeout : 150,
opened : function () {},
closed : function () {}
},
init : function (scope, method, options) {
Foundation.inherit(this, 'throttle');
$.extend(true, this.settings, method, options);
this.bindings(method, options);
},
events : function (scope) {
var self = this,
S = self.S;
S(this.scope)
.off('.dropdown')
.on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) {
var settings = S(this).data(self.attr_name(true) + '-init') || self.settings;
if (!settings.is_hover || Modernizr.touch) {
e.preventDefault();
if (S(this).parent('[data-reveal-id]').length) {
e.stopPropagation();
}
self.toggle($(this));
}
})
.on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
var $this = S(this),
dropdown,
target;
clearTimeout(self.timeout);
if ($this.data(self.data_attr())) {
dropdown = S('#' + $this.data(self.data_attr()));
target = $this;
} else {
dropdown = $this;
target = S('[' + self.attr_name() + '="' + dropdown.attr('id') + '"]');
}
var settings = target.data(self.attr_name(true) + '-init') || self.settings;
if (S(e.currentTarget).data(self.data_attr()) && settings.is_hover) {
self.closeall.call(self);
}
if (settings.is_hover) {
self.open.apply(self, [dropdown, target]);
}
})
.on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
var $this = S(this);
var settings;
if ($this.data(self.data_attr())) {
settings = $this.data(self.data_attr(true) + '-init') || self.settings;
} else {
var target = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'),
settings = target.data(self.attr_name(true) + '-init') || self.settings;
}
self.timeout = setTimeout(function () {
if ($this.data(self.data_attr())) {
if (settings.is_hover) {
self.close.call(self, S('#' + $this.data(self.data_attr())));
}
} else {
if (settings.is_hover) {
self.close.call(self, $this);
}
}
}.bind(this), settings.hover_timeout);
})
.on('click.fndtn.dropdown', function (e) {
var parent = S(e.target).closest('[' + self.attr_name() + '-content]');
var links = parent.find('a');
if (links.length > 0 && parent.attr('aria-autoclose') !== 'false') {
self.close.call(self, S('[' + self.attr_name() + '-content]'));
}
if (e.target !== document && !$.contains(document.documentElement, e.target)) {
return;
}
if (S(e.target).closest('[' + self.attr_name() + ']').length > 0) {
return;
}
if (!(S(e.target).data('revealId')) &&
(parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') ||
$.contains(parent.first()[0], e.target)))) {
e.stopPropagation();
return;
}
self.close.call(self, S('[' + self.attr_name() + '-content]'));
})
.on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
self.settings.opened.call(this);
})
.on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
self.settings.closed.call(this);
});
S(window)
.off('.dropdown')
.on('resize.fndtn.dropdown', self.throttle(function () {
self.resize.call(self);
}, 50));
this.resize();
},
close : function (dropdown) {
var self = this;
dropdown.each(function (idx) {
var original_target = $('[' + self.attr_name() + '=' + dropdown[idx].id + ']') || $('aria-controls=' + dropdown[idx].id + ']');
original_target.attr('aria-expanded', 'false');
if (self.S(this).hasClass(self.settings.active_class)) {
self.S(this)
.css(Foundation.rtl ? 'right' : 'left', '-99999px')
.attr('aria-hidden', 'true')
.removeClass(self.settings.active_class)
.prev('[' + self.attr_name() + ']')
.removeClass(self.settings.active_class)
.removeData('target');
self.S(this).trigger('closed.fndtn.dropdown', [dropdown]);
}
});
dropdown.removeClass('f-open-' + this.attr_name(true));
},
closeall : function () {
var self = this;
$.each(self.S('.f-open-' + this.attr_name(true)), function () {
self.close.call(self, self.S(this));
});
},
open : function (dropdown, target) {
this
.css(dropdown
.addClass(this.settings.active_class), target);
dropdown.prev('[' + this.attr_name() + ']').addClass(this.settings.active_class);
dropdown.data('target', target.get(0)).trigger('opened.fndtn.dropdown', [dropdown, target]);
dropdown.attr('aria-hidden', 'false');
target.attr('aria-expanded', 'true');
dropdown.focus();
dropdown.addClass('f-open-' + this.attr_name(true));
},
data_attr : function () {
if (this.namespace.length > 0) {
return this.namespace + '-' + this.name;
}
return this.name;
},
toggle : function (target) {
if (target.hasClass(this.settings.disabled_class)) {
return;
}
var dropdown = this.S('#' + target.data(this.data_attr()));
if (dropdown.length === 0) {
// No dropdown found, not continuing
return;
}
this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown));
if (dropdown.hasClass(this.settings.active_class)) {
this.close.call(this, dropdown);
if (dropdown.data('target') !== target.get(0)) {
this.open.call(this, dropdown, target);
}
} else {
this.open.call(this, dropdown, target);
}
},
resize : function () {
var dropdown = this.S('[' + this.attr_name() + '-content].open');
var target = $(dropdown.data("target"));
if (dropdown.length && target.length) {
this.css(dropdown, target);
}
},
css : function (dropdown, target) {
var left_offset = Math.max((target.width() - dropdown.width()) / 2, 8),
settings = target.data(this.attr_name(true) + '-init') || this.settings,
parentOverflow = dropdown.parent().css('overflow-y') || dropdown.parent().css('overflow');
this.clear_idx();
if (this.small()) {
var p = this.dirs.bottom.call(dropdown, target, settings);
dropdown.attr('style', '').removeClass('drop-left drop-right drop-top').css({
position : 'absolute',
width : '95%',
'max-width' : 'none',
top : p.top
});
dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset);
}
// detect if dropdown is in an overflow container
else if (parentOverflow !== 'visible') {
var offset = target[0].offsetTop + target[0].offsetHeight;
dropdown.attr('style', '').css({
position : 'absolute',
top : offset
});
dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset);
}
else {
this.style(dropdown, target, settings);
}
return dropdown;
},
style : function (dropdown, target, settings) {
var css = $.extend({position : 'absolute'},
this.dirs[settings.align].call(dropdown, target, settings));
dropdown.attr('style', '').css(css);
},
// return CSS property object
// `this` is the dropdown
dirs : {
// Calculate target offset
_base : function (t) {
var o_p = this.offsetParent(),
o = o_p.offset(),
p = t.offset();
p.top -= o.top;
p.left -= o.left;
//set some flags on the p object to pass along
p.missRight = false;
p.missTop = false;
p.missLeft = false;
p.leftRightFlag = false;
//lets see if the panel will be off the screen
//get the actual width of the page and store it
var actualBodyWidth;
if (document.getElementsByClassName('row')[0]) {
actualBodyWidth = document.getElementsByClassName('row')[0].clientWidth;
} else {
actualBodyWidth = window.innerWidth;
}
var actualMarginWidth = (window.innerWidth - actualBodyWidth) / 2;
var actualBoundary = actualBodyWidth;
if (!this.hasClass('mega')) {
//miss top
if (t.offset().top <= this.outerHeight()) {
p.missTop = true;
actualBoundary = window.innerWidth - actualMarginWidth;
p.leftRightFlag = true;
}
//miss right
if (t.offset().left + this.outerWidth() > t.offset().left + actualMarginWidth && t.offset().left - actualMarginWidth > this.outerWidth()) {
p.missRight = true;
p.missLeft = false;
}
//miss left
if (t.offset().left - this.outerWidth() <= 0) {
p.missLeft = true;
p.missRight = false;
}
}
return p;
},
top : function (t, s) {
var self = Foundation.libs.dropdown,
p = self.dirs._base.call(this, t);
this.addClass('drop-top');
if (p.missTop == true) {
p.top = p.top + t.outerHeight() + this.outerHeight();
this.removeClass('drop-top');
}
if (p.missRight == true) {
p.left = p.left - this.outerWidth() + t.outerWidth();
}
if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) {
self.adjust_pip(this, t, s, p);
}
if (Foundation.rtl) {
return {left : p.left - this.outerWidth() + t.outerWidth(),
top : p.top - this.outerHeight()};
}
return {left : p.left, top : p.top - this.outerHeight()};
},
bottom : function (t, s) {
var self = Foundation.libs.dropdown,
p = self.dirs._base.call(this, t);
if (p.missRight == true) {
p.left = p.left - this.outerWidth() + t.outerWidth();
}
if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) {
self.adjust_pip(this, t, s, p);
}
if (self.rtl) {
return {left : p.left - this.outerWidth() + t.outerWidth(), top : p.top + t.outerHeight()};
}
return {left : p.left, top : p.top + t.outerHeight()};
},
left : function (t, s) {
var p = Foundation.libs.dropdown.dirs._base.call(this, t);
this.addClass('drop-left');
if (p.missLeft == true) {
p.left = p.left + this.outerWidth();
p.top = p.top + t.outerHeight();
this.removeClass('drop-left');
}
return {left : p.left - this.outerWidth(), top : p.top};
},
right : function (t, s) {
var p = Foundation.libs.dropdown.dirs._base.call(this, t);
this.addClass('drop-right');
if (p.missRight == true) {
p.left = p.left - this.outerWidth();
p.top = p.top + t.outerHeight();
this.removeClass('drop-right');
} else {
p.triggeredRight = true;
}
var self = Foundation.libs.dropdown;
if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) {
self.adjust_pip(this, t, s, p);
}
return {left : p.left + t.outerWidth(), top : p.top};
}
},
// Insert rule to style psuedo elements
adjust_pip : function (dropdown, target, settings, position) {
var sheet = Foundation.stylesheet,
pip_offset_base = 8;
if (dropdown.hasClass(settings.mega_class)) {
pip_offset_base = position.left + (target.outerWidth() / 2) - 8;
} else if (this.small()) {
pip_offset_base += position.left - 8;
}
this.rule_idx = sheet.cssRules.length;
//default
var sel_before = '.f-dropdown.open:before',
sel_after = '.f-dropdown.open:after',
css_before = 'left: ' + pip_offset_base + 'px;',
css_after = 'left: ' + (pip_offset_base - 1) + 'px;';
if (position.missRight == true) {
pip_offset_base = dropdown.outerWidth() - 23;
sel_before = '.f-dropdown.open:before',
sel_after = '.f-dropdown.open:after',
css_before = 'left: ' + pip_offset_base + 'px;',
css_after = 'left: ' + (pip_offset_base - 1) + 'px;';
}
//just a case where right is fired, but its not missing right
if (position.triggeredRight == true) {
sel_before = '.f-dropdown.open:before',
sel_after = '.f-dropdown.open:after',
css_before = 'left:-12px;',
css_after = 'left:-14px;';
}
if (sheet.insertRule) {
sheet.insertRule([sel_before, '{', css_before, '}'].join(' '), this.rule_idx);
sheet.insertRule([sel_after, '{', css_after, '}'].join(' '), this.rule_idx + 1);
} else {
sheet.addRule(sel_before, css_before, this.rule_idx);
sheet.addRule(sel_after, css_after, this.rule_idx + 1);
}
},
// Remove old dropdown rule index
clear_idx : function () {
var sheet = Foundation.stylesheet;
if (typeof this.rule_idx !== 'undefined') {
sheet.deleteRule(this.rule_idx);
sheet.deleteRule(this.rule_idx);
delete this.rule_idx;
}
},
small : function () {
return matchMedia(Foundation.media_queries.small).matches &&
!matchMedia(Foundation.media_queries.medium).matches;
},
off : function () {
this.S(this.scope).off('.fndtn.dropdown');
this.S('html, body').off('.fndtn.dropdown');
this.S(window).off('.fndtn.dropdown');
this.S('[data-dropdown-content]').off('.fndtn.dropdown');
},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,104 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.equalizer = {
name : 'equalizer',
version : '5.5.2',
settings : {
use_tallest : true,
before_height_change : $.noop,
after_height_change : $.noop,
equalize_on_stack : false,
act_on_hidden_el: false
},
init : function (scope, method, options) {
Foundation.inherit(this, 'image_loaded');
this.bindings(method, options);
this.reflow();
},
events : function () {
this.S(window).off('.equalizer').on('resize.fndtn.equalizer', function (e) {
this.reflow();
}.bind(this));
},
equalize : function (equalizer) {
var isStacked = false,
group = equalizer.data('equalizer'),
settings = equalizer.data(this.attr_name(true)+'-init') || this.settings,
vals,
firstTopOffset;
if (settings.act_on_hidden_el) {
vals = group ? equalizer.find('['+this.attr_name()+'-watch="'+group+'"]') : equalizer.find('['+this.attr_name()+'-watch]');
}
else {
vals = group ? equalizer.find('['+this.attr_name()+'-watch="'+group+'"]:visible') : equalizer.find('['+this.attr_name()+'-watch]:visible');
}
if (vals.length === 0) {
return;
}
settings.before_height_change();
equalizer.trigger('before-height-change.fndth.equalizer');
vals.height('inherit');
if (settings.equalize_on_stack === false) {
firstTopOffset = vals.first().offset().top;
vals.each(function () {
if ($(this).offset().top !== firstTopOffset) {
isStacked = true;
return false;
}
});
if (isStacked) {
return;
}
}
var heights = vals.map(function () { return $(this).outerHeight(false) }).get();
if (settings.use_tallest) {
var max = Math.max.apply(null, heights);
vals.css('height', max);
} else {
var min = Math.min.apply(null, heights);
vals.css('height', min);
}
settings.after_height_change();
equalizer.trigger('after-height-change.fndtn.equalizer');
},
reflow : function () {
var self = this;
this.S('[' + this.attr_name() + ']', this.scope).each(function () {
var $eq_target = $(this),
media_query = $eq_target.data('equalizer-mq'),
ignore_media_query = true;
if (media_query) {
media_query = 'is_' + media_query.replace(/-/g, '_');
if (Foundation.utils.hasOwnProperty(media_query)) {
ignore_media_query = false;
}
}
self.image_loaded(self.S('img', this), function () {
if (ignore_media_query || Foundation.utils[media_query]()) {
self.equalize($eq_target)
} else {
var vals = $eq_target.find('[' + self.attr_name() + '-watch]:visible');
vals.css('height', 'auto');
}
});
});
}
};
})(jQuery, window, window.document);

View File

@ -0,0 +1,359 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.interchange = {
name : 'interchange',
version : '5.5.2',
cache : {},
images_loaded : false,
nodes_loaded : false,
settings : {
load_attr : 'interchange',
named_queries : {
'default' : 'only screen',
'small' : Foundation.media_queries['small'],
'small-only' : Foundation.media_queries['small-only'],
'medium' : Foundation.media_queries['medium'],
'medium-only' : Foundation.media_queries['medium-only'],
'large' : Foundation.media_queries['large'],
'large-only' : Foundation.media_queries['large-only'],
'xlarge' : Foundation.media_queries['xlarge'],
'xlarge-only' : Foundation.media_queries['xlarge-only'],
'xxlarge' : Foundation.media_queries['xxlarge'],
'landscape' : 'only screen and (orientation: landscape)',
'portrait' : 'only screen and (orientation: portrait)',
'retina' : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
'only screen and (min--moz-device-pixel-ratio: 2),' +
'only screen and (-o-min-device-pixel-ratio: 2/1),' +
'only screen and (min-device-pixel-ratio: 2),' +
'only screen and (min-resolution: 192dpi),' +
'only screen and (min-resolution: 2dppx)'
},
directives : {
replace : function (el, path, trigger) {
// The trigger argument, if called within the directive, fires
// an event named after the directive on the element, passing
// any parameters along to the event that you pass to trigger.
//
// ex. trigger(), trigger([a, b, c]), or trigger(a, b, c)
//
// This allows you to bind a callback like so:
// $('#interchangeContainer').on('replace', function (e, a, b, c) {
// console.log($(this).html(), a, b, c);
// });
if (el !== null && /IMG/.test(el[0].nodeName)) {
var orig_path = el[0].src;
if (new RegExp(path, 'i').test(orig_path)) {
return;
}
el.attr("src", path);
return trigger(el[0].src);
}
var last_path = el.data(this.data_attr + '-last-path'),
self = this;
if (last_path == path) {
return;
}
if (/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(path)) {
$(el).css('background-image', 'url(' + path + ')');
el.data('interchange-last-path', path);
return trigger(path);
}
return $.get(path, function (response) {
el.html(response);
el.data(self.data_attr + '-last-path', path);
trigger();
});
}
}
},
init : function (scope, method, options) {
Foundation.inherit(this, 'throttle random_str');
this.data_attr = this.set_data_attr();
$.extend(true, this.settings, method, options);
this.bindings(method, options);
this.reflow();
},
get_media_hash : function () {
var mediaHash = '';
for (var queryName in this.settings.named_queries ) {
mediaHash += matchMedia(this.settings.named_queries[queryName]).matches.toString();
}
return mediaHash;
},
events : function () {
var self = this, prevMediaHash;
$(window)
.off('.interchange')
.on('resize.fndtn.interchange', self.throttle(function () {
var currMediaHash = self.get_media_hash();
if (currMediaHash !== prevMediaHash) {
self.resize();
}
prevMediaHash = currMediaHash;
}, 50));
return this;
},
resize : function () {
var cache = this.cache;
if (!this.images_loaded || !this.nodes_loaded) {
setTimeout($.proxy(this.resize, this), 50);
return;
}
for (var uuid in cache) {
if (cache.hasOwnProperty(uuid)) {
var passed = this.results(uuid, cache[uuid]);
if (passed) {
this.settings.directives[passed
.scenario[1]].call(this, passed.el, passed.scenario[0], (function (passed) {
if (arguments[0] instanceof Array) {
var args = arguments[0];
} else {
var args = Array.prototype.slice.call(arguments, 0);
}
return function() {
passed.el.trigger(passed.scenario[1], args);
}
}(passed)));
}
}
}
},
results : function (uuid, scenarios) {
var count = scenarios.length;
if (count > 0) {
var el = this.S('[' + this.add_namespace('data-uuid') + '="' + uuid + '"]');
while (count--) {
var mq, rule = scenarios[count][2];
if (this.settings.named_queries.hasOwnProperty(rule)) {
mq = matchMedia(this.settings.named_queries[rule]);
} else {
mq = matchMedia(rule);
}
if (mq.matches) {
return {el : el, scenario : scenarios[count]};
}
}
}
return false;
},
load : function (type, force_update) {
if (typeof this['cached_' + type] === 'undefined' || force_update) {
this['update_' + type]();
}
return this['cached_' + type];
},
update_images : function () {
var images = this.S('img[' + this.data_attr + ']'),
count = images.length,
i = count,
loaded_count = 0,
data_attr = this.data_attr;
this.cache = {};
this.cached_images = [];
this.images_loaded = (count === 0);
while (i--) {
loaded_count++;
if (images[i]) {
var str = images[i].getAttribute(data_attr) || '';
if (str.length > 0) {
this.cached_images.push(images[i]);
}
}
if (loaded_count === count) {
this.images_loaded = true;
this.enhance('images');
}
}
return this;
},
update_nodes : function () {
var nodes = this.S('[' + this.data_attr + ']').not('img'),
count = nodes.length,
i = count,
loaded_count = 0,
data_attr = this.data_attr;
this.cached_nodes = [];
this.nodes_loaded = (count === 0);
while (i--) {
loaded_count++;
var str = nodes[i].getAttribute(data_attr) || '';
if (str.length > 0) {
this.cached_nodes.push(nodes[i]);
}
if (loaded_count === count) {
this.nodes_loaded = true;
this.enhance('nodes');
}
}
return this;
},
enhance : function (type) {
var i = this['cached_' + type].length;
while (i--) {
this.object($(this['cached_' + type][i]));
}
return $(window).trigger('resize.fndtn.interchange');
},
convert_directive : function (directive) {
var trimmed = this.trim(directive);
if (trimmed.length > 0) {
return trimmed;
}
return 'replace';
},
parse_scenario : function (scenario) {
// This logic had to be made more complex since some users were using commas in the url path
// So we cannot simply just split on a comma
var directive_match = scenario[0].match(/(.+),\s*(\w+)\s*$/),
// getting the mq has gotten a bit complicated since we started accounting for several use cases
// of URLs. For now we'll continue to match these scenarios, but we may consider having these scenarios
// as nested objects or arrays in F6.
// regex: match everything before close parenthesis for mq
media_query = scenario[1].match(/(.*)\)/);
if (directive_match) {
var path = directive_match[1],
directive = directive_match[2];
} else {
var cached_split = scenario[0].split(/,\s*$/),
path = cached_split[0],
directive = '';
}
return [this.trim(path), this.convert_directive(directive), this.trim(media_query[1])];
},
object : function (el) {
var raw_arr = this.parse_data_attr(el),
scenarios = [],
i = raw_arr.length;
if (i > 0) {
while (i--) {
// split array between comma delimited content and mq
// regex: comma, optional space, open parenthesis
var scenario = raw_arr[i].split(/,\s?\(/);
if (scenario.length > 1) {
var params = this.parse_scenario(scenario);
scenarios.push(params);
}
}
}
return this.store(el, scenarios);
},
store : function (el, scenarios) {
var uuid = this.random_str(),
current_uuid = el.data(this.add_namespace('uuid', true));
if (this.cache[current_uuid]) {
return this.cache[current_uuid];
}
el.attr(this.add_namespace('data-uuid'), uuid);
return this.cache[uuid] = scenarios;
},
trim : function (str) {
if (typeof str === 'string') {
return $.trim(str);
}
return str;
},
set_data_attr : function (init) {
if (init) {
if (this.namespace.length > 0) {
return this.namespace + '-' + this.settings.load_attr;
}
return this.settings.load_attr;
}
if (this.namespace.length > 0) {
return 'data-' + this.namespace + '-' + this.settings.load_attr;
}
return 'data-' + this.settings.load_attr;
},
parse_data_attr : function (el) {
var raw = el.attr(this.attr_name()).split(/\[(.*?)\]/),
i = raw.length,
output = [];
while (i--) {
if (raw[i].replace(/[\W\d]+/, '').length > 4) {
output.push(raw[i]);
}
}
return output;
},
reflow : function () {
this.load('images', true);
this.load('nodes', true);
}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,932 @@
;(function ($, window, document, undefined) {
'use strict';
var Modernizr = Modernizr || false;
Foundation.libs.joyride = {
name : 'joyride',
version : '5.5.2',
defaults : {
expose : false, // turn on or off the expose feature
modal : true, // Whether to cover page with modal during the tour
keyboard : true, // enable left, right and esc keystrokes
tip_location : 'bottom', // 'top' or 'bottom' in relation to parent
nub_position : 'auto', // override on a per tooltip bases
scroll_speed : 1500, // Page scrolling speed in milliseconds, 0 = no scroll animation
scroll_animation : 'linear', // supports 'swing' and 'linear', extend with jQuery UI.
timer : 0, // 0 = no timer , all other numbers = timer in milliseconds
start_timer_on_click : true, // true or false - true requires clicking the first button start the timer
start_offset : 0, // the index of the tooltip you want to start on (index of the li)
next_button : true, // true or false to control whether a next button is used
prev_button : true, // true or false to control whether a prev button is used
tip_animation : 'fade', // 'pop' or 'fade' in each tip
pause_after : [], // array of indexes where to pause the tour after
exposed : [], // array of expose elements
tip_animation_fade_speed : 300, // when tipAnimation = 'fade' this is speed in milliseconds for the transition
cookie_monster : false, // true or false to control whether cookies are used
cookie_name : 'joyride', // Name the cookie you'll use
cookie_domain : false, // Will this cookie be attached to a domain, ie. '.notableapp.com'
cookie_expires : 365, // set when you would like the cookie to expire.
tip_container : 'body', // Where will the tip be attached
abort_on_close : true, // When true, the close event will not fire any callback
tip_location_patterns : {
top : ['bottom'],
bottom : [], // bottom should not need to be repositioned
left : ['right', 'top', 'bottom'],
right : ['left', 'top', 'bottom']
},
post_ride_callback : function () {}, // A method to call once the tour closes (canceled or complete)
post_step_callback : function () {}, // A method to call after each step
pre_step_callback : function () {}, // A method to call before each step
pre_ride_callback : function () {}, // A method to call before the tour starts (passed index, tip, and cloned exposed element)
post_expose_callback : function () {}, // A method to call after an element has been exposed
template : { // HTML segments for tip layout
link : '<a href="#close" class="joyride-close-tip">&times;</a>',
timer : '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>',
tip : '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>',
wrapper : '<div class="joyride-content-wrapper"></div>',
button : '<a href="#" class="small button joyride-next-tip"></a>',
prev_button : '<a href="#" class="small button joyride-prev-tip"></a>',
modal : '<div class="joyride-modal-bg"></div>',
expose : '<div class="joyride-expose-wrapper"></div>',
expose_cover : '<div class="joyride-expose-cover"></div>'
},
expose_add_class : '' // One or more space-separated class names to be added to exposed element
},
init : function (scope, method, options) {
Foundation.inherit(this, 'throttle random_str');
this.settings = this.settings || $.extend({}, this.defaults, (options || method));
this.bindings(method, options)
},
go_next : function () {
if (this.settings.$li.next().length < 1) {
this.end();
} else if (this.settings.timer > 0) {
clearTimeout(this.settings.automate);
this.hide();
this.show();
this.startTimer();
} else {
this.hide();
this.show();
}
},
go_prev : function () {
if (this.settings.$li.prev().length < 1) {
// Do nothing if there are no prev element
} else if (this.settings.timer > 0) {
clearTimeout(this.settings.automate);
this.hide();
this.show(null, true);
this.startTimer();
} else {
this.hide();
this.show(null, true);
}
},
events : function () {
var self = this;
$(this.scope)
.off('.joyride')
.on('click.fndtn.joyride', '.joyride-next-tip, .joyride-modal-bg', function (e) {
e.preventDefault();
this.go_next()
}.bind(this))
.on('click.fndtn.joyride', '.joyride-prev-tip', function (e) {
e.preventDefault();
this.go_prev();
}.bind(this))
.on('click.fndtn.joyride', '.joyride-close-tip', function (e) {
e.preventDefault();
this.end(this.settings.abort_on_close);
}.bind(this))
.on('keyup.fndtn.joyride', function (e) {
// Don't do anything if keystrokes are disabled
// or if the joyride is not being shown
if (!this.settings.keyboard || !this.settings.riding) {
return;
}
switch (e.which) {
case 39: // right arrow
e.preventDefault();
this.go_next();
break;
case 37: // left arrow
e.preventDefault();
this.go_prev();
break;
case 27: // escape
e.preventDefault();
this.end(this.settings.abort_on_close);
}
}.bind(this));
$(window)
.off('.joyride')
.on('resize.fndtn.joyride', self.throttle(function () {
if ($('[' + self.attr_name() + ']').length > 0 && self.settings.$next_tip && self.settings.riding) {
if (self.settings.exposed.length > 0) {
var $els = $(self.settings.exposed);
$els.each(function () {
var $this = $(this);
self.un_expose($this);
self.expose($this);
});
}
if (self.is_phone()) {
self.pos_phone();
} else {
self.pos_default(false);
}
}
}, 100));
},
start : function () {
var self = this,
$this = $('[' + this.attr_name() + ']', this.scope),
integer_settings = ['timer', 'scrollSpeed', 'startOffset', 'tipAnimationFadeSpeed', 'cookieExpires'],
int_settings_count = integer_settings.length;
if (!$this.length > 0) {
return;
}
if (!this.settings.init) {
this.events();
}
this.settings = $this.data(this.attr_name(true) + '-init');
// non configureable settings
this.settings.$content_el = $this;
this.settings.$body = $(this.settings.tip_container);
this.settings.body_offset = $(this.settings.tip_container).position();
this.settings.$tip_content = this.settings.$content_el.find('> li');
this.settings.paused = false;
this.settings.attempts = 0;
this.settings.riding = true;
// can we create cookies?
if (typeof $.cookie !== 'function') {
this.settings.cookie_monster = false;
}
// generate the tips and insert into dom.
if (!this.settings.cookie_monster || this.settings.cookie_monster && !$.cookie(this.settings.cookie_name)) {
this.settings.$tip_content.each(function (index) {
var $this = $(this);
this.settings = $.extend({}, self.defaults, self.data_options($this));
// Make sure that settings parsed from data_options are integers where necessary
var i = int_settings_count;
while (i--) {
self.settings[integer_settings[i]] = parseInt(self.settings[integer_settings[i]], 10);
}
self.create({$li : $this, index : index});
});
// show first tip
if (!this.settings.start_timer_on_click && this.settings.timer > 0) {
this.show('init');
this.startTimer();
} else {
this.show('init');
}
}
},
resume : function () {
this.set_li();
this.show();
},
tip_template : function (opts) {
var $blank, content;
opts.tip_class = opts.tip_class || '';
$blank = $(this.settings.template.tip).addClass(opts.tip_class);
content = $.trim($(opts.li).html()) +
this.prev_button_text(opts.prev_button_text, opts.index) +
this.button_text(opts.button_text) +
this.settings.template.link +
this.timer_instance(opts.index);
$blank.append($(this.settings.template.wrapper));
$blank.first().attr(this.add_namespace('data-index'), opts.index);
$('.joyride-content-wrapper', $blank).append(content);
return $blank[0];
},
timer_instance : function (index) {
var txt;
if ((index === 0 && this.settings.start_timer_on_click && this.settings.timer > 0) || this.settings.timer === 0) {
txt = '';
} else {
txt = $(this.settings.template.timer)[0].outerHTML;
}
return txt;
},
button_text : function (txt) {
if (this.settings.tip_settings.next_button) {
txt = $.trim(txt) || 'Next';
txt = $(this.settings.template.button).append(txt)[0].outerHTML;
} else {
txt = '';
}
return txt;
},
prev_button_text : function (txt, idx) {
if (this.settings.tip_settings.prev_button) {
txt = $.trim(txt) || 'Previous';
// Add the disabled class to the button if it's the first element
if (idx == 0) {
txt = $(this.settings.template.prev_button).append(txt).addClass('disabled')[0].outerHTML;
} else {
txt = $(this.settings.template.prev_button).append(txt)[0].outerHTML;
}
} else {
txt = '';
}
return txt;
},
create : function (opts) {
this.settings.tip_settings = $.extend({}, this.settings, this.data_options(opts.$li));
var buttonText = opts.$li.attr(this.add_namespace('data-button')) || opts.$li.attr(this.add_namespace('data-text')),
prevButtonText = opts.$li.attr(this.add_namespace('data-button-prev')) || opts.$li.attr(this.add_namespace('data-prev-text')),
tipClass = opts.$li.attr('class'),
$tip_content = $(this.tip_template({
tip_class : tipClass,
index : opts.index,
button_text : buttonText,
prev_button_text : prevButtonText,
li : opts.$li
}));
$(this.settings.tip_container).append($tip_content);
},
show : function (init, is_prev) {
var $timer = null;
// are we paused?
if (this.settings.$li === undefined || ($.inArray(this.settings.$li.index(), this.settings.pause_after) === -1)) {
// don't go to the next li if the tour was paused
if (this.settings.paused) {
this.settings.paused = false;
} else {
this.set_li(init, is_prev);
}
this.settings.attempts = 0;
if (this.settings.$li.length && this.settings.$target.length > 0) {
if (init) { //run when we first start
this.settings.pre_ride_callback(this.settings.$li.index(), this.settings.$next_tip);
if (this.settings.modal) {
this.show_modal();
}
}
this.settings.pre_step_callback(this.settings.$li.index(), this.settings.$next_tip);
if (this.settings.modal && this.settings.expose) {
this.expose();
}
this.settings.tip_settings = $.extend({}, this.settings, this.data_options(this.settings.$li));
this.settings.timer = parseInt(this.settings.timer, 10);
this.settings.tip_settings.tip_location_pattern = this.settings.tip_location_patterns[this.settings.tip_settings.tip_location];
// scroll and hide bg if not modal
if (!/body/i.test(this.settings.$target.selector)) {
var joyridemodalbg = $('.joyride-modal-bg');
if (/pop/i.test(this.settings.tipAnimation)) {
joyridemodalbg.hide();
} else {
joyridemodalbg.fadeOut(this.settings.tipAnimationFadeSpeed);
}
this.scroll_to();
}
if (this.is_phone()) {
this.pos_phone(true);
} else {
this.pos_default(true);
}
$timer = this.settings.$next_tip.find('.joyride-timer-indicator');
if (/pop/i.test(this.settings.tip_animation)) {
$timer.width(0);
if (this.settings.timer > 0) {
this.settings.$next_tip.show();
setTimeout(function () {
$timer.animate({
width : $timer.parent().width()
}, this.settings.timer, 'linear');
}.bind(this), this.settings.tip_animation_fade_speed);
} else {
this.settings.$next_tip.show();
}
} else if (/fade/i.test(this.settings.tip_animation)) {
$timer.width(0);
if (this.settings.timer > 0) {
this.settings.$next_tip
.fadeIn(this.settings.tip_animation_fade_speed)
.show();
setTimeout(function () {
$timer.animate({
width : $timer.parent().width()
}, this.settings.timer, 'linear');
}.bind(this), this.settings.tip_animation_fade_speed);
} else {
this.settings.$next_tip.fadeIn(this.settings.tip_animation_fade_speed);
}
}
this.settings.$current_tip = this.settings.$next_tip;
// skip non-existant targets
} else if (this.settings.$li && this.settings.$target.length < 1) {
this.show(init, is_prev);
} else {
this.end();
}
} else {
this.settings.paused = true;
}
},
is_phone : function () {
return matchMedia(Foundation.media_queries.small).matches &&
!matchMedia(Foundation.media_queries.medium).matches;
},
hide : function () {
if (this.settings.modal && this.settings.expose) {
this.un_expose();
}
if (!this.settings.modal) {
$('.joyride-modal-bg').hide();
}
// Prevent scroll bouncing...wait to remove from layout
this.settings.$current_tip.css('visibility', 'hidden');
setTimeout($.proxy(function () {
this.hide();
this.css('visibility', 'visible');
}, this.settings.$current_tip), 0);
this.settings.post_step_callback(this.settings.$li.index(),
this.settings.$current_tip);
},
set_li : function (init, is_prev) {
if (init) {
this.settings.$li = this.settings.$tip_content.eq(this.settings.start_offset);
this.set_next_tip();
this.settings.$current_tip = this.settings.$next_tip;
} else {
if (is_prev) {
this.settings.$li = this.settings.$li.prev();
} else {
this.settings.$li = this.settings.$li.next();
}
this.set_next_tip();
}
this.set_target();
},
set_next_tip : function () {
this.settings.$next_tip = $('.joyride-tip-guide').eq(this.settings.$li.index());
this.settings.$next_tip.data('closed', '');
},
set_target : function () {
var cl = this.settings.$li.attr(this.add_namespace('data-class')),
id = this.settings.$li.attr(this.add_namespace('data-id')),
$sel = function () {
if (id) {
return $(document.getElementById(id));
} else if (cl) {
return $('.' + cl).first();
} else {
return $('body');
}
};
this.settings.$target = $sel();
},
scroll_to : function () {
var window_half, tipOffset;
window_half = $(window).height() / 2;
tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight());
if (tipOffset != 0) {
$('html, body').stop().animate({
scrollTop : tipOffset
}, this.settings.scroll_speed, 'swing');
}
},
paused : function () {
return ($.inArray((this.settings.$li.index() + 1), this.settings.pause_after) === -1);
},
restart : function () {
this.hide();
this.settings.$li = undefined;
this.show('init');
},
pos_default : function (init) {
var $nub = this.settings.$next_tip.find('.joyride-nub'),
nub_width = Math.ceil($nub.outerWidth() / 2),
nub_height = Math.ceil($nub.outerHeight() / 2),
toggle = init || false;
// tip must not be "display: none" to calculate position
if (toggle) {
this.settings.$next_tip.css('visibility', 'hidden');
this.settings.$next_tip.show();
}
if (!/body/i.test(this.settings.$target.selector)) {
var topAdjustment = this.settings.tip_settings.tipAdjustmentY ? parseInt(this.settings.tip_settings.tipAdjustmentY) : 0,
leftAdjustment = this.settings.tip_settings.tipAdjustmentX ? parseInt(this.settings.tip_settings.tipAdjustmentX) : 0;
if (this.bottom()) {
if (this.rtl) {
this.settings.$next_tip.css({
top : (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment),
left : this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth() + leftAdjustment});
} else {
this.settings.$next_tip.css({
top : (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment),
left : this.settings.$target.offset().left + leftAdjustment});
}
this.nub_position($nub, this.settings.tip_settings.nub_position, 'top');
} else if (this.top()) {
if (this.rtl) {
this.settings.$next_tip.css({
top : (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment),
left : this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth()});
} else {
this.settings.$next_tip.css({
top : (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment),
left : this.settings.$target.offset().left + leftAdjustment});
}
this.nub_position($nub, this.settings.tip_settings.nub_position, 'bottom');
} else if (this.right()) {
this.settings.$next_tip.css({
top : this.settings.$target.offset().top + topAdjustment,
left : (this.settings.$target.outerWidth() + this.settings.$target.offset().left + nub_width + leftAdjustment)});
this.nub_position($nub, this.settings.tip_settings.nub_position, 'left');
} else if (this.left()) {
this.settings.$next_tip.css({
top : this.settings.$target.offset().top + topAdjustment,
left : (this.settings.$target.offset().left - this.settings.$next_tip.outerWidth() - nub_width + leftAdjustment)});
this.nub_position($nub, this.settings.tip_settings.nub_position, 'right');
}
if (!this.visible(this.corners(this.settings.$next_tip)) && this.settings.attempts < this.settings.tip_settings.tip_location_pattern.length) {
$nub.removeClass('bottom')
.removeClass('top')
.removeClass('right')
.removeClass('left');
this.settings.tip_settings.tip_location = this.settings.tip_settings.tip_location_pattern[this.settings.attempts];
this.settings.attempts++;
this.pos_default();
}
} else if (this.settings.$li.length) {
this.pos_modal($nub);
}
if (toggle) {
this.settings.$next_tip.hide();
this.settings.$next_tip.css('visibility', 'visible');
}
},
pos_phone : function (init) {
var tip_height = this.settings.$next_tip.outerHeight(),
tip_offset = this.settings.$next_tip.offset(),
target_height = this.settings.$target.outerHeight(),
$nub = $('.joyride-nub', this.settings.$next_tip),
nub_height = Math.ceil($nub.outerHeight() / 2),
toggle = init || false;
$nub.removeClass('bottom')
.removeClass('top')
.removeClass('right')
.removeClass('left');
if (toggle) {
this.settings.$next_tip.css('visibility', 'hidden');
this.settings.$next_tip.show();
}
if (!/body/i.test(this.settings.$target.selector)) {
if (this.top()) {
this.settings.$next_tip.offset({top : this.settings.$target.offset().top - tip_height - nub_height});
$nub.addClass('bottom');
} else {
this.settings.$next_tip.offset({top : this.settings.$target.offset().top + target_height + nub_height});
$nub.addClass('top');
}
} else if (this.settings.$li.length) {
this.pos_modal($nub);
}
if (toggle) {
this.settings.$next_tip.hide();
this.settings.$next_tip.css('visibility', 'visible');
}
},
pos_modal : function ($nub) {
this.center();
$nub.hide();
this.show_modal();
},
show_modal : function () {
if (!this.settings.$next_tip.data('closed')) {
var joyridemodalbg = $('.joyride-modal-bg');
if (joyridemodalbg.length < 1) {
var joyridemodalbg = $(this.settings.template.modal);
joyridemodalbg.appendTo('body');
}
if (/pop/i.test(this.settings.tip_animation)) {
joyridemodalbg.show();
} else {
joyridemodalbg.fadeIn(this.settings.tip_animation_fade_speed);
}
}
},
expose : function () {
var expose,
exposeCover,
el,
origCSS,
origClasses,
randId = 'expose-' + this.random_str(6);
if (arguments.length > 0 && arguments[0] instanceof $) {
el = arguments[0];
} else if (this.settings.$target && !/body/i.test(this.settings.$target.selector)) {
el = this.settings.$target;
} else {
return false;
}
if (el.length < 1) {
if (window.console) {
console.error('element not valid', el);
}
return false;
}
expose = $(this.settings.template.expose);
this.settings.$body.append(expose);
expose.css({
top : el.offset().top,
left : el.offset().left,
width : el.outerWidth(true),
height : el.outerHeight(true)
});
exposeCover = $(this.settings.template.expose_cover);
origCSS = {
zIndex : el.css('z-index'),
position : el.css('position')
};
origClasses = el.attr('class') == null ? '' : el.attr('class');
el.css('z-index', parseInt(expose.css('z-index')) + 1);
if (origCSS.position == 'static') {
el.css('position', 'relative');
}
el.data('expose-css', origCSS);
el.data('orig-class', origClasses);
el.attr('class', origClasses + ' ' + this.settings.expose_add_class);
exposeCover.css({
top : el.offset().top,
left : el.offset().left,
width : el.outerWidth(true),
height : el.outerHeight(true)
});
if (this.settings.modal) {
this.show_modal();
}
this.settings.$body.append(exposeCover);
expose.addClass(randId);
exposeCover.addClass(randId);
el.data('expose', randId);
this.settings.post_expose_callback(this.settings.$li.index(), this.settings.$next_tip, el);
this.add_exposed(el);
},
un_expose : function () {
var exposeId,
el,
expose,
origCSS,
origClasses,
clearAll = false;
if (arguments.length > 0 && arguments[0] instanceof $) {
el = arguments[0];
} else if (this.settings.$target && !/body/i.test(this.settings.$target.selector)) {
el = this.settings.$target;
} else {
return false;
}
if (el.length < 1) {
if (window.console) {
console.error('element not valid', el);
}
return false;
}
exposeId = el.data('expose');
expose = $('.' + exposeId);
if (arguments.length > 1) {
clearAll = arguments[1];
}
if (clearAll === true) {
$('.joyride-expose-wrapper,.joyride-expose-cover').remove();
} else {
expose.remove();
}
origCSS = el.data('expose-css');
if (origCSS.zIndex == 'auto') {
el.css('z-index', '');
} else {
el.css('z-index', origCSS.zIndex);
}
if (origCSS.position != el.css('position')) {
if (origCSS.position == 'static') {// this is default, no need to set it.
el.css('position', '');
} else {
el.css('position', origCSS.position);
}
}
origClasses = el.data('orig-class');
el.attr('class', origClasses);
el.removeData('orig-classes');
el.removeData('expose');
el.removeData('expose-z-index');
this.remove_exposed(el);
},
add_exposed : function (el) {
this.settings.exposed = this.settings.exposed || [];
if (el instanceof $ || typeof el === 'object') {
this.settings.exposed.push(el[0]);
} else if (typeof el == 'string') {
this.settings.exposed.push(el);
}
},
remove_exposed : function (el) {
var search, i;
if (el instanceof $) {
search = el[0]
} else if (typeof el == 'string') {
search = el;
}
this.settings.exposed = this.settings.exposed || [];
i = this.settings.exposed.length;
while (i--) {
if (this.settings.exposed[i] == search) {
this.settings.exposed.splice(i, 1);
return;
}
}
},
center : function () {
var $w = $(window);
this.settings.$next_tip.css({
top : ((($w.height() - this.settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()),
left : ((($w.width() - this.settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft())
});
return true;
},
bottom : function () {
return /bottom/i.test(this.settings.tip_settings.tip_location);
},
top : function () {
return /top/i.test(this.settings.tip_settings.tip_location);
},
right : function () {
return /right/i.test(this.settings.tip_settings.tip_location);
},
left : function () {
return /left/i.test(this.settings.tip_settings.tip_location);
},
corners : function (el) {
var w = $(window),
window_half = w.height() / 2,
//using this to calculate since scroll may not have finished yet.
tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight()),
right = w.width() + w.scrollLeft(),
offsetBottom = w.height() + tipOffset,
bottom = w.height() + w.scrollTop(),
top = w.scrollTop();
if (tipOffset < top) {
if (tipOffset < 0) {
top = 0;
} else {
top = tipOffset;
}
}
if (offsetBottom > bottom) {
bottom = offsetBottom;
}
return [
el.offset().top < top,
right < el.offset().left + el.outerWidth(),
bottom < el.offset().top + el.outerHeight(),
w.scrollLeft() > el.offset().left
];
},
visible : function (hidden_corners) {
var i = hidden_corners.length;
while (i--) {
if (hidden_corners[i]) {
return false;
}
}
return true;
},
nub_position : function (nub, pos, def) {
if (pos === 'auto') {
nub.addClass(def);
} else {
nub.addClass(pos);
}
},
startTimer : function () {
if (this.settings.$li.length) {
this.settings.automate = setTimeout(function () {
this.hide();
this.show();
this.startTimer();
}.bind(this), this.settings.timer);
} else {
clearTimeout(this.settings.automate);
}
},
end : function (abort) {
if (this.settings.cookie_monster) {
$.cookie(this.settings.cookie_name, 'ridden', {expires : this.settings.cookie_expires, domain : this.settings.cookie_domain});
}
if (this.settings.timer > 0) {
clearTimeout(this.settings.automate);
}
if (this.settings.modal && this.settings.expose) {
this.un_expose();
}
// Unplug keystrokes listener
$(this.scope).off('keyup.joyride')
this.settings.$next_tip.data('closed', true);
this.settings.riding = false;
$('.joyride-modal-bg').hide();
this.settings.$current_tip.hide();
if (typeof abort === 'undefined' || abort === false) {
this.settings.post_step_callback(this.settings.$li.index(), this.settings.$current_tip);
this.settings.post_ride_callback(this.settings.$li.index(), this.settings.$current_tip);
}
$('.joyride-tip-guide').remove();
},
off : function () {
$(this.scope).off('.joyride');
$(window).off('.joyride');
$('.joyride-close-tip, .joyride-next-tip, .joyride-modal-bg').off('.joyride');
$('.joyride-tip-guide, .joyride-modal-bg').remove();
clearTimeout(this.settings.automate);
this.settings = {};
},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,725 @@
/*
* Foundation Responsive Library
* http://foundation.zurb.com
* Copyright 2014, ZURB
* 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 i = class_array.length;
var head = $('head');
while (i--) {
if (head.has('.' + class_array[i]).length === 0) {
head.append('<meta class="' + class_array[i] + '" />');
}
}
};
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),
should_bind_events = !$this.data(self.attr_name(true) + '-init');
$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;
}
window.Foundation = {
name : 'Foundation',
version : '5.5.2',
media_queries : {
'small' : S('.foundation-mq-small').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'small-only' : S('.foundation-mq-small-only').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'medium' : S('.foundation-mq-medium').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'medium-only' : S('.foundation-mq-medium-only').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'large' : S('.foundation-mq-large').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'large-only' : S('.foundation-mq-large-only').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'xlarge' : S('.foundation-mq-xlarge').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'xlarge-only' : S('.foundation-mq-xlarge-only').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, ''),
'xxlarge' : S('.foundation-mq-xxlarge').css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, '')
},
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));
}
}
S(window).load(function () {
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));

View File

@ -0,0 +1,215 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs['magellan-expedition'] = {
name : 'magellan-expedition',
version : '5.5.2',
settings : {
active_class : 'active',
threshold : 0, // pixels from the top of the expedition for it to become fixes
destination_threshold : 20, // pixels from the top of destination for it to be considered active
throttle_delay : 30, // calculation throttling to increase framerate
fixed_top : 0, // top distance in pixels assigend to the fixed element on scroll
offset_by_height : true, // whether to offset the destination by the expedition height. Usually you want this to be true, unless your expedition is on the side.
duration : 700, // animation duration time
easing : 'swing' // animation easing
},
init : function (scope, method, options) {
Foundation.inherit(this, 'throttle');
this.bindings(method, options);
},
events : function () {
var self = this,
S = self.S,
settings = self.settings;
// initialize expedition offset
self.set_expedition_position();
S(self.scope)
.off('.magellan')
.on('click.fndtn.magellan', '[' + self.add_namespace('data-magellan-arrival') + '] a[href*=#]', function (e) {
var sameHost = ((this.hostname === location.hostname) || !this.hostname),
samePath = self.filterPathname(location.pathname) === self.filterPathname(this.pathname),
testHash = this.hash.replace(/(:|\.|\/)/g, '\\$1'),
anchor = this;
if (sameHost && samePath && testHash) {
e.preventDefault();
var expedition = $(this).closest('[' + self.attr_name() + ']'),
settings = expedition.data('magellan-expedition-init'),
hash = this.hash.split('#').join(''),
target = $('a[name="' + hash + '"]');
if (target.length === 0) {
target = $('#' + hash);
}
// Account for expedition height if fixed position
var scroll_top = target.offset().top - settings.destination_threshold + 1;
if (settings.offset_by_height) {
scroll_top = scroll_top - expedition.outerHeight();
}
$('html, body').stop().animate({
'scrollTop' : scroll_top
}, settings.duration, settings.easing, function () {
if (history.pushState) {
history.pushState(null, null, anchor.pathname + '#' + hash);
}
else {
location.hash = anchor.pathname + '#' + hash;
}
});
}
})
.on('scroll.fndtn.magellan', self.throttle(this.check_for_arrivals.bind(this), settings.throttle_delay));
},
check_for_arrivals : function () {
var self = this;
self.update_arrivals();
self.update_expedition_positions();
},
set_expedition_position : function () {
var self = this;
$('[' + this.attr_name() + '=fixed]', self.scope).each(function (idx, el) {
var expedition = $(this),
settings = expedition.data('magellan-expedition-init'),
styles = expedition.attr('styles'), // save styles
top_offset, fixed_top;
expedition.attr('style', '');
top_offset = expedition.offset().top + settings.threshold;
//set fixed-top by attribute
fixed_top = parseInt(expedition.data('magellan-fixed-top'));
if (!isNaN(fixed_top)) {
self.settings.fixed_top = fixed_top;
}
expedition.data(self.data_attr('magellan-top-offset'), top_offset);
expedition.attr('style', styles);
});
},
update_expedition_positions : function () {
var self = this,
window_top_offset = $(window).scrollTop();
$('[' + this.attr_name() + '=fixed]', self.scope).each(function () {
var expedition = $(this),
settings = expedition.data('magellan-expedition-init'),
styles = expedition.attr('style'), // save styles
top_offset = expedition.data('magellan-top-offset');
//scroll to the top distance
if (window_top_offset + self.settings.fixed_top >= top_offset) {
// Placeholder allows height calculations to be consistent even when
// appearing to switch between fixed/non-fixed placement
var placeholder = expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']');
if (placeholder.length === 0) {
placeholder = expedition.clone();
placeholder.removeAttr(self.attr_name());
placeholder.attr(self.add_namespace('data-magellan-expedition-clone'), '');
expedition.before(placeholder);
}
expedition.css({position :'fixed', top : settings.fixed_top}).addClass('fixed');
} else {
expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']').remove();
expedition.attr('style', styles).css('position', '').css('top', '').removeClass('fixed');
}
});
},
update_arrivals : function () {
var self = this,
window_top_offset = $(window).scrollTop();
$('[' + this.attr_name() + ']', self.scope).each(function () {
var expedition = $(this),
settings = expedition.data(self.attr_name(true) + '-init'),
offsets = self.offsets(expedition, window_top_offset),
arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']'),
active_item = false;
offsets.each(function (idx, item) {
if (item.viewport_offset >= item.top_offset) {
var arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']');
arrivals.not(item.arrival).removeClass(settings.active_class);
item.arrival.addClass(settings.active_class);
active_item = true;
return true;
}
});
if (!active_item) {
arrivals.removeClass(settings.active_class);
}
});
},
offsets : function (expedition, window_offset) {
var self = this,
settings = expedition.data(self.attr_name(true) + '-init'),
viewport_offset = window_offset;
return expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']').map(function (idx, el) {
var name = $(this).data(self.data_attr('magellan-arrival')),
dest = $('[' + self.add_namespace('data-magellan-destination') + '=' + name + ']');
if (dest.length > 0) {
var top_offset = dest.offset().top - settings.destination_threshold;
if (settings.offset_by_height) {
top_offset = top_offset - expedition.outerHeight();
}
top_offset = Math.floor(top_offset);
return {
destination : dest,
arrival : $(this),
top_offset : top_offset,
viewport_offset : viewport_offset
}
}
}).sort(function (a, b) {
if (a.top_offset < b.top_offset) {
return -1;
}
if (a.top_offset > b.top_offset) {
return 1;
}
return 0;
});
},
data_attr : function (str) {
if (this.namespace.length > 0) {
return this.namespace + '-' + str;
}
return str;
},
off : function () {
this.S(this.scope).off('.magellan');
this.S(window).off('.magellan');
},
filterPathname : function (pathname) {
pathname = pathname || '';
return pathname
.replace(/^\//,'')
.replace(/(?:index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
},
reflow : function () {
var self = this;
// remove placeholder expeditions used for height calculation purposes
$('[' + self.add_namespace('data-magellan-expedition-clone') + ']', self.scope).remove();
}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,152 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.offcanvas = {
name : 'offcanvas',
version : '5.5.2',
settings : {
open_method : 'move',
close_on_click : false
},
init : function (scope, method, options) {
this.bindings(method, options);
},
events : function () {
var self = this,
S = self.S,
move_class = '',
right_postfix = '',
left_postfix = '';
if (this.settings.open_method === 'move') {
move_class = 'move-';
right_postfix = 'right';
left_postfix = 'left';
} else if (this.settings.open_method === 'overlap_single') {
move_class = 'offcanvas-overlap-';
right_postfix = 'right';
left_postfix = 'left';
} else if (this.settings.open_method === 'overlap') {
move_class = 'offcanvas-overlap';
}
S(this.scope).off('.offcanvas')
.on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) {
self.click_toggle_class(e, move_class + right_postfix);
if (self.settings.open_method !== 'overlap') {
S('.left-submenu').removeClass(move_class + right_postfix);
}
$('.left-off-canvas-toggle').attr('aria-expanded', 'true');
})
.on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) {
var settings = self.get_settings(e);
var parent = S(this).parent();
if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
self.hide.call(self, move_class + right_postfix, self.get_wrapper(e));
parent.parent().removeClass(move_class + right_postfix);
} else if (S(this).parent().hasClass('has-submenu')) {
e.preventDefault();
S(this).siblings('.left-submenu').toggleClass(move_class + right_postfix);
} else if (parent.hasClass('back')) {
e.preventDefault();
parent.parent().removeClass(move_class + right_postfix);
}
$('.left-off-canvas-toggle').attr('aria-expanded', 'true');
})
.on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) {
self.click_toggle_class(e, move_class + left_postfix);
if (self.settings.open_method !== 'overlap') {
S('.right-submenu').removeClass(move_class + left_postfix);
}
$('.right-off-canvas-toggle').attr('aria-expanded', 'true');
})
.on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) {
var settings = self.get_settings(e);
var parent = S(this).parent();
if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) {
self.hide.call(self, move_class + left_postfix, self.get_wrapper(e));
parent.parent().removeClass(move_class + left_postfix);
} else if (S(this).parent().hasClass('has-submenu')) {
e.preventDefault();
S(this).siblings('.right-submenu').toggleClass(move_class + left_postfix);
} else if (parent.hasClass('back')) {
e.preventDefault();
parent.parent().removeClass(move_class + left_postfix);
}
$('.right-off-canvas-toggle').attr('aria-expanded', 'true');
})
.on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
self.click_remove_class(e, move_class + left_postfix);
S('.right-submenu').removeClass(move_class + left_postfix);
if (right_postfix) {
self.click_remove_class(e, move_class + right_postfix);
S('.left-submenu').removeClass(move_class + left_postfix);
}
$('.right-off-canvas-toggle').attr('aria-expanded', 'true');
})
.on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) {
self.click_remove_class(e, move_class + left_postfix);
$('.left-off-canvas-toggle').attr('aria-expanded', 'false');
if (right_postfix) {
self.click_remove_class(e, move_class + right_postfix);
$('.right-off-canvas-toggle').attr('aria-expanded', 'false');
}
});
},
toggle : function (class_name, $off_canvas) {
$off_canvas = $off_canvas || this.get_wrapper();
if ($off_canvas.is('.' + class_name)) {
this.hide(class_name, $off_canvas);
} else {
this.show(class_name, $off_canvas);
}
},
show : function (class_name, $off_canvas) {
$off_canvas = $off_canvas || this.get_wrapper();
$off_canvas.trigger('open.fndtn.offcanvas');
$off_canvas.addClass(class_name);
},
hide : function (class_name, $off_canvas) {
$off_canvas = $off_canvas || this.get_wrapper();
$off_canvas.trigger('close.fndtn.offcanvas');
$off_canvas.removeClass(class_name);
},
click_toggle_class : function (e, class_name) {
e.preventDefault();
var $off_canvas = this.get_wrapper(e);
this.toggle(class_name, $off_canvas);
},
click_remove_class : function (e, class_name) {
e.preventDefault();
var $off_canvas = this.get_wrapper(e);
this.hide(class_name, $off_canvas);
},
get_settings : function (e) {
var offcanvas = this.S(e.target).closest('[' + this.attr_name() + ']');
return offcanvas.data(this.attr_name(true) + '-init') || this.settings;
},
get_wrapper : function (e) {
var $off_canvas = this.S(e ? e.target : this.scope).closest('.off-canvas-wrap');
if ($off_canvas.length === 0) {
$off_canvas = this.S('.off-canvas-wrap');
}
return $off_canvas;
},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,476 @@
;(function ($, window, document, undefined) {
'use strict';
var noop = function () {};
var Orbit = function (el, settings) {
// Don't reinitialize plugin
if (el.hasClass(settings.slides_container_class)) {
return this;
}
var self = this,
container,
slides_container = el,
number_container,
bullets_container,
timer_container,
idx = 0,
animate,
timer,
locked = false,
adjust_height_after = false;
self.slides = function () {
return slides_container.children(settings.slide_selector);
};
self.slides().first().addClass(settings.active_slide_class);
self.update_slide_number = function (index) {
if (settings.slide_number) {
number_container.find('span:first').text(parseInt(index) + 1);
number_container.find('span:last').text(self.slides().length);
}
if (settings.bullets) {
bullets_container.children().removeClass(settings.bullets_active_class);
$(bullets_container.children().get(index)).addClass(settings.bullets_active_class);
}
};
self.update_active_link = function (index) {
var link = $('[data-orbit-link="' + self.slides().eq(index).attr('data-orbit-slide') + '"]');
link.siblings().removeClass(settings.bullets_active_class);
link.addClass(settings.bullets_active_class);
};
self.build_markup = function () {
slides_container.wrap('<div class="' + settings.container_class + '"></div>');
container = slides_container.parent();
slides_container.addClass(settings.slides_container_class);
if (settings.stack_on_small) {
container.addClass(settings.stack_on_small_class);
}
if (settings.navigation_arrows) {
container.append($('<a href="#"><span></span></a>').addClass(settings.prev_class));
container.append($('<a href="#"><span></span></a>').addClass(settings.next_class));
}
if (settings.timer) {
timer_container = $('<div>').addClass(settings.timer_container_class);
timer_container.append('<span>');
timer_container.append($('<div>').addClass(settings.timer_progress_class));
timer_container.addClass(settings.timer_paused_class);
container.append(timer_container);
}
if (settings.slide_number) {
number_container = $('<div>').addClass(settings.slide_number_class);
number_container.append('<span></span> ' + settings.slide_number_text + ' <span></span>');
container.append(number_container);
}
if (settings.bullets) {
bullets_container = $('<ol>').addClass(settings.bullets_container_class);
container.append(bullets_container);
bullets_container.wrap('<div class="orbit-bullets-container"></div>');
self.slides().each(function (idx, el) {
var bullet = $('<li>').attr('data-orbit-slide', idx).on('click', self.link_bullet);;
bullets_container.append(bullet);
});
}
};
self._goto = function (next_idx, start_timer) {
// if (locked) {return false;}
if (next_idx === idx) {return false;}
if (typeof timer === 'object') {timer.restart();}
var slides = self.slides();
var dir = 'next';
locked = true;
if (next_idx < idx) {dir = 'prev';}
if (next_idx >= slides.length) {
if (!settings.circular) {
return false;
}
next_idx = 0;
} else if (next_idx < 0) {
if (!settings.circular) {
return false;
}
next_idx = slides.length - 1;
}
var current = $(slides.get(idx));
var next = $(slides.get(next_idx));
current.css('zIndex', 2);
current.removeClass(settings.active_slide_class);
next.css('zIndex', 4).addClass(settings.active_slide_class);
slides_container.trigger('before-slide-change.fndtn.orbit');
settings.before_slide_change();
self.update_active_link(next_idx);
var callback = function () {
var unlock = function () {
idx = next_idx;
locked = false;
if (start_timer === true) {timer = self.create_timer(); timer.start();}
self.update_slide_number(idx);
slides_container.trigger('after-slide-change.fndtn.orbit', [{slide_number : idx, total_slides : slides.length}]);
settings.after_slide_change(idx, slides.length);
};
if (slides_container.outerHeight() != next.outerHeight() && settings.variable_height) {
slides_container.animate({'height': next.outerHeight()}, 250, 'linear', unlock);
} else {
unlock();
}
};
if (slides.length === 1) {callback(); return false;}
var start_animation = function () {
if (dir === 'next') {animate.next(current, next, callback);}
if (dir === 'prev') {animate.prev(current, next, callback);}
};
if (next.outerHeight() > slides_container.outerHeight() && settings.variable_height) {
slides_container.animate({'height': next.outerHeight()}, 250, 'linear', start_animation);
} else {
start_animation();
}
};
self.next = function (e) {
e.stopImmediatePropagation();
e.preventDefault();
self._goto(idx + 1);
};
self.prev = function (e) {
e.stopImmediatePropagation();
e.preventDefault();
self._goto(idx - 1);
};
self.link_custom = function (e) {
e.preventDefault();
var link = $(this).attr('data-orbit-link');
if ((typeof link === 'string') && (link = $.trim(link)) != '') {
var slide = container.find('[data-orbit-slide=' + link + ']');
if (slide.index() != -1) {self._goto(slide.index());}
}
};
self.link_bullet = function (e) {
var index = $(this).attr('data-orbit-slide');
if ((typeof index === 'string') && (index = $.trim(index)) != '') {
if (isNaN(parseInt(index))) {
var slide = container.find('[data-orbit-slide=' + index + ']');
if (slide.index() != -1) {self._goto(slide.index() + 1);}
} else {
self._goto(parseInt(index));
}
}
}
self.timer_callback = function () {
self._goto(idx + 1, true);
}
self.compute_dimensions = function () {
var current = $(self.slides().get(idx));
var h = current.outerHeight();
if (!settings.variable_height) {
self.slides().each(function(){
if ($(this).outerHeight() > h) { h = $(this).outerHeight(); }
});
}
slides_container.height(h);
};
self.create_timer = function () {
var t = new Timer(
container.find('.' + settings.timer_container_class),
settings,
self.timer_callback
);
return t;
};
self.stop_timer = function () {
if (typeof timer === 'object') {
timer.stop();
}
};
self.toggle_timer = function () {
var t = container.find('.' + settings.timer_container_class);
if (t.hasClass(settings.timer_paused_class)) {
if (typeof timer === 'undefined') {timer = self.create_timer();}
timer.start();
} else {
if (typeof timer === 'object') {timer.stop();}
}
};
self.init = function () {
self.build_markup();
if (settings.timer) {
timer = self.create_timer();
Foundation.utils.image_loaded(this.slides().children('img'), timer.start);
}
animate = new FadeAnimation(settings, slides_container);
if (settings.animation === 'slide') {
animate = new SlideAnimation(settings, slides_container);
}
container.on('click', '.' + settings.next_class, self.next);
container.on('click', '.' + settings.prev_class, self.prev);
if (settings.next_on_click) {
container.on('click', '.' + settings.slides_container_class + ' [data-orbit-slide]', self.link_bullet);
}
container.on('click', self.toggle_timer);
if (settings.swipe) {
container.on('touchstart.fndtn.orbit', function (e) {
if (!e.touches) {e = e.originalEvent;}
var data = {
start_page_x : e.touches[0].pageX,
start_page_y : e.touches[0].pageY,
start_time : (new Date()).getTime(),
delta_x : 0,
is_scrolling : undefined
};
container.data('swipe-transition', data);
e.stopPropagation();
})
.on('touchmove.fndtn.orbit', function (e) {
if (!e.touches) {
e = e.originalEvent;
}
// Ignore pinch/zoom events
if (e.touches.length > 1 || e.scale && e.scale !== 1) {
return;
}
var data = container.data('swipe-transition');
if (typeof data === 'undefined') {data = {};}
data.delta_x = e.touches[0].pageX - data.start_page_x;
if ( typeof data.is_scrolling === 'undefined') {
data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
}
if (!data.is_scrolling && !data.active) {
e.preventDefault();
var direction = (data.delta_x < 0) ? (idx + 1) : (idx - 1);
data.active = true;
self._goto(direction);
}
})
.on('touchend.fndtn.orbit', function (e) {
container.data('swipe-transition', {});
e.stopPropagation();
})
}
container.on('mouseenter.fndtn.orbit', function (e) {
if (settings.timer && settings.pause_on_hover) {
self.stop_timer();
}
})
.on('mouseleave.fndtn.orbit', function (e) {
if (settings.timer && settings.resume_on_mouseout) {
timer.start();
}
});
$(document).on('click', '[data-orbit-link]', self.link_custom);
$(window).on('load resize', self.compute_dimensions);
Foundation.utils.image_loaded(this.slides().children('img'), self.compute_dimensions);
Foundation.utils.image_loaded(this.slides().children('img'), function () {
container.prev('.' + settings.preloader_class).css('display', 'none');
self.update_slide_number(0);
self.update_active_link(0);
slides_container.trigger('ready.fndtn.orbit');
});
};
self.init();
};
var Timer = function (el, settings, callback) {
var self = this,
duration = settings.timer_speed,
progress = el.find('.' + settings.timer_progress_class),
start,
timeout,
left = -1;
this.update_progress = function (w) {
var new_progress = progress.clone();
new_progress.attr('style', '');
new_progress.css('width', w + '%');
progress.replaceWith(new_progress);
progress = new_progress;
};
this.restart = function () {
clearTimeout(timeout);
el.addClass(settings.timer_paused_class);
left = -1;
self.update_progress(0);
};
this.start = function () {
if (!el.hasClass(settings.timer_paused_class)) {return true;}
left = (left === -1) ? duration : left;
el.removeClass(settings.timer_paused_class);
start = new Date().getTime();
progress.animate({'width' : '100%'}, left, 'linear');
timeout = setTimeout(function () {
self.restart();
callback();
}, left);
el.trigger('timer-started.fndtn.orbit')
};
this.stop = function () {
if (el.hasClass(settings.timer_paused_class)) {return true;}
clearTimeout(timeout);
el.addClass(settings.timer_paused_class);
var end = new Date().getTime();
left = left - (end - start);
var w = 100 - ((left / duration) * 100);
self.update_progress(w);
el.trigger('timer-stopped.fndtn.orbit');
};
};
var SlideAnimation = function (settings, container) {
var duration = settings.animation_speed;
var is_rtl = ($('html[dir=rtl]').length === 1);
var margin = is_rtl ? 'marginRight' : 'marginLeft';
var animMargin = {};
animMargin[margin] = '0%';
this.next = function (current, next, callback) {
current.animate({marginLeft : '-100%'}, duration);
next.animate(animMargin, duration, function () {
current.css(margin, '100%');
callback();
});
};
this.prev = function (current, prev, callback) {
current.animate({marginLeft : '100%'}, duration);
prev.css(margin, '-100%');
prev.animate(animMargin, duration, function () {
current.css(margin, '100%');
callback();
});
};
};
var FadeAnimation = function (settings, container) {
var duration = settings.animation_speed;
var is_rtl = ($('html[dir=rtl]').length === 1);
var margin = is_rtl ? 'marginRight' : 'marginLeft';
this.next = function (current, next, callback) {
next.css({'margin' : '0%', 'opacity' : '0.01'});
next.animate({'opacity' :'1'}, duration, 'linear', function () {
current.css('margin', '100%');
callback();
});
};
this.prev = function (current, prev, callback) {
prev.css({'margin' : '0%', 'opacity' : '0.01'});
prev.animate({'opacity' : '1'}, duration, 'linear', function () {
current.css('margin', '100%');
callback();
});
};
};
Foundation.libs = Foundation.libs || {};
Foundation.libs.orbit = {
name : 'orbit',
version : '5.5.2',
settings : {
animation : 'slide',
timer_speed : 10000,
pause_on_hover : true,
resume_on_mouseout : false,
next_on_click : true,
animation_speed : 500,
stack_on_small : false,
navigation_arrows : true,
slide_number : true,
slide_number_text : 'of',
container_class : 'orbit-container',
stack_on_small_class : 'orbit-stack-on-small',
next_class : 'orbit-next',
prev_class : 'orbit-prev',
timer_container_class : 'orbit-timer',
timer_paused_class : 'paused',
timer_progress_class : 'orbit-progress',
slides_container_class : 'orbit-slides-container',
preloader_class : 'preloader',
slide_selector : '*',
bullets_container_class : 'orbit-bullets',
bullets_active_class : 'active',
slide_number_class : 'orbit-slide-number',
caption_class : 'orbit-caption',
active_slide_class : 'active',
orbit_transition_class : 'orbit-transitioning',
bullets : true,
circular : true,
timer : true,
variable_height : false,
swipe : true,
before_slide_change : noop,
after_slide_change : noop
},
init : function (scope, method, options) {
var self = this;
this.bindings(method, options);
},
events : function (instance) {
var orbit_instance = new Orbit(this.S(instance), this.S(instance).data('orbit-init'));
this.S(instance).data(this.name + '-instance', orbit_instance);
},
reflow : function () {
var self = this;
if (self.S(self.scope).is('[data-orbit]')) {
var $el = self.S(self.scope);
var instance = $el.data(self.name + '-instance');
instance.compute_dimensions();
} else {
self.S('[data-orbit]', self.scope).each(function (idx, el) {
var $el = self.S(el);
var opts = self.data_options($el);
var instance = $el.data(self.name + '-instance');
instance.compute_dimensions();
});
}
}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,498 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.reveal = {
name : 'reveal',
version : '5.5.2',
locked : false,
settings : {
animation : 'fadeAndPop',
animation_speed : 250,
close_on_background_click : true,
close_on_esc : true,
dismiss_modal_class : 'close-reveal-modal',
multiple_opened : false,
bg_class : 'reveal-modal-bg',
root_element : 'body',
open : function(){},
opened : function(){},
close : function(){},
closed : function(){},
on_ajax_error: $.noop,
bg : $('.reveal-modal-bg'),
css : {
open : {
'opacity' : 0,
'visibility' : 'visible',
'display' : 'block'
},
close : {
'opacity' : 1,
'visibility' : 'hidden',
'display' : 'none'
}
}
},
init : function (scope, method, options) {
$.extend(true, this.settings, method, options);
this.bindings(method, options);
},
events : function (scope) {
var self = this,
S = self.S;
S(this.scope)
.off('.reveal')
.on('click.fndtn.reveal', '[' + this.add_namespace('data-reveal-id') + ']:not([disabled])', function (e) {
e.preventDefault();
if (!self.locked) {
var element = S(this),
ajax = element.data(self.data_attr('reveal-ajax')),
replaceContentSel = element.data(self.data_attr('reveal-replace-content'));
self.locked = true;
if (typeof ajax === 'undefined') {
self.open.call(self, element);
} else {
var url = ajax === true ? element.attr('href') : ajax;
self.open.call(self, element, {url : url}, { replaceContentSel : replaceContentSel });
}
}
});
S(document)
.on('click.fndtn.reveal', this.close_targets(), function (e) {
e.preventDefault();
if (!self.locked) {
var settings = S('[' + self.attr_name() + '].open').data(self.attr_name(true) + '-init') || self.settings,
bg_clicked = S(e.target)[0] === S('.' + settings.bg_class)[0];
if (bg_clicked) {
if (settings.close_on_background_click) {
e.stopPropagation();
} else {
return;
}
}
self.locked = true;
self.close.call(self, bg_clicked ? S('[' + self.attr_name() + '].open:not(.toback)') : S(this).closest('[' + self.attr_name() + ']'));
}
});
if (S('[' + self.attr_name() + ']', this.scope).length > 0) {
S(this.scope)
// .off('.reveal')
.on('open.fndtn.reveal', this.settings.open)
.on('opened.fndtn.reveal', this.settings.opened)
.on('opened.fndtn.reveal', this.open_video)
.on('close.fndtn.reveal', this.settings.close)
.on('closed.fndtn.reveal', this.settings.closed)
.on('closed.fndtn.reveal', this.close_video);
} else {
S(this.scope)
// .off('.reveal')
.on('open.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.open)
.on('opened.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.opened)
.on('opened.fndtn.reveal', '[' + self.attr_name() + ']', this.open_video)
.on('close.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.close)
.on('closed.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.closed)
.on('closed.fndtn.reveal', '[' + self.attr_name() + ']', this.close_video);
}
return true;
},
// PATCH #3: turning on key up capture only when a reveal window is open
key_up_on : function (scope) {
var self = this;
// PATCH #1: fixing multiple keyup event trigger from single key press
self.S('body').off('keyup.fndtn.reveal').on('keyup.fndtn.reveal', function ( event ) {
var open_modal = self.S('[' + self.attr_name() + '].open'),
settings = open_modal.data(self.attr_name(true) + '-init') || self.settings ;
// PATCH #2: making sure that the close event can be called only while unlocked,
// so that multiple keyup.fndtn.reveal events don't prevent clean closing of the reveal window.
if ( settings && event.which === 27 && settings.close_on_esc && !self.locked) { // 27 is the keycode for the Escape key
self.close.call(self, open_modal);
}
});
return true;
},
// PATCH #3: turning on key up capture only when a reveal window is open
key_up_off : function (scope) {
this.S('body').off('keyup.fndtn.reveal');
return true;
},
open : function (target, ajax_settings) {
var self = this,
modal;
if (target) {
if (typeof target.selector !== 'undefined') {
// Find the named node; only use the first one found, since the rest of the code assumes there's only one node
modal = self.S('#' + target.data(self.data_attr('reveal-id'))).first();
} else {
modal = self.S(this.scope);
ajax_settings = target;
}
} else {
modal = self.S(this.scope);
}
var settings = modal.data(self.attr_name(true) + '-init');
settings = settings || this.settings;
if (modal.hasClass('open') && target.attr('data-reveal-id') == modal.attr('id')) {
return self.close(modal);
}
if (!modal.hasClass('open')) {
var open_modal = self.S('[' + self.attr_name() + '].open');
if (typeof modal.data('css-top') === 'undefined') {
modal.data('css-top', parseInt(modal.css('top'), 10))
.data('offset', this.cache_offset(modal));
}
modal.attr('tabindex','0').attr('aria-hidden','false');
this.key_up_on(modal); // PATCH #3: turning on key up capture only when a reveal window is open
// Prevent namespace event from triggering twice
modal.on('open.fndtn.reveal', function(e) {
if (e.namespace !== 'fndtn.reveal') return;
});
modal.on('open.fndtn.reveal').trigger('open.fndtn.reveal');
if (open_modal.length < 1) {
this.toggle_bg(modal, true);
}
if (typeof ajax_settings === 'string') {
ajax_settings = {
url : ajax_settings
};
}
if (typeof ajax_settings === 'undefined' || !ajax_settings.url) {
if (open_modal.length > 0) {
if (settings.multiple_opened) {
self.to_back(open_modal);
} else {
self.hide(open_modal, settings.css.close);
}
}
this.show(modal, settings.css.open);
} else {
var old_success = typeof ajax_settings.success !== 'undefined' ? ajax_settings.success : null;
$.extend(ajax_settings, {
success : function (data, textStatus, jqXHR) {
if ( $.isFunction(old_success) ) {
var result = old_success(data, textStatus, jqXHR);
if (typeof result == 'string') {
data = result;
}
}
if (typeof options !== 'undefined' && typeof options.replaceContentSel !== 'undefined') {
modal.find(options.replaceContentSel).html(data);
} else {
modal.html(data);
}
self.S(modal).foundation('section', 'reflow');
self.S(modal).children().foundation();
if (open_modal.length > 0) {
if (settings.multiple_opened) {
self.to_back(open_modal);
} else {
self.hide(open_modal, settings.css.close);
}
}
self.show(modal, settings.css.open);
}
});
// check for if user initalized with error callback
if (settings.on_ajax_error !== $.noop) {
$.extend(ajax_settings, {
error : settings.on_ajax_error
});
}
$.ajax(ajax_settings);
}
}
self.S(window).trigger('resize');
},
close : function (modal) {
var modal = modal && modal.length ? modal : this.S(this.scope),
open_modals = this.S('[' + this.attr_name() + '].open'),
settings = modal.data(this.attr_name(true) + '-init') || this.settings,
self = this;
if (open_modals.length > 0) {
modal.removeAttr('tabindex','0').attr('aria-hidden','true');
this.locked = true;
this.key_up_off(modal); // PATCH #3: turning on key up capture only when a reveal window is open
modal.trigger('close.fndtn.reveal');
if ((settings.multiple_opened && open_modals.length === 1) || !settings.multiple_opened || modal.length > 1) {
self.toggle_bg(modal, false);
self.to_front(modal);
}
if (settings.multiple_opened) {
self.hide(modal, settings.css.close, settings);
self.to_front($($.makeArray(open_modals).reverse()[1]));
} else {
self.hide(open_modals, settings.css.close, settings);
}
}
},
close_targets : function () {
var base = '.' + this.settings.dismiss_modal_class;
if (this.settings.close_on_background_click) {
return base + ', .' + this.settings.bg_class;
}
return base;
},
toggle_bg : function (modal, state) {
if (this.S('.' + this.settings.bg_class).length === 0) {
this.settings.bg = $('<div />', {'class': this.settings.bg_class})
.appendTo('body').hide();
}
var visible = this.settings.bg.filter(':visible').length > 0;
if ( state != visible ) {
if ( state == undefined ? visible : !state ) {
this.hide(this.settings.bg);
} else {
this.show(this.settings.bg);
}
}
},
show : function (el, css) {
// is modal
if (css) {
var settings = el.data(this.attr_name(true) + '-init') || this.settings,
root_element = settings.root_element,
context = this;
if (el.parent(root_element).length === 0) {
var placeholder = el.wrap('<div style="display: none;" />').parent();
el.on('closed.fndtn.reveal.wrapped', function () {
el.detach().appendTo(placeholder);
el.unwrap().unbind('closed.fndtn.reveal.wrapped');
});
el.detach().appendTo(root_element);
}
var animData = getAnimationData(settings.animation);
if (!animData.animate) {
this.locked = false;
}
if (animData.pop) {
css.top = $(window).scrollTop() - el.data('offset') + 'px';
var end_css = {
top: $(window).scrollTop() + el.data('css-top') + 'px',
opacity: 1
};
return setTimeout(function () {
return el
.css(css)
.animate(end_css, settings.animation_speed, 'linear', function () {
context.locked = false;
el.trigger('opened.fndtn.reveal');
})
.addClass('open');
}, settings.animation_speed / 2);
}
if (animData.fade) {
css.top = $(window).scrollTop() + el.data('css-top') + 'px';
var end_css = {opacity: 1};
return setTimeout(function () {
return el
.css(css)
.animate(end_css, settings.animation_speed, 'linear', function () {
context.locked = false;
el.trigger('opened.fndtn.reveal');
})
.addClass('open');
}, settings.animation_speed / 2);
}
return el.css(css).show().css({opacity : 1}).addClass('open').trigger('opened.fndtn.reveal');
}
var settings = this.settings;
// should we animate the background?
if (getAnimationData(settings.animation).fade) {
return el.fadeIn(settings.animation_speed / 2);
}
this.locked = false;
return el.show();
},
to_back : function(el) {
el.addClass('toback');
},
to_front : function(el) {
el.removeClass('toback');
},
hide : function (el, css) {
// is modal
if (css) {
var settings = el.data(this.attr_name(true) + '-init'),
context = this;
settings = settings || this.settings;
var animData = getAnimationData(settings.animation);
if (!animData.animate) {
this.locked = false;
}
if (animData.pop) {
var end_css = {
top: - $(window).scrollTop() - el.data('offset') + 'px',
opacity: 0
};
return setTimeout(function () {
return el
.animate(end_css, settings.animation_speed, 'linear', function () {
context.locked = false;
el.css(css).trigger('closed.fndtn.reveal');
})
.removeClass('open');
}, settings.animation_speed / 2);
}
if (animData.fade) {
var end_css = {opacity : 0};
return setTimeout(function () {
return el
.animate(end_css, settings.animation_speed, 'linear', function () {
context.locked = false;
el.css(css).trigger('closed.fndtn.reveal');
})
.removeClass('open');
}, settings.animation_speed / 2);
}
return el.hide().css(css).removeClass('open').trigger('closed.fndtn.reveal');
}
var settings = this.settings;
// should we animate the background?
if (getAnimationData(settings.animation).fade) {
return el.fadeOut(settings.animation_speed / 2);
}
return el.hide();
},
close_video : function (e) {
var video = $('.flex-video', e.target),
iframe = $('iframe', video);
if (iframe.length > 0) {
iframe.attr('data-src', iframe[0].src);
iframe.attr('src', iframe.attr('src'));
video.hide();
}
},
open_video : function (e) {
var video = $('.flex-video', e.target),
iframe = video.find('iframe');
if (iframe.length > 0) {
var data_src = iframe.attr('data-src');
if (typeof data_src === 'string') {
iframe[0].src = iframe.attr('data-src');
} else {
var src = iframe[0].src;
iframe[0].src = undefined;
iframe[0].src = src;
}
video.show();
}
},
data_attr : function (str) {
if (this.namespace.length > 0) {
return this.namespace + '-' + str;
}
return str;
},
cache_offset : function (modal) {
var offset = modal.show().height() + parseInt(modal.css('top'), 10) + modal.scrollY;
modal.hide();
return offset;
},
off : function () {
$(this.scope).off('.fndtn.reveal');
},
reflow : function () {}
};
/*
* getAnimationData('popAndFade') // {animate: true, pop: true, fade: true}
* getAnimationData('fade') // {animate: true, pop: false, fade: true}
* getAnimationData('pop') // {animate: true, pop: true, fade: false}
* getAnimationData('foo') // {animate: false, pop: false, fade: false}
* getAnimationData(null) // {animate: false, pop: false, fade: false}
*/
function getAnimationData(str) {
var fade = /fade/i.test(str);
var pop = /pop/i.test(str);
return {
animate : fade || pop,
pop : pop,
fade : fade
};
}
}(jQuery, window, window.document));

View File

@ -0,0 +1,281 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.slider = {
name : 'slider',
version : '5.5.2',
settings : {
start : 0,
end : 100,
step : 1,
precision : null,
initial : null,
display_selector : '',
vertical : false,
trigger_input_change : false,
on_change : function () {}
},
cache : {},
init : function (scope, method, options) {
Foundation.inherit(this, 'throttle');
this.bindings(method, options);
this.reflow();
},
events : function () {
var self = this;
$(this.scope)
.off('.slider')
.on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider',
'[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function (e) {
if (!self.cache.active) {
e.preventDefault();
self.set_active_slider($(e.target));
}
})
.on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function (e) {
if (!!self.cache.active) {
e.preventDefault();
if ($.data(self.cache.active[0], 'settings').vertical) {
var scroll_offset = 0;
if (!e.pageY) {
scroll_offset = window.scrollY;
}
self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset);
} else {
self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x'));
}
}
})
.on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function (e) {
self.remove_active_slider();
})
.on('change.fndtn.slider', function (e) {
self.settings.on_change();
});
self.S(window)
.on('resize.fndtn.slider', self.throttle(function (e) {
self.reflow();
}, 300));
// update slider value as users change input value
this.S('[' + this.attr_name() + ']').each(function () {
var slider = $(this),
handle = slider.children('.range-slider-handle')[0],
settings = self.initialize_settings(handle);
if (settings.display_selector != '') {
$(settings.display_selector).each(function(){
if (this.hasOwnProperty('value')) {
$(this).change(function(){
// is there a better way to do this?
slider.foundation("slider", "set_value", $(this).val());
});
}
});
}
});
},
get_cursor_position : function (e, xy) {
var pageXY = 'page' + xy.toUpperCase(),
clientXY = 'client' + xy.toUpperCase(),
position;
if (typeof e[pageXY] !== 'undefined') {
position = e[pageXY];
} else if (typeof e.originalEvent[clientXY] !== 'undefined') {
position = e.originalEvent[clientXY];
} else if (e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0][clientXY] !== 'undefined') {
position = e.originalEvent.touches[0][clientXY];
} else if (e.currentPoint && typeof e.currentPoint[xy] !== 'undefined') {
position = e.currentPoint[xy];
}
return position;
},
set_active_slider : function ($handle) {
this.cache.active = $handle;
},
remove_active_slider : function () {
this.cache.active = null;
},
calculate_position : function ($handle, cursor_x) {
var self = this,
settings = $.data($handle[0], 'settings'),
handle_l = $.data($handle[0], 'handle_l'),
handle_o = $.data($handle[0], 'handle_o'),
bar_l = $.data($handle[0], 'bar_l'),
bar_o = $.data($handle[0], 'bar_o');
requestAnimationFrame(function () {
var pct;
if (Foundation.rtl && !settings.vertical) {
pct = self.limit_to(((bar_o + bar_l - cursor_x) / bar_l), 0, 1);
} else {
pct = self.limit_to(((cursor_x - bar_o) / bar_l), 0, 1);
}
pct = settings.vertical ? 1 - pct : pct;
var norm = self.normalized_value(pct, settings.start, settings.end, settings.step, settings.precision);
self.set_ui($handle, norm);
});
},
set_ui : function ($handle, value) {
var settings = $.data($handle[0], 'settings'),
handle_l = $.data($handle[0], 'handle_l'),
bar_l = $.data($handle[0], 'bar_l'),
norm_pct = this.normalized_percentage(value, settings.start, settings.end),
handle_offset = norm_pct * (bar_l - handle_l) - 1,
progress_bar_length = norm_pct * 100,
$handle_parent = $handle.parent(),
$hidden_inputs = $handle.parent().children('input[type=hidden]');
if (Foundation.rtl && !settings.vertical) {
handle_offset = -handle_offset;
}
handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset;
this.set_translate($handle, handle_offset, settings.vertical);
if (settings.vertical) {
$handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%');
} else {
$handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%');
}
$handle_parent.attr(this.attr_name(), value).trigger('change.fndtn.slider');
$hidden_inputs.val(value);
if (settings.trigger_input_change) {
$hidden_inputs.trigger('change.fndtn.slider');
}
if (!$handle[0].hasAttribute('aria-valuemin')) {
$handle.attr({
'aria-valuemin' : settings.start,
'aria-valuemax' : settings.end
});
}
$handle.attr('aria-valuenow', value);
if (settings.display_selector != '') {
$(settings.display_selector).each(function () {
if (this.hasAttribute('value')) {
$(this).val(value);
} else {
$(this).text(value);
}
});
}
},
normalized_percentage : function (val, start, end) {
return Math.min(1, (val - start) / (end - start));
},
normalized_value : function (val, start, end, step, precision) {
var range = end - start,
point = val * range,
mod = (point - (point % step)) / step,
rem = point % step,
round = ( rem >= step * 0.5 ? step : 0);
return ((mod * step + round) + start).toFixed(precision);
},
set_translate : function (ele, offset, vertical) {
if (vertical) {
$(ele)
.css('-webkit-transform', 'translateY(' + offset + 'px)')
.css('-moz-transform', 'translateY(' + offset + 'px)')
.css('-ms-transform', 'translateY(' + offset + 'px)')
.css('-o-transform', 'translateY(' + offset + 'px)')
.css('transform', 'translateY(' + offset + 'px)');
} else {
$(ele)
.css('-webkit-transform', 'translateX(' + offset + 'px)')
.css('-moz-transform', 'translateX(' + offset + 'px)')
.css('-ms-transform', 'translateX(' + offset + 'px)')
.css('-o-transform', 'translateX(' + offset + 'px)')
.css('transform', 'translateX(' + offset + 'px)');
}
},
limit_to : function (val, min, max) {
return Math.min(Math.max(val, min), max);
},
initialize_settings : function (handle) {
var settings = $.extend({}, this.settings, this.data_options($(handle).parent())),
decimal_places_match_result;
if (settings.precision === null) {
decimal_places_match_result = ('' + settings.step).match(/\.([\d]*)/);
settings.precision = decimal_places_match_result && decimal_places_match_result[1] ? decimal_places_match_result[1].length : 0;
}
if (settings.vertical) {
$.data(handle, 'bar_o', $(handle).parent().offset().top);
$.data(handle, 'bar_l', $(handle).parent().outerHeight());
$.data(handle, 'handle_o', $(handle).offset().top);
$.data(handle, 'handle_l', $(handle).outerHeight());
} else {
$.data(handle, 'bar_o', $(handle).parent().offset().left);
$.data(handle, 'bar_l', $(handle).parent().outerWidth());
$.data(handle, 'handle_o', $(handle).offset().left);
$.data(handle, 'handle_l', $(handle).outerWidth());
}
$.data(handle, 'bar', $(handle).parent());
return $.data(handle, 'settings', settings);
},
set_initial_position : function ($ele) {
var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'),
initial = ((typeof settings.initial == 'number' && !isNaN(settings.initial)) ? settings.initial : Math.floor((settings.end - settings.start) * 0.5 / settings.step) * settings.step + settings.start),
$handle = $ele.children('.range-slider-handle');
this.set_ui($handle, initial);
},
set_value : function (value) {
var self = this;
$('[' + self.attr_name() + ']', this.scope).each(function () {
$(this).attr(self.attr_name(), value);
});
if (!!$(this.scope).attr(self.attr_name())) {
$(this.scope).attr(self.attr_name(), value);
}
self.reflow();
},
reflow : function () {
var self = this;
self.S('[' + this.attr_name() + ']').each(function () {
var handle = $(this).children('.range-slider-handle')[0],
val = $(this).attr(self.attr_name());
self.initialize_settings(handle);
if (val) {
self.set_ui($(handle), parseFloat(val));
} else {
self.set_initial_position($(this));
}
});
}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,249 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.tab = {
name : 'tab',
version : '5.5.2',
settings : {
active_class : 'active',
callback : function () {},
deep_linking : false,
scroll_to_content : true,
is_hover : false
},
default_tab_hashes : [],
init : function (scope, method, options) {
var self = this,
S = this.S;
// Store the default active tabs which will be referenced when the
// location hash is absent, as in the case of navigating the tabs and
// returning to the first viewing via the browser Back button.
S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () {
self.default_tab_hashes.push(this.hash);
});
// store the initial href, which is used to allow correct behaviour of the
// browser back button when deep linking is turned on.
self.entry_location = window.location.href;
this.bindings(method, options);
this.handle_location_hash_change();
},
events : function () {
var self = this,
S = this.S;
var usual_tab_behavior = function (e, target) {
var settings = S(target).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
if (!settings.is_hover || Modernizr.touch) {
e.preventDefault();
e.stopPropagation();
self.toggle_active_tab(S(target).parent());
}
};
S(this.scope)
.off('.tab')
// Key event: focus/tab key
.on('keydown.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) {
var el = this;
var keyCode = e.keyCode || e.which;
// if user pressed tab key
if (keyCode == 9) {
e.preventDefault();
// TODO: Change usual_tab_behavior into accessibility function?
usual_tab_behavior(e, el);
}
})
// Click event: tab title
.on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) {
var el = this;
usual_tab_behavior(e, el);
})
// Hover event: tab title
.on('mouseenter.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) {
var settings = S(this).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init');
if (settings.is_hover) {
self.toggle_active_tab(S(this).parent());
}
});
// Location hash change event
S(window).on('hashchange.fndtn.tab', function (e) {
e.preventDefault();
self.handle_location_hash_change();
});
},
handle_location_hash_change : function () {
var self = this,
S = this.S;
S('[' + this.attr_name() + ']', this.scope).each(function () {
var settings = S(this).data(self.attr_name(true) + '-init');
if (settings.deep_linking) {
// Match the location hash to a label
var hash;
if (settings.scroll_to_content) {
hash = self.scope.location.hash;
} else {
// prefix the hash to prevent anchor scrolling
hash = self.scope.location.hash.replace('fndtn-', '');
}
if (hash != '') {
// Check whether the location hash references a tab content div or
// another element on the page (inside or outside the tab content div)
var hash_element = S(hash);
if (hash_element.hasClass('content') && hash_element.parent().hasClass('tabs-content')) {
// Tab content div
self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + hash + ']').parent());
} else {
// Not the tab content div. If inside the tab content, find the
// containing tab and toggle it as active.
var hash_tab_container_id = hash_element.closest('.content').attr('id');
if (hash_tab_container_id != undefined) {
self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=#' + hash_tab_container_id + ']').parent(), hash);
}
}
} else {
// Reference the default tab hashes which were initialized in the init function
for (var ind = 0; ind < self.default_tab_hashes.length; ind++) {
self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + self.default_tab_hashes[ind] + ']').parent());
}
}
}
});
},
toggle_active_tab : function (tab, location_hash) {
var self = this,
S = self.S,
tabs = tab.closest('[' + this.attr_name() + ']'),
tab_link = tab.find('a'),
anchor = tab.children('a').first(),
target_hash = '#' + anchor.attr('href').split('#')[1],
target = S(target_hash),
siblings = tab.siblings(),
settings = tabs.data(this.attr_name(true) + '-init'),
interpret_keyup_action = function (e) {
// Light modification of Heydon Pickering's Practical ARIA Examples: http://heydonworks.com/practical_aria_examples/js/a11y.js
// define current, previous and next (possible) tabs
var $original = $(this);
var $prev = $(this).parents('li').prev().children('[role="tab"]');
var $next = $(this).parents('li').next().children('[role="tab"]');
var $target;
// find the direction (prev or next)
switch (e.keyCode) {
case 37:
$target = $prev;
break;
case 39:
$target = $next;
break;
default:
$target = false
break;
}
if ($target.length) {
$original.attr({
'tabindex' : '-1',
'aria-selected' : null
});
$target.attr({
'tabindex' : '0',
'aria-selected' : true
}).focus();
}
// Hide panels
$('[role="tabpanel"]')
.attr('aria-hidden', 'true');
// Show panel which corresponds to target
$('#' + $(document.activeElement).attr('href').substring(1))
.attr('aria-hidden', null);
},
go_to_hash = function(hash) {
// This function allows correct behaviour of the browser's back button when deep linking is enabled. Without it
// the user would get continually redirected to the default hash.
var is_entry_location = window.location.href === self.entry_location,
default_hash = settings.scroll_to_content ? self.default_tab_hashes[0] : is_entry_location ? window.location.hash :'fndtn-' + self.default_tab_hashes[0].replace('#', '')
if (!(is_entry_location && hash === default_hash)) {
window.location.hash = hash;
}
};
// allow usage of data-tab-content attribute instead of href
if (anchor.data('tab-content')) {
target_hash = '#' + anchor.data('tab-content').split('#')[1];
target = S(target_hash);
}
if (settings.deep_linking) {
if (settings.scroll_to_content) {
// retain current hash to scroll to content
go_to_hash(location_hash || target_hash);
if (location_hash == undefined || location_hash == target_hash) {
tab.parent()[0].scrollIntoView();
} else {
S(target_hash)[0].scrollIntoView();
}
} else {
// prefix the hashes so that the browser doesn't scroll down
if (location_hash != undefined) {
go_to_hash('fndtn-' + location_hash.replace('#', ''));
} else {
go_to_hash('fndtn-' + target_hash.replace('#', ''));
}
}
}
// WARNING: The activation and deactivation of the tab content must
// occur after the deep linking in order to properly refresh the browser
// window (notably in Chrome).
// Clean up multiple attr instances to done once
tab.addClass(settings.active_class).triggerHandler('opened');
tab_link.attr({'aria-selected' : 'true', tabindex : 0});
siblings.removeClass(settings.active_class)
siblings.find('a').attr({'aria-selected' : 'false', tabindex : -1});
target.siblings().removeClass(settings.active_class).attr({'aria-hidden' : 'true', tabindex : -1});
target.addClass(settings.active_class).attr('aria-hidden', 'false').removeAttr('tabindex');
settings.callback(tab);
target.triggerHandler('toggled', [target]);
tabs.triggerHandler('toggled', [tab]);
tab_link.off('keydown').on('keydown', interpret_keyup_action );
},
data_attr : function (str) {
if (this.namespace.length > 0) {
return this.namespace + '-' + str;
}
return str;
},
off : function () {},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,339 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.tooltip = {
name : 'tooltip',
version : '5.5.2',
settings : {
additional_inheritable_classes : [],
tooltip_class : '.tooltip',
append_to : 'body',
touch_close_text : 'Tap To Close',
disable_for_touch : false,
hover_delay : 200,
show_on : 'all',
tip_template : function (selector, content) {
return '<span data-selector="' + selector + '" id="' + selector + '" class="'
+ Foundation.libs.tooltip.settings.tooltip_class.substring(1)
+ '" role="tooltip">' + content + '<span class="nub"></span></span>';
}
},
cache : {},
init : function (scope, method, options) {
Foundation.inherit(this, 'random_str');
this.bindings(method, options);
},
should_show : function (target, tip) {
var settings = $.extend({}, this.settings, this.data_options(target));
if (settings.show_on === 'all') {
return true;
} else if (this.small() && settings.show_on === 'small') {
return true;
} else if (this.medium() && settings.show_on === 'medium') {
return true;
} else if (this.large() && settings.show_on === 'large') {
return true;
}
return false;
},
medium : function () {
return matchMedia(Foundation.media_queries['medium']).matches;
},
large : function () {
return matchMedia(Foundation.media_queries['large']).matches;
},
events : function (instance) {
var self = this,
S = self.S;
self.create(this.S(instance));
function _startShow(elt, $this, immediate) {
if (elt.timer) {
return;
}
if (immediate) {
elt.timer = null;
self.showTip($this);
} else {
elt.timer = setTimeout(function () {
elt.timer = null;
self.showTip($this);
}.bind(elt), self.settings.hover_delay);
}
}
function _startHide(elt, $this) {
if (elt.timer) {
clearTimeout(elt.timer);
elt.timer = null;
}
self.hide($this);
}
$(this.scope)
.off('.tooltip')
.on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip',
'[' + this.attr_name() + ']', function (e) {
var $this = S(this),
settings = $.extend({}, self.settings, self.data_options($this)),
is_touch = false;
if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type) && S(e.target).is('a')) {
return false;
}
if (/mouse/i.test(e.type) && self.ie_touch(e)) {
return false;
}
if ($this.hasClass('open')) {
if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
e.preventDefault();
}
self.hide($this);
} else {
if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
return;
} else if (!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) {
e.preventDefault();
S(settings.tooltip_class + '.open').hide();
is_touch = true;
// close other open tooltips on touch
if ($('.open[' + self.attr_name() + ']').length > 0) {
var prevOpen = S($('.open[' + self.attr_name() + ']')[0]);
self.hide(prevOpen);
}
}
if (/enter|over/i.test(e.type)) {
_startShow(this, $this);
} else if (e.type === 'mouseout' || e.type === 'mouseleave') {
_startHide(this, $this);
} else {
_startShow(this, $this, true);
}
}
})
.on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) {
if (/mouse/i.test(e.type) && self.ie_touch(e)) {
return false;
}
if ($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') {
return;
} else if ($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) {
self.convert_to_touch($(this));
} else {
_startHide(this, $(this));
}
})
.on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) {
_startHide(this, S(this));
});
},
ie_touch : function (e) {
// How do I distinguish between IE11 and Windows Phone 8?????
return false;
},
showTip : function ($target) {
var $tip = this.getTip($target);
if (this.should_show($target, $tip)) {
return this.show($target);
}
return;
},
getTip : function ($target) {
var selector = this.selector($target),
settings = $.extend({}, this.settings, this.data_options($target)),
tip = null;
if (selector) {
tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class);
}
return (typeof tip === 'object') ? tip : false;
},
selector : function ($target) {
var dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector');
if (typeof dataSelector != 'string') {
dataSelector = this.random_str(6);
$target
.attr('data-selector', dataSelector)
.attr('aria-describedby', dataSelector);
}
return dataSelector;
},
create : function ($target) {
var self = this,
settings = $.extend({}, this.settings, this.data_options($target)),
tip_template = this.settings.tip_template;
if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) {
tip_template = window[settings.tip_template];
}
var $tip = $(tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())),
classes = this.inheritable_classes($target);
$tip.addClass(classes).appendTo(settings.append_to);
if (Modernizr.touch) {
$tip.append('<span class="tap-to-close">' + settings.touch_close_text + '</span>');
$tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function (e) {
self.hide($target);
});
}
$target.removeAttr('title').attr('title', '');
},
reposition : function (target, tip, classes) {
var width, nub, nubHeight, nubWidth, column, objPos;
tip.css('visibility', 'hidden').show();
width = target.data('width');
nub = tip.children('.nub');
nubHeight = nub.outerHeight();
nubWidth = nub.outerHeight();
if (this.small()) {
tip.css({'width' : '100%'});
} else {
tip.css({'width' : (width) ? width : 'auto'});
}
objPos = function (obj, top, right, bottom, left, width) {
return obj.css({
'top' : (top) ? top : 'auto',
'bottom' : (bottom) ? bottom : 'auto',
'left' : (left) ? left : 'auto',
'right' : (right) ? right : 'auto'
}).end();
};
objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left);
if (this.small()) {
objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
tip.addClass('tip-override');
objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
} else {
var left = target.offset().left;
if (Foundation.rtl) {
nub.addClass('rtl');
left = target.offset().left + target.outerWidth() - tip.outerWidth();
}
objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left);
// reset nub from small styles, if they've been applied
if (nub.attr('style')) {
nub.removeAttr('style');
}
tip.removeClass('tip-override');
if (classes && classes.indexOf('tip-top') > -1) {
if (Foundation.rtl) {
nub.addClass('rtl');
}
objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left)
.removeClass('tip-override');
} else if (classes && classes.indexOf('tip-left') > -1) {
objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight))
.removeClass('tip-override');
nub.removeClass('rtl');
} else if (classes && classes.indexOf('tip-right') > -1) {
objPos(tip, (target.offset().top + (target.outerHeight() / 2) - (tip.outerHeight() / 2)), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight))
.removeClass('tip-override');
nub.removeClass('rtl');
}
}
tip.css('visibility', 'visible').hide();
},
small : function () {
return matchMedia(Foundation.media_queries.small).matches &&
!matchMedia(Foundation.media_queries.medium).matches;
},
inheritable_classes : function ($target) {
var settings = $.extend({}, this.settings, this.data_options($target)),
inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes),
classes = $target.attr('class'),
filtered = classes ? $.map(classes.split(' '), function (el, i) {
if ($.inArray(el, inheritables) !== -1) {
return el;
}
}).join(' ') : '';
return $.trim(filtered);
},
convert_to_touch : function ($target) {
var self = this,
$tip = self.getTip($target),
settings = $.extend({}, self.settings, self.data_options($target));
if ($tip.find('.tap-to-close').length === 0) {
$tip.append('<span class="tap-to-close">' + settings.touch_close_text + '</span>');
$tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function (e) {
self.hide($target);
});
}
$target.data('tooltip-open-event-type', 'touch');
},
show : function ($target) {
var $tip = this.getTip($target);
if ($target.data('tooltip-open-event-type') == 'touch') {
this.convert_to_touch($target);
}
this.reposition($target, $tip, $target.attr('class'));
$target.addClass('open');
$tip.fadeIn(150);
},
hide : function ($target) {
var $tip = this.getTip($target);
$tip.fadeOut(150, function () {
$tip.find('.tap-to-close').remove();
$tip.off('click.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose');
$target.removeClass('open');
});
},
off : function () {
var self = this;
this.S(this.scope).off('.fndtn.tooltip');
this.S(this.settings.tooltip_class).each(function (i) {
$('[' + self.attr_name() + ']').eq(i).attr('title', $(this).text());
}).remove();
},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -0,0 +1,458 @@
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.topbar = {
name : 'topbar',
version : '5.5.2',
settings : {
index : 0,
start_offset : 0,
sticky_class : 'sticky',
custom_back_text : true,
back_text : 'Back',
mobile_show_parent_link : true,
is_hover : true,
scrolltop : true, // jump to top when sticky nav menu toggle is clicked
sticky_on : 'all',
dropdown_autoclose: true
},
init : function (section, method, options) {
Foundation.inherit(this, 'add_custom_rule register_media throttle');
var self = this;
self.register_media('topbar', 'foundation-mq-topbar');
this.bindings(method, options);
self.S('[' + this.attr_name() + ']', this.scope).each(function () {
var topbar = $(this),
settings = topbar.data(self.attr_name(true) + '-init'),
section = self.S('section, .top-bar-section', this);
topbar.data('index', 0);
var topbarContainer = topbar.parent();
if (topbarContainer.hasClass('fixed') || self.is_sticky(topbar, topbarContainer, settings) ) {
self.settings.sticky_class = settings.sticky_class;
self.settings.sticky_topbar = topbar;
topbar.data('height', topbarContainer.outerHeight());
topbar.data('stickyoffset', topbarContainer.offset().top);
} else {
topbar.data('height', topbar.outerHeight());
}
if (!settings.assembled) {
self.assemble(topbar);
}
if (settings.is_hover) {
self.S('.has-dropdown', topbar).addClass('not-click');
} else {
self.S('.has-dropdown', topbar).removeClass('not-click');
}
// Pad body when sticky (scrolled) or fixed.
self.add_custom_rule('.f-topbar-fixed { padding-top: ' + topbar.data('height') + 'px }');
if (topbarContainer.hasClass('fixed')) {
self.S('body').addClass('f-topbar-fixed');
}
});
},
is_sticky : function (topbar, topbarContainer, settings) {
var sticky = topbarContainer.hasClass(settings.sticky_class);
var smallMatch = matchMedia(Foundation.media_queries.small).matches;
var medMatch = matchMedia(Foundation.media_queries.medium).matches;
var lrgMatch = matchMedia(Foundation.media_queries.large).matches;
if (sticky && settings.sticky_on === 'all') {
return true;
}
if (sticky && this.small() && settings.sticky_on.indexOf('small') !== -1) {
if (smallMatch && !medMatch && !lrgMatch) { return true; }
}
if (sticky && this.medium() && settings.sticky_on.indexOf('medium') !== -1) {
if (smallMatch && medMatch && !lrgMatch) { return true; }
}
if (sticky && this.large() && settings.sticky_on.indexOf('large') !== -1) {
if (smallMatch && medMatch && lrgMatch) { return true; }
}
return false;
},
toggle : function (toggleEl) {
var self = this,
topbar;
if (toggleEl) {
topbar = self.S(toggleEl).closest('[' + this.attr_name() + ']');
} else {
topbar = self.S('[' + this.attr_name() + ']');
}
var settings = topbar.data(this.attr_name(true) + '-init');
var section = self.S('section, .top-bar-section', topbar);
if (self.breakpoint()) {
if (!self.rtl) {
section.css({left : '0%'});
$('>.name', section).css({left : '100%'});
} else {
section.css({right : '0%'});
$('>.name', section).css({right : '100%'});
}
self.S('li.moved', section).removeClass('moved');
topbar.data('index', 0);
topbar
.toggleClass('expanded')
.css('height', '');
}
if (settings.scrolltop) {
if (!topbar.hasClass('expanded')) {
if (topbar.hasClass('fixed')) {
topbar.parent().addClass('fixed');
topbar.removeClass('fixed');
self.S('body').addClass('f-topbar-fixed');
}
} else if (topbar.parent().hasClass('fixed')) {
if (settings.scrolltop) {
topbar.parent().removeClass('fixed');
topbar.addClass('fixed');
self.S('body').removeClass('f-topbar-fixed');
window.scrollTo(0, 0);
} else {
topbar.parent().removeClass('expanded');
}
}
} else {
if (self.is_sticky(topbar, topbar.parent(), settings)) {
topbar.parent().addClass('fixed');
}
if (topbar.parent().hasClass('fixed')) {
if (!topbar.hasClass('expanded')) {
topbar.removeClass('fixed');
topbar.parent().removeClass('expanded');
self.update_sticky_positioning();
} else {
topbar.addClass('fixed');
topbar.parent().addClass('expanded');
self.S('body').addClass('f-topbar-fixed');
}
}
}
},
timer : null,
events : function (bar) {
var self = this,
S = this.S;
S(this.scope)
.off('.topbar')
.on('click.fndtn.topbar', '[' + this.attr_name() + '] .toggle-topbar', function (e) {
e.preventDefault();
self.toggle(this);
})
.on('click.fndtn.topbar contextmenu.fndtn.topbar', '.top-bar .top-bar-section li a[href^="#"],[' + this.attr_name() + '] .top-bar-section li a[href^="#"]', function (e) {
var li = $(this).closest('li'),
topbar = li.closest('[' + self.attr_name() + ']'),
settings = topbar.data(self.attr_name(true) + '-init');
if (settings.dropdown_autoclose && settings.is_hover) {
var hoverLi = $(this).closest('.hover');
hoverLi.removeClass('hover');
}
if (self.breakpoint() && !li.hasClass('back') && !li.hasClass('has-dropdown')) {
self.toggle();
}
})
.on('click.fndtn.topbar', '[' + this.attr_name() + '] li.has-dropdown', function (e) {
var li = S(this),
target = S(e.target),
topbar = li.closest('[' + self.attr_name() + ']'),
settings = topbar.data(self.attr_name(true) + '-init');
if (target.data('revealId')) {
self.toggle();
return;
}
if (self.breakpoint()) {
return;
}
if (settings.is_hover && !Modernizr.touch) {
return;
}
e.stopImmediatePropagation();
if (li.hasClass('hover')) {
li
.removeClass('hover')
.find('li')
.removeClass('hover');
li.parents('li.hover')
.removeClass('hover');
} else {
li.addClass('hover');
$(li).siblings().removeClass('hover');
if (target[0].nodeName === 'A' && target.parent().hasClass('has-dropdown')) {
e.preventDefault();
}
}
})
.on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown>a', function (e) {
if (self.breakpoint()) {
e.preventDefault();
var $this = S(this),
topbar = $this.closest('[' + self.attr_name() + ']'),
section = topbar.find('section, .top-bar-section'),
dropdownHeight = $this.next('.dropdown').outerHeight(),
$selectedLi = $this.closest('li');
topbar.data('index', topbar.data('index') + 1);
$selectedLi.addClass('moved');
if (!self.rtl) {
section.css({left : -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({left : 100 * topbar.data('index') + '%'});
} else {
section.css({right : -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({right : 100 * topbar.data('index') + '%'});
}
topbar.css('height', $this.siblings('ul').outerHeight(true) + topbar.data('height'));
}
});
S(window).off('.topbar').on('resize.fndtn.topbar', self.throttle(function () {
self.resize.call(self);
}, 50)).trigger('resize.fndtn.topbar').load(function () {
// Ensure that the offset is calculated after all of the pages resources have loaded
S(this).trigger('resize.fndtn.topbar');
});
S('body').off('.topbar').on('click.fndtn.topbar', function (e) {
var parent = S(e.target).closest('li').closest('li.hover');
if (parent.length > 0) {
return;
}
S('[' + self.attr_name() + '] li.hover').removeClass('hover');
});
// Go up a level on Click
S(this.scope).on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown .back', function (e) {
e.preventDefault();
var $this = S(this),
topbar = $this.closest('[' + self.attr_name() + ']'),
section = topbar.find('section, .top-bar-section'),
settings = topbar.data(self.attr_name(true) + '-init'),
$movedLi = $this.closest('li.moved'),
$previousLevelUl = $movedLi.parent();
topbar.data('index', topbar.data('index') - 1);
if (!self.rtl) {
section.css({left : -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({left : 100 * topbar.data('index') + '%'});
} else {
section.css({right : -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({right : 100 * topbar.data('index') + '%'});
}
if (topbar.data('index') === 0) {
topbar.css('height', '');
} else {
topbar.css('height', $previousLevelUl.outerHeight(true) + topbar.data('height'));
}
setTimeout(function () {
$movedLi.removeClass('moved');
}, 300);
});
// Show dropdown menus when their items are focused
S(this.scope).find('.dropdown a')
.focus(function () {
$(this).parents('.has-dropdown').addClass('hover');
})
.blur(function () {
$(this).parents('.has-dropdown').removeClass('hover');
});
},
resize : function () {
var self = this;
self.S('[' + this.attr_name() + ']').each(function () {
var topbar = self.S(this),
settings = topbar.data(self.attr_name(true) + '-init');
var stickyContainer = topbar.parent('.' + self.settings.sticky_class);
var stickyOffset;
if (!self.breakpoint()) {
var doToggle = topbar.hasClass('expanded');
topbar
.css('height', '')
.removeClass('expanded')
.find('li')
.removeClass('hover');
if (doToggle) {
self.toggle(topbar);
}
}
if (self.is_sticky(topbar, stickyContainer, settings)) {
if (stickyContainer.hasClass('fixed')) {
// Remove the fixed to allow for correct calculation of the offset.
stickyContainer.removeClass('fixed');
stickyOffset = stickyContainer.offset().top;
if (self.S(document.body).hasClass('f-topbar-fixed')) {
stickyOffset -= topbar.data('height');
}
topbar.data('stickyoffset', stickyOffset);
stickyContainer.addClass('fixed');
} else {
stickyOffset = stickyContainer.offset().top;
topbar.data('stickyoffset', stickyOffset);
}
}
});
},
breakpoint : function () {
return !matchMedia(Foundation.media_queries['topbar']).matches;
},
small : function () {
return matchMedia(Foundation.media_queries['small']).matches;
},
medium : function () {
return matchMedia(Foundation.media_queries['medium']).matches;
},
large : function () {
return matchMedia(Foundation.media_queries['large']).matches;
},
assemble : function (topbar) {
var self = this,
settings = topbar.data(this.attr_name(true) + '-init'),
section = self.S('section, .top-bar-section', topbar);
// Pull element out of the DOM for manipulation
section.detach();
self.S('.has-dropdown>a', section).each(function () {
var $link = self.S(this),
$dropdown = $link.siblings('.dropdown'),
url = $link.attr('href'),
$titleLi;
if (!$dropdown.find('.title.back').length) {
if (settings.mobile_show_parent_link == true && url) {
$titleLi = $('<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5></li><li class="parent-link hide-for-medium-up"><a class="parent-link js-generated" href="' + url + '">' + $link.html() +'</a></li>');
} else {
$titleLi = $('<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5>');
}
// Copy link to subnav
if (settings.custom_back_text == true) {
$('h5>a', $titleLi).html(settings.back_text);
} else {
$('h5>a', $titleLi).html('&laquo; ' + $link.html());
}
$dropdown.prepend($titleLi);
}
});
// Put element back in the DOM
section.appendTo(topbar);
// check for sticky
this.sticky();
this.assembled(topbar);
},
assembled : function (topbar) {
topbar.data(this.attr_name(true), $.extend({}, topbar.data(this.attr_name(true)), {assembled : true}));
},
height : function (ul) {
var total = 0,
self = this;
$('> li', ul).each(function () {
total += self.S(this).outerHeight(true);
});
return total;
},
sticky : function () {
var self = this;
this.S(window).on('scroll', function () {
self.update_sticky_positioning();
});
},
update_sticky_positioning : function () {
var klass = '.' + this.settings.sticky_class,
$window = this.S(window),
self = this;
if (self.settings.sticky_topbar && self.is_sticky(this.settings.sticky_topbar,this.settings.sticky_topbar.parent(), this.settings)) {
var distance = this.settings.sticky_topbar.data('stickyoffset') + this.settings.start_offset;
if (!self.S(klass).hasClass('expanded')) {
if ($window.scrollTop() > (distance)) {
if (!self.S(klass).hasClass('fixed')) {
self.S(klass).addClass('fixed');
self.S('body').addClass('f-topbar-fixed');
}
} else if ($window.scrollTop() <= distance) {
if (self.S(klass).hasClass('fixed')) {
self.S(klass).removeClass('fixed');
self.S('body').removeClass('f-topbar-fixed');
}
}
}
}
},
off : function () {
this.S(this.scope).off('.fndtn.topbar');
this.S(window).off('.fndtn.topbar');
},
reflow : function () {}
};
}(jQuery, window, window.document));

View File

@ -347,12 +347,12 @@ function connedit_content(&$a) {
$o .= "<script>function connectDefaultShare() { $o .= "<script>function connectDefaultShare() {
\$('.abook-edit-me').each(function() { \$('.abook-edit-me').each(function() {
if(! $(this).is(':disabled')) if(! $(this).is(':disabled'))
$(this).removeAttr('checked'); $(this).prop('checked', false);
});\n\n"; });\n\n";
$perms = get_perms(); $perms = get_perms();
foreach($perms as $p => $v) { foreach($perms as $p => $v) {
if($my_perms & $v[1]) { if($my_perms & $v[1]) {
$o .= "\$('#me_id_perms_" . $p . "').attr('checked','checked'); \n"; $o .= "\$('#me_id_perms_" . $p . "').prop('checked', true); \n";
} }
} }
$o .= " }\n</script>\n"; $o .= " }\n</script>\n";

View File

@ -1,40 +1,53 @@
<?php <?php
/**
* @file mod/setup.php
*
* Controller for the initial setup/installation.
*
* @todo This setup module could need some love and improvements.
*/
$install_wizard_pass=1; $install_wizard_pass = 1;
/**
* @brief Initialisation for the setup module.
*
* @param[in,out] App &$a
*/
function setup_init(&$a){ function setup_init(&$a){
// Ensure that if somebody hasn't read the install documentation and doesn't have all // Ensure that if somebody hasn't read the install documentation and doesn't have all
// the required modules or has a totally borked shared hosting provider and they can't // the required modules or has a totally borked shared hosting provider and they can't
// figure out what the hell is going on - that we at least spit out an error message which // figure out what the hell is going on - that we at least spit out an error message which
// we can inquire about when they write to tell us that our software doesn't work. // we can inquire about when they write to tell us that our software doesn't work.
// The worst thing we can do at this point is throw a white screen of death and rely on // The worst thing we can do at this point is throw a white screen of death and rely on
// them knowing about servers and php modules and logfiles enough so that we can guess // them knowing about servers and php modules and logfiles enough so that we can guess
// at the source of the problem. As ugly as it may be, we need to throw a technically worded // at the source of the problem. As ugly as it may be, we need to throw a technically worded
// PHP error message in their face. Once installation is complete application errors will // PHP error message in their face. Once installation is complete application errors will
// throw a white screen because these error messages divulge information which can // throw a white screen because these error messages divulge information which can
// potentially be useful to hackers. // potentially be useful to hackers.
error_reporting(E_ERROR | E_WARNING | E_PARSE );
error_reporting(E_ERROR | E_WARNING | E_PARSE ); ini_set('log_errors', '0');
ini_set('log_errors','0');
ini_set('display_errors', '1'); ini_set('display_errors', '1');
// $baseurl/setup/testrwrite to test if rewite in .htaccess is working // $baseurl/setup/testrwrite to test if rewite in .htaccess is working
if (argc() ==2 && argv(1)=="testrewrite") { if (argc() == 2 && argv(1) == "testrewrite") {
echo "ok"; echo 'ok';
killme(); killme();
} }
global $install_wizard_pass; global $install_wizard_pass;
if (x($_POST,'pass')) if (x($_POST, 'pass'))
$install_wizard_pass = intval($_POST['pass']); $install_wizard_pass = intval($_POST['pass']);
} }
/**
* @brief Handle the actions of the different setup steps.
*
* @param[in,out] App &$a
*/
function setup_post(&$a) { function setup_post(&$a) {
global $install_wizard_pass, $db; global $install_wizard_pass, $db;
@ -58,8 +71,9 @@ function setup_post(&$a) {
require_once('include/dba/dba_driver.php'); require_once('include/dba/dba_driver.php');
unset($db); unset($db);
$db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true); $db = dba_factory($dbhost, $dbport, $dbuser, $dbpass, $dbdata, $dbtype, true);
if(! $db->connected) { if(! $db->connected) {
echo "Database Connect failed: " . $db->error; echo 'Database Connect failed: ' . $db->error;
killme(); killme();
$a->data['db_conn_failed']=true; $a->data['db_conn_failed']=true;
} }
@ -83,10 +97,10 @@ function setup_post(&$a) {
} }
}*/ }*/
//if(get_db_errno()) { //if(get_db_errno()) {
//} //}
return; return;
break; break;
case 4: case 4:
$urlpath = $a->get_path(); $urlpath = $a->get_path();
@ -100,10 +114,9 @@ function setup_post(&$a) {
$timezone = notags(trim($_POST['timezone'])); $timezone = notags(trim($_POST['timezone']));
$adminmail = notags(trim($_POST['adminmail'])); $adminmail = notags(trim($_POST['adminmail']));
$siteurl = notags(trim($_POST['siteurl'])); $siteurl = notags(trim($_POST['siteurl']));
if($siteurl != z_root()) { if($siteurl != z_root()) {
$test = z_fetch_url($siteurl."/setup/testrewrite"); $test = z_fetch_url($siteurl."/setup/testrewrite");
if((! $test['success']) || ($test['body'] != 'ok')) { if((! $test['success']) || ($test['body'] != 'ok')) {
$a->data['url_fail'] = true; $a->data['url_fail'] = true;
$a->data['url_error'] = $test['error']; $a->data['url_error'] = $test['error'];
@ -147,7 +160,7 @@ function setup_post(&$a) {
$a->data['db_installed'] = true; $a->data['db_installed'] = true;
return; return;
break; break;
} }
} }
@ -156,45 +169,50 @@ function get_db_errno() {
return mysqli_connect_errno(); return mysqli_connect_errno();
else else
return mysql_errno(); return mysql_errno();
} }
/**
* @brief Get output for the setup page.
*
* Depending on the state we are currently in it returns different content.
*
* @param App &$a
* @return string parsed HTML output
*/
function setup_content(&$a) { function setup_content(&$a) {
global $install_wizard_pass, $db; global $install_wizard_pass, $db;
$o = ''; $o = '';
$wizard_status = ""; $wizard_status = '';
$install_title = t('$Projectname Server - Setup'); $install_title = t('$Projectname Server - Setup');
if(x($a->data,'db_conn_failed')) { if(x($a->data, 'db_conn_failed')) {
$install_wizard_pass = 2; $install_wizard_pass = 2;
$wizard_status = t('Could not connect to database.'); $wizard_status = t('Could not connect to database.');
} }
if(x($a->data,'url_fail')) { if(x($a->data, 'url_fail')) {
$install_wizard_pass = 3; $install_wizard_pass = 3;
$wizard_status = t('Could not connect to specified site URL. Possible SSL certificate or DNS issue.'); $wizard_status = t('Could not connect to specified site URL. Possible SSL certificate or DNS issue.');
if($a->data['url_error']) if($a->data['url_error'])
$wizard_status .= ' ' . $a->data['url_error']; $wizard_status .= ' ' . $a->data['url_error'];
} }
if(x($a->data,'db_create_failed')) { if(x($a->data, 'db_create_failed')) {
$install_wizard_pass = 2; $install_wizard_pass = 2;
$wizard_status = t('Could not create table.'); $wizard_status = t('Could not create table.');
} }
$db_return_text = '';
$db_return_text=""; if(x($a->data, 'db_installed')) {
if(x($a->data,'db_installed')) {
$txt = '<p style="font-size: 130%;">'; $txt = '<p style="font-size: 130%;">';
$txt .= t('Your site database has been installed.') . EOL; $txt .= t('Your site database has been installed.') . EOL;
$db_return_text .= $txt; $db_return_text .= $txt;
} }
if(x($a->data, 'db_failed')) {
if(x($a->data,'db_failed')) {
$txt = t('You may need to import the file "install/schema_xxx.sql" manually using a database client.') . EOL; $txt = t('You may need to import the file "install/schema_xxx.sql" manually using a database client.') . EOL;
$txt .= t('Please see the file "install/INSTALL.txt".') . EOL ."<hr>" ; $txt .= t('Please see the file "install/INSTALL.txt".') . EOL ."<hr>" ;
$txt .= "<pre>".$a->data['db_failed'] . "</pre>". EOL ; $txt .= "<pre>".$a->data['db_failed'] . "</pre>". EOL ;
$db_return_text .= $txt; $db_return_text .= $txt;
} }
if($db && $db->connected) { if($db && $db->connected) {
$r = q("SELECT COUNT(*) as `total` FROM `account`"); $r = q("SELECT COUNT(*) as `total` FROM `account`");
if($r && count($r) && $r[0]['total']) { if($r && count($r) && $r[0]['total']) {
@ -208,23 +226,22 @@ function setup_content(&$a) {
} }
} }
if(x($a->data,'txt') && strlen($a->data['txt'])) { if(x($a->data, 'txt') && strlen($a->data['txt'])) {
$db_return_text .= manual_config($a); $db_return_text .= manual_config($a);
} }
if ($db_return_text!="") { if ($db_return_text != "") {
$tpl = get_markup_template('install.tpl'); $tpl = get_markup_template('install.tpl');
return replace_macros($tpl, array( return replace_macros($tpl, array(
'$title' => $install_title, '$title' => $install_title,
'$pass' => "", '$pass' => '',
'$text' => $db_return_text . what_next(), '$text' => $db_return_text . what_next(),
)); ));
} }
switch ($install_wizard_pass){ switch ($install_wizard_pass){
case 1: { // System check case 1: { // System check
$checks = array(); $checks = array();
check_funcs($checks); check_funcs($checks);
@ -236,22 +253,23 @@ function setup_content(&$a) {
check_smarty3($checks); check_smarty3($checks);
check_keys($checks); check_keys($checks);
if(x($_POST,'phpath')) if (x($_POST, 'phpath'))
$phpath = notags(trim($_POST['phpath'])); $phpath = notags(trim($_POST['phpath']));
check_php($phpath, $checks); check_php($phpath, $checks);
check_htaccess($checks); check_phpconfig($checks);
function check_passed($v, $c){ check_htaccess($checks);
function check_passed($v, $c) {
if ($c['required']) if ($c['required'])
$v = $v && $c['status']; $v = $v && $c['status'];
return $v; return $v;
} }
$checkspassed = array_reduce($checks, "check_passed", true); $checkspassed = array_reduce($checks, "check_passed", true);
$tpl = get_markup_template('install_checks.tpl'); $tpl = get_markup_template('install_checks.tpl');
$o .= replace_macros($tpl, array( $o .= replace_macros($tpl, array(
@ -267,7 +285,7 @@ function setup_content(&$a) {
)); ));
return $o; return $o;
}; break; }; break;
case 2: { // Database config case 2: { // Database config
$dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost'); $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost');
@ -279,7 +297,6 @@ function setup_content(&$a) {
$phpath = notags(trim($_POST['phpath'])); $phpath = notags(trim($_POST['phpath']));
$adminmail = notags(trim($_POST['adminmail'])); $adminmail = notags(trim($_POST['adminmail']));
$siteurl = notags(trim($_POST['siteurl'])); $siteurl = notags(trim($_POST['siteurl']));
$tpl = get_markup_template('install_db.tpl'); $tpl = get_markup_template('install_db.tpl');
$o .= replace_macros($tpl, array( $o .= replace_macros($tpl, array(
@ -290,7 +307,7 @@ function setup_content(&$a) {
'$info_03' => t('The database you specify below should already exist. If it does not, please create it before continuing.'), '$info_03' => t('The database you specify below should already exist. If it does not, please create it before continuing.'),
'$status' => $wizard_status, '$status' => $wizard_status,
'$dbhost' => array('dbhost', t('Database Server Name'), $dbhost, t('Default is localhost')), '$dbhost' => array('dbhost', t('Database Server Name'), $dbhost, t('Default is localhost')),
'$dbport' => array('dbport', t('Database Port'), $dbport, t('Communication port number - use 0 for default')), '$dbport' => array('dbport', t('Database Port'), $dbport, t('Communication port number - use 0 for default')),
'$dbuser' => array('dbuser', t('Database Login Name'), $dbuser, ''), '$dbuser' => array('dbuser', t('Database Login Name'), $dbuser, ''),
@ -300,16 +317,14 @@ function setup_content(&$a) {
'$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.')), '$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.')),
'$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')), '$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')),
'$lbl_10' => t('Please select a default timezone for your website'), '$lbl_10' => t('Please select a default timezone for your website'),
'$baseurl' => $a->get_baseurl(), '$baseurl' => $a->get_baseurl(),
'$phpath' => $phpath, '$phpath' => $phpath,
'$submit' => t('Submit'), '$submit' => t('Submit'),
)); ));
return $o; return $o;
}; break; }; break;
@ -322,241 +337,296 @@ function setup_content(&$a) {
$dbdata = notags(trim($_POST['dbdata'])); $dbdata = notags(trim($_POST['dbdata']));
$dbtype = intval(notags(trim($_POST['dbtype']))); $dbtype = intval(notags(trim($_POST['dbtype'])));
$phpath = notags(trim($_POST['phpath'])); $phpath = notags(trim($_POST['phpath']));
$adminmail = notags(trim($_POST['adminmail'])); $adminmail = notags(trim($_POST['adminmail']));
$siteurl = notags(trim($_POST['siteurl'])); $siteurl = notags(trim($_POST['siteurl']));
$timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles'); $timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles');
$tpl = get_markup_template('install_settings.tpl'); $tpl = get_markup_template('install_settings.tpl');
$o .= replace_macros($tpl, array( $o .= replace_macros($tpl, array(
'$title' => $install_title, '$title' => $install_title,
'$pass' => t('Site settings'), '$pass' => t('Site settings'),
'$status' => $wizard_status, '$status' => $wizard_status,
'$dbhost' => $dbhost, '$dbhost' => $dbhost,
'$dbport' => $dbport, '$dbport' => $dbport,
'$dbuser' => $dbuser, '$dbuser' => $dbuser,
'$dbpass' => $dbpass, '$dbpass' => $dbpass,
'$dbdata' => $dbdata, '$dbdata' => $dbdata,
'$phpath' => $phpath, '$phpath' => $phpath,
'$dbtype' => $dbtype, '$dbtype' => $dbtype,
'$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.')), '$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.')),
'$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')), '$siteurl' => array('siteurl', t('Website URL'), z_root(), t('Please use SSL (https) URL if available.')),
'$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()), '$timezone' => array('timezone', t('Please select a default timezone for your website'), $timezone, '', get_timezones()),
'$baseurl' => $a->get_baseurl(), '$baseurl' => $a->get_baseurl(),
'$submit' => t('Submit'), '$submit' => t('Submit'),
)); ));
return $o; return $o;
}; break; }; break;
} }
} }
/** /**
* checks : array passed to template * @brief Add a check result to the array for output.
* title : string *
* status : boolean * @param[in,out] array &$checks array passed to template
* required : boolean * @param string $title a title for the check
* help : string optional * @param boolean $status
* @param boolean $required
* @param[optional] string $help optional help string
*/ */
function check_add(&$checks, $title, $status, $required, $help){ function check_add(&$checks, $title, $status, $required, $help = '') {
$checks[] = array( $checks[] = array(
'title' => $title, 'title' => $title,
'status' => $status, 'status' => $status,
'required' => $required, 'required' => $required,
'help' => $help, 'help' => $help
); );
} }
/**
* @brief Checks the PHP environment.
*
* @param[in,out] string &$phpath
* @param[out] array &$checks
*/
function check_php(&$phpath, &$checks) { function check_php(&$phpath, &$checks) {
if (strlen($phpath)){ $help = '';
if (strlen($phpath)) {
$passed = file_exists($phpath); $passed = file_exists($phpath);
} else { } else {
if(is_windows()) if(is_windows())
$phpath = trim(shell_exec('where php')); $phpath = trim(shell_exec('where php'));
else else
$phpath = trim(shell_exec('which php')); $phpath = trim(shell_exec('which php'));
$passed = strlen($phpath); $passed = strlen($phpath);
} }
$help = "";
if(!$passed) { if(!$passed) {
$help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL; $help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL;
$help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron.") . EOL; $help .= t('If you don\'t have a command line version of PHP installed on server, you will not be able to run background polling via cron.') . EOL;
$help .= EOL . EOL ; $help .= EOL . EOL ;
$tpl = get_markup_template('field_input.tpl'); $tpl = get_markup_template('field_input.tpl');
$help .= replace_macros($tpl, array( $help .= replace_macros($tpl, array(
'$field' => array('phpath', t('PHP executable path'), $phpath, t('Enter full path to php executable. You can leave this blank to continue the installation.')), '$field' => array('phpath', t('PHP executable path'), $phpath, t('Enter full path to php executable. You can leave this blank to continue the installation.')),
)); ));
$phpath=""; $phpath = '';
} }
check_add($checks, t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help); check_add($checks, t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help);
if($passed) { if($passed) {
$str = autoname(8); $str = autoname(8);
$cmd = "$phpath install/testargs.php $str"; $cmd = "$phpath install/testargs.php $str";
$result = trim(shell_exec($cmd)); $result = trim(shell_exec($cmd));
$passed2 = $result == $str; $passed2 = $result == $str;
$help = ""; $help = '';
if(!$passed2) { if(!$passed2) {
$help .= t('The command line version of PHP on your system does not have "register_argc_argv" enabled.'). EOL; $help .= t('The command line version of PHP on your system does not have "register_argc_argv" enabled.'). EOL;
$help .= t('This is required for message delivery to work.'); $help .= t('This is required for message delivery to work.');
} }
check_add($checks, t('PHP register_argc_argv'), $passed, true, $help); check_add($checks, t('PHP register_argc_argv'), $passed, true, $help);
} }
} }
function check_keys(&$checks) { /**
* @brief Some PHP configuration checks.
*
* @todo Change how we display such informational text. Add more description
* how to change them.
*
* @param[out] array &$checks
*/
function check_phpconfig(&$checks) {
require_once 'include/environment.php';
$help = ''; $help = '';
$result = getPhpiniUploadLimits();
$help = sprintf(t('Your max allowed total upload size is set to %s. Maximum size of one file to upload is set to %s. You are allowed to upload up to %d files at once.'),
userReadableSize($result['post_max_size']),
userReadableSize($result['max_upload_filesize']),
$result['max_file_uploads']
);
$help .= '<br>' . t('You can adjust these settings in the servers php.ini.');
check_add($checks, t('PHP upload limits'), true, false, $help);
}
/**
* @brief Check if the openssl implementation can generate keys.
*
* @param[out] array $checks
*/
function check_keys(&$checks) {
$help = '';
$res = false; $res = false;
if(function_exists('openssl_pkey_new')) if (function_exists('openssl_pkey_new')) {
$res=openssl_pkey_new(array( $res = openssl_pkey_new(array(
'digest_alg' => 'sha1', 'digest_alg' => 'sha1',
'private_key_bits' => 4096, 'private_key_bits' => 4096,
'encrypt_key' => false )); 'encrypt_key' => false)
);
}
// Get private key // Get private key
if(! $res) { if (! $res) {
$help .= t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'). EOL; $help .= t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'). EOL;
$help .= t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".'); $help .= t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".');
} }
check_add($checks, t('Generate encryption keys'), $res, true, $help);
check_add($checks, t('Generate encryption keys'), $res, true, $help);
} }
/**
* @brief Check for some PHP functions and modules.
*
* @param[in,out] array &$checks
*/
function check_funcs(&$checks) { function check_funcs(&$checks) {
$ck_funcs = array(); $ck_funcs = array();
check_add($ck_funcs, t('libCurl PHP module'), true, true, "");
check_add($ck_funcs, t('GD graphics PHP module'), true, true, ""); // add check metadata, the real check is done bit later and return values set
check_add($ck_funcs, t('OpenSSL PHP module'), true, true, ""); check_add($ck_funcs, t('libCurl PHP module'), true, true);
check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true, ""); check_add($ck_funcs, t('GD graphics PHP module'), true, true);
check_add($ck_funcs, t('mb_string PHP module'), true, true, ""); check_add($ck_funcs, t('OpenSSL PHP module'), true, true);
check_add($ck_funcs, t('mcrypt PHP module'), true, true, ""); check_add($ck_funcs, t('mysqli or postgres PHP module'), true, true);
check_add($ck_funcs, t('mb_string PHP module'), true, true);
check_add($ck_funcs, t('mcrypt PHP module'), true, true);
check_add($ck_funcs, t('xml PHP module'), true, true);
if(function_exists('apache_get_modules')){ if(function_exists('apache_get_modules')){
if (! in_array('mod_rewrite',apache_get_modules())) { if (! in_array('mod_rewrite', apache_get_modules())) {
check_add($ck_funcs, t('Apache mod_rewrite module'), false, true, t('Error: Apache webserver mod-rewrite module is required but not installed.')); check_add($ck_funcs, t('Apache mod_rewrite module'), false, true, t('Error: Apache webserver mod-rewrite module is required but not installed.'));
} else { } else {
check_add($ck_funcs, t('Apache mod_rewrite module'), true, true, ""); check_add($ck_funcs, t('Apache mod_rewrite module'), true, true);
} }
} }
if((! function_exists('proc_open')) || strstr(ini_get('disable_functions'),'proc_open')) { if((! function_exists('proc_open')) || strstr(ini_get('disable_functions'),'proc_open')) {
check_add($ck_funcs, t('proc_open'), false, true, t('Error: proc_open is required but is either not installed or has been disabled in php.ini')); check_add($ck_funcs, t('proc_open'), false, true, t('Error: proc_open is required but is either not installed or has been disabled in php.ini'));
} }
else { else {
check_add($ck_funcs, t('proc_open'), true, true, ""); check_add($ck_funcs, t('proc_open'), true, true);
} }
if(! function_exists('curl_init')){ if(! function_exists('curl_init')) {
$ck_funcs[0]['status']= false; $ck_funcs[0]['status'] = false;
$ck_funcs[0]['help']= t('Error: libCURL PHP module required but not installed.'); $ck_funcs[0]['help'] = t('Error: libCURL PHP module required but not installed.');
} }
if(! function_exists('imagecreatefromjpeg')){ if(! function_exists('imagecreatefromjpeg')) {
$ck_funcs[1]['status']= false; $ck_funcs[1]['status'] = false;
$ck_funcs[1]['help']= t('Error: GD graphics PHP module with JPEG support required but not installed.'); $ck_funcs[1]['help'] = t('Error: GD graphics PHP module with JPEG support required but not installed.');
} }
if(! function_exists('openssl_public_encrypt')) { if(! function_exists('openssl_public_encrypt')) {
$ck_funcs[2]['status']= false; $ck_funcs[2]['status'] = false;
$ck_funcs[2]['help']= t('Error: openssl PHP module required but not installed.'); $ck_funcs[2]['help'] = t('Error: openssl PHP module required but not installed.');
} }
if(! function_exists('mysqli_connect') && !function_exists('pg_connect')){ if(! function_exists('mysqli_connect') && !function_exists('pg_connect')) {
$ck_funcs[3]['status']= false; $ck_funcs[3]['status'] = false;
$ck_funcs[3]['help']= t('Error: mysqli or postgres PHP module required but neither are installed.'); $ck_funcs[3]['help'] = t('Error: mysqli or postgres PHP module required but neither are installed.');
} }
if(! function_exists('mb_strlen')){ if(! function_exists('mb_strlen')) {
$ck_funcs[4]['status']= false; $ck_funcs[4]['status'] = false;
$ck_funcs[4]['help']= t('Error: mb_string PHP module required but not installed.'); $ck_funcs[4]['help'] = t('Error: mb_string PHP module required but not installed.');
} }
if(! function_exists('mcrypt_encrypt')){ if(! function_exists('mcrypt_encrypt')) {
$ck_funcs[5]['status']= false; $ck_funcs[5]['status'] = false;
$ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.'); $ck_funcs[5]['help'] = t('Error: mcrypt PHP module required but not installed.');
}
if(! extension_loaded('xml')) {
$ck_funcs[6]['status'] = false;
$ck_funcs[6]['help'] = t('Error: xml PHP module required for DAV but not installed.');
} }
$checks = array_merge($checks, $ck_funcs);
$checks = array_merge($checks, $ck_funcs);
} }
/**
* @brief Check for .htconfig requirements.
*
* @param[out] array &$checks
*/
function check_htconfig(&$checks) { function check_htconfig(&$checks) {
$status = true; $status = true;
$help = ""; $help = '';
if( (file_exists('.htconfig.php') && !is_writable('.htconfig.php')) ||
(!file_exists('.htconfig.php') && !is_writable('.')) ) {
$status=false;
$help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL;
$help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL;
$help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Red top folder.').EOL;
$help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "install/INSTALL.txt" for instructions.').EOL;
}
check_add($checks, t('.htconfig.php is writable'), $status, false, $help);
if( (file_exists('.htconfig.php') && !is_writable('.htconfig.php')) ||
(!file_exists('.htconfig.php') && !is_writable('.')) ) {
$status = false;
$help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL;
$help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL;
$help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Red top folder.').EOL;
$help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "install/INSTALL.txt" for instructions.').EOL;
}
check_add($checks, t('.htconfig.php is writable'), $status, false, $help);
} }
/**
* @brief Checks for our templating engine Smarty3 requirements.
*
* @param[out] array &$checks
*/
function check_smarty3(&$checks) { function check_smarty3(&$checks) {
$status = true; $status = true;
$help = ""; $help = '';
if( !is_writable(TEMPLATE_BUILD_PATH) ) {
if(! is_writable(TEMPLATE_BUILD_PATH) ) {
$status=false; $status = false;
$help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL; $help = t('Red uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL;
$help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the Red top level folder.'), TEMPLATE_BUILD_PATH) . EOL; $help .= sprintf( t('In order to store these compiled templates, the web server needs to have write access to the directory %s under the Red top level folder.'), TEMPLATE_BUILD_PATH) . EOL;
$help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
$help .= sprintf( t('Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains.'), TEMPLATE_BUILD_PATH) . EOL; $help .= sprintf( t('Note: as a security measure, you should give the web server write access to %s only--not the template files (.tpl) that it contains.'), TEMPLATE_BUILD_PATH) . EOL;
} }
check_add($checks, sprintf( t('%s is writable'), TEMPLATE_BUILD_PATH), $status, true, $help);
check_add($checks, sprintf( t('%s is writable'), TEMPLATE_BUILD_PATH), $status, true, $help);
} }
/**
* @brief Check for store directory.
*
* @param[out] array &$checks
*/
function check_store(&$checks) { function check_store(&$checks) {
$status = true; $status = true;
$help = ""; $help = '';
@os_mkdir(TEMPLATE_BUILD_PATH,STORAGE_DEFAULT_PERMISSIONS,true); @os_mkdir(TEMPLATE_BUILD_PATH, STORAGE_DEFAULT_PERMISSIONS, true);
if( !is_writable('store') ) { if(! is_writable('store')) {
$status = false;
$status=false;
$help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL; $help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
$help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL; $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
} }
check_add($checks, t('store is writable'), $status, true, $help);
check_add($checks, t('store is writable'), $status, true, $help);
} }
/**
* @brief Check URL rewrite und SSL certificate.
*
* @param[out] array &$checks
*/
function check_htaccess(&$checks) { function check_htaccess(&$checks) {
$a = get_app(); $a = get_app();
$status = true; $status = true;
$help = ""; $help = '';
$ssl_error = false; $ssl_error = false;
$url = $a->get_baseurl() . '/setup/testrewrite'; $url = $a->get_baseurl() . '/setup/testrewrite';
if (function_exists('curl_init')){ if (function_exists('curl_init')){
$test = z_fetch_url($url); $test = z_fetch_url($url);
if(! $test['success']) { if(! $test['success']) {
if(strstr($url,'https://')) { if(strstr($url,'https://')) {
$test = z_fetch_url($url,false,0,array('novalidate' => true)); $test = z_fetch_url($url,false,0,array('novalidate' => true));
@ -579,26 +649,27 @@ function check_htaccess(&$checks) {
$help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL; $help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL;
$help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL; $help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL;
check_add($checks, t('SSL certificate validation'),false,true, $help); check_add($checks, t('SSL certificate validation'), false, true, $help);
} }
} }
if ((! $test['success']) || ($test['body'] != "ok")) { if ((! $test['success']) || ($test['body'] != "ok")) {
$status = false; $status = false;
$help = t('Url rewrite in .htaccess is not working. Check your server configuration.'.'Test: '.var_export($test,true)); $help = t('Url rewrite in .htaccess is not working. Check your server configuration.'.'Test: '.var_export($test,true));
} }
check_add($checks, t('Url rewrite is working'), $status, true, $help);
} else { check_add($checks, t('Url rewrite is working'), $status, true, $help);
// cannot check modrewrite if libcurl is not installed } else {
} // cannot check modrewrite if libcurl is not installed
}
} }
function manual_config(&$a) { function manual_config(&$a) {
$data = htmlspecialchars($a->data['txt'],ENT_COMPAT,'UTF-8'); $data = htmlspecialchars($a->data['txt'], ENT_COMPAT, 'UTF-8');
$o = t('The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.'); $o = t('The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.');
$o .= "<textarea rows=\"24\" cols=\"80\" >$data</textarea>"; $o .= "<textarea rows=\"24\" cols=\"80\" >$data</textarea>";
return $o; return $o;
} }
@ -617,50 +688,47 @@ function load_database($db) {
$arr = explode(';',$str); $arr = explode(';',$str);
$errors = false; $errors = false;
foreach($arr as $a) { foreach($arr as $a) {
if(strlen(trim($a))) { if(strlen(trim($a))) {
$r = @$db->q(trim($a)); $r = @$db->q(trim($a));
if(! $r) { if(! $r) {
$errors .= t('Errors encountered creating database tables.') . $a . EOL; $errors .= t('Errors encountered creating database tables.') . $a . EOL;
} }
} }
} }
return $errors; return $errors;
} }
function what_next() { function what_next() {
$a = get_app(); $a = get_app();
// install the standard theme // install the standard theme
set_config('system','allowed_themes','redbasic'); set_config('system', 'allowed_themes', 'redbasic');
// Set a lenient list of ciphers if using openssl. Other ssl engines // Set a lenient list of ciphers if using openssl. Other ssl engines
// (e.g. NSS used in RedHat) require different syntax, so hopefully // (e.g. NSS used in RedHat) require different syntax, so hopefully
// the default curl cipher list will work for most sites. If not, // the default curl cipher list will work for most sites. If not,
// this can set via config. Many distros are now disabling RC4, // this can set via config. Many distros are now disabling RC4,
// but many Red sites still use it and are unable to change it. // but many Red sites still use it and are unable to change it.
// We do not use SSL for encryption, only to protect session cookies. // We do not use SSL for encryption, only to protect session cookies.
// z_fetch_url() is also used to import shared links and other content // z_fetch_url() is also used to import shared links and other content
// so in theory most any cipher could show up and we should do our best // so in theory most any cipher could show up and we should do our best
// to make the content available rather than tell folks that there's a // to make the content available rather than tell folks that there's a
// weird SSL error which they can't do anything about. // weird SSL error which they can't do anything about.
$x = curl_version(); $x = curl_version();
if(stristr($x['ssl_version'],'openssl')) if(stristr($x['ssl_version'],'openssl'))
set_config('system','curl_ssl_ciphers','ALL:!eNULL'); set_config('system','curl_ssl_ciphers','ALL:!eNULL');
// Create a system channel // Create a system channel
require_once ('include/identity.php'); require_once ('include/identity.php');
create_sys_channel(); create_sys_channel();
$baseurl = $a->get_baseurl(); $baseurl = $a->get_baseurl();
return return
t('<h1>What next</h1>') t('<h1>What next</h1>')
."<p>".t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.') ."<p>".t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.')
.t('Please see the file "install/INSTALL.txt".') .t('Please see the file "install/INSTALL.txt".')
."</p><p>" ."</p><p>"
.t("Go to your new Red node <a href='$baseurl/register'>registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.") .t("Go to your new Red node <a href='$baseurl/register'>registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.")
."</p>"; ."</p>";
} }

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
2015-05-21.1039 2015-05-23.1041