Drupal.locale = { 'pluralFormula': function ($n) { return Number(($n!=1)); }, 'strings': {"":{"An AJAX HTTP error occurred.":"Si \u00e8 verificato un errore HTTP in AJAX.","HTTP Result Code: !status":"Codice HTTP di risposta: !status","An AJAX HTTP request terminated abnormally.":"Una richiesta AJAX HTTP \u00e8 terminata in modo anomalo.","Debugging information follows.":"Di seguito le informazioni di debug.","Path: !uri":"Percorso: !uri","StatusText: !statusText":"StatusText: !statusText","ResponseText: !responseText":"ResponseText: !responseText","ReadyState: !readyState":"ReadyState: !readyState","Next":"Seguente","Disabled":"Disattivato","Enabled":"Attivato","Edit":"Modifica","Sunday":"Domenica","Monday":"Luned\u00ec","Tuesday":"Marted\u00ec","Wednesday":"Mercoled\u00ec","Thursday":"Gioved\u00ec","Friday":"Venerd\u00ec","Saturday":"Sabato","Add":"Aggiungi","Upload":"Carica","Configure":"Configura","All":"Tutti","Done":"Fatto","This field is required.":"Questo campo \u00e8 obbligatorio.","Prev":"Precedente","Mon":"Lun","Tue":"Mar","Wed":"Mer","Thu":"Gio","Fri":"Ven","Sat":"Sab","Sun":"Dom","January":"Gennaio","February":"Febbraio","March":"Marzo","April":"Aprile","May":"Mag","June":"Giugno","July":"Luglio","August":"Agosto","September":"Settembre","October":"Ottobre","November":"Novembre","December":"Dicembre","Show":"Mostra","Select all rows in this table":"Seleziona tutte le righe in questa tabella","Deselect all rows in this table":"Deseleziona tutte le righe in questa tabella","Today":"Oggi","Jan":"Gen","Feb":"Feb","Mar":"Mar","Apr":"Apr","Jun":"Giu","Jul":"Lug","Aug":"Ago","Sep":"Set","Oct":"Ott","Nov":"Nov","Dec":"Dic","Su":"Do","Mo":"Lu","Tu":"Ma","We":"Noi","Th":"Gi","Fr":"Ve","Sa":"Sa","Not published":"Non pubblicato","Please wait...":"Attendere prego...","Hide":"Nascondi","Loading":"Caricamento","mm\/dd\/yy":"mm\/gg\/aa","Only files with the following extensions are allowed: %files-allowed.":"Sono consentiti solo i file con le seguenti estensioni: %files-allowed.","By @name on @date":"Da @name il @date","By @name":"Da @name","Not in menu":"Non nel menu","Alias: @alias":"Alias: @alias","No alias":"Nessun alias","New revision":"Nuova revisione","Drag to re-order":"Trascina per riordinare","Changes made in this table will not be saved until the form is submitted.":"I cambiamenti fatti a questa tabella non saranno salvati finch\u00e8 il form non viene inviato.","The changes to these blocks will not be saved until the \u003Cem\u003ESave blocks\u003C\/em\u003E button is clicked.":"I cambiamenti a questi blocchi non saranno salvati finch\u00e9 il bottone \u003Cem\u003ESalva blocchi\u003C\/em\u003E \u00e8 cliccato.","Show shortcuts":"Mostra scorciatoie","This permission is inherited from the authenticated user role.":"Questo permesso viene ereditato dal ruolo utente autenticato.","No revision":"Nessuna revisione","@number comments per page":"@number commenti per pagina","Requires a title":"Richiede un titolo","Not restricted":"Non limitato","(active tab)":"(scheda attiva)","Not customizable":"Non personalizzabile","Restricted to certain pages":"Limitato a certe pagine","The block cannot be placed in this region.":"Il blocco non pu\u00f2 essere posizionato in questa regione.","Customize dashboard":"Personalizza la dashboard","Hide summary":"Nascondi sommario","Edit summary":"Modifica sommario","Don\u0027t display post information":"Non mostrare le informazioni di pubblicazione","@title dialog":"Finestra di dialogo @title","The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.":"Il file selezionato %filename non pu\u00f2 essere caricato. Sono consentiti solo file con le seguenti estensioni: %extensions.","Re-order rows by numerical weight instead of dragging.":"Riordina le righe utilizzando il peso numerico invece del trascinamento.","Show row weights":"Visualizza i pesi delle righe","Hide row weights":"Nascondi i pesi delle righe","Autocomplete popup":"Popup di autocompletamento","Searching for matches...":"Ricerca in corso...","Hide shortcuts":"Nascondi scorciatoie","Other":"Altro","Changes to the checkout panes will not be saved until the \u003Cem\u003ESave configuration\u003C\/em\u003E button is clicked.":"Le modifiche ai pannelli di checkout non saranno salvate fino a quando non si clicca su \u003Cem\u003ESalva configurazione\u003C\/em\u003E.","Available tokens":"Token disponibili","Insert this token into your form":"Inserisci questo token nel form","First click a text field to insert your tokens into.":"Prima occorre cliccare sul campo di testo dove inserire i token.","Loading token browser...":"Caricamento del browser dei token...","Remove group":"Rimuovi gruppo","Apply (all displays)":"Applica (tutte le visualizzazioni)","Apply (this display)":"Applica (solo questa visualizzazione)","Revert to default":"Ritorna al predefinito","Translatable":"Traducibile","Not translatable":"Non traducibile","Restricted to certain languages":"Limitato ad alcune lingue","New":"Nuovo","Automatic alias":"Alias automatico","Close":"Chiudi","Log messages":"Messaggi di log","Please select a file.":"Selezionare un file.","You are not allowed to operate on more than %num files.":"L\u0027utente non \u00e8 autorizzato ad operare su pi\u00f9 di %num file.","Please specify dimensions within the allowed range that is from 1x1 to @dimensions.":"Le dimensioni specificate devono rientrare nell\u0027intervallo consentito, che va da 1x1 a @dimensions.","%filename is not an image.":"%filename non \u00e8 un\u0027immagine.","Do you want to refresh the current directory?":"Si desidera aggiornare la cartella corrente?","Delete selected files?":"Eliminare i file selezionati?","Please select a thumbnail.":"Selezionare una miniatura.","You must select at least %num files.":"Devi selezionare almeno %num file.","You can not perform this operation.":"Impossibile eseguire l\u0027operazione richiesta.","Insert file":"Inserisci file","Change view":"Cambia vista","The response failed verification so will not be processed.":"La risposta non ha superato la verifica, quindi non verr\u00e0 elaborata.","The callback URL is not local and not trusted: !url":"L\u0027URL di callback non \u00e8 locale o non \u00e8 affidabile: !url","CustomMessage: !customMessage":"Messaggio personalizzato: !customMessage","Downloads":"Download","One domain with multiple subdomains":"Un dominio con pi\u00f9 sottodomini","Multiple top-level domains":"Molteplici domini di primo livello","Show description":"Mostra la descrizione","Hide description":"Nascondi la descrizione","Using defaults":"Utilizza le impostazioni predefinite.","Colorbox":"Colorbox","Resume":"Ripresa","Pause":"Pausa","Update Advanced Option":"Aggiorna le opzioni avanzate","Applied Options":"Opzioni applicate","There was no action specified.":"Non \u00e8 stata specificata alcuna azione.","An invalid integer was specified for slideNum.":"Il valore di slideNum non \u00e8 un numero intero.","An invalid action \u0022!action\u0022 was specified.":"\u00c8 stata specificata una azione non valida \u0022!action\u0022.","This slideshow is forced paused.":"Questo slideshow \u00e8 in pausa forzata.","Inclusion: @value":"Inclusione: @value","Priority: @value":"Priorit\u00e0: @value"}} };;
/**
* @file
* JavaScript behaviors for the front-end display of webforms.
*/
(function ($) {
"use strict";
Drupal.behaviors.webform = Drupal.behaviors.webform || {};
Drupal.behaviors.webform.attach = function (context) {
// Calendar datepicker behavior.
Drupal.webform.datepicker(context);
// Conditional logic.
if (Drupal.settings.webform && Drupal.settings.webform.conditionals) {
Drupal.webform.conditional(context);
}
};
Drupal.webform = Drupal.webform || {};
Drupal.webform.datepicker = function (context) {
$('div.webform-datepicker').each(function () {
var $webformDatepicker = $(this);
var $calendar = $webformDatepicker.find('input.webform-calendar');
// Ensure the page we're on actually contains a datepicker.
if ($calendar.length == 0) {
return;
}
var startDate = $calendar[0].className.replace(/.*webform-calendar-start-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
var endDate = $calendar[0].className.replace(/.*webform-calendar-end-(\d{4}-\d{2}-\d{2}).*/, '$1').split('-');
var firstDay = $calendar[0].className.replace(/.*webform-calendar-day-(\d).*/, '$1');
// Convert date strings into actual Date objects.
startDate = new Date(startDate[0], startDate[1] - 1, startDate[2]);
endDate = new Date(endDate[0], endDate[1] - 1, endDate[2]);
// Ensure that start comes before end for datepicker.
if (startDate > endDate) {
var laterDate = startDate;
startDate = endDate;
endDate = laterDate;
}
var startYear = startDate.getFullYear();
var endYear = endDate.getFullYear();
// Set up the jQuery datepicker element.
$calendar.datepicker({
dateFormat: 'yy-mm-dd',
yearRange: startYear + ':' + endYear,
firstDay: parseInt(firstDay),
minDate: startDate,
maxDate: endDate,
onSelect: function (dateText, inst) {
var date = dateText.split('-');
$webformDatepicker.find('select.year, input.year').val(+date[0]).trigger('change');
$webformDatepicker.find('select.month').val(+date[1]).trigger('change');
$webformDatepicker.find('select.day').val(+date[2]).trigger('change');
},
beforeShow: function (input, inst) {
// Get the select list values.
var year = $webformDatepicker.find('select.year, input.year').val();
var month = $webformDatepicker.find('select.month').val();
var day = $webformDatepicker.find('select.day').val();
// If empty, default to the current year/month/day in the popup.
var today = new Date();
year = year ? year : today.getFullYear();
month = month ? month : today.getMonth() + 1;
day = day ? day : today.getDate();
// Make sure that the default year fits in the available options.
year = (year < startYear || year > endYear) ? startYear : year;
// jQuery UI Datepicker will read the input field and base its date
// off of that, even though in our case the input field is a button.
$(input).val(year + '-' + month + '-' + day);
}
});
// Prevent the calendar button from submitting the form.
$calendar.click(function (event) {
// This event is triggered also when pressing enter when the focus is on
// previous webform components, but we only want to do something when
// we are on the calendar component. By checking the event client x/y
// position we known if it was the user clicking. For keyboard navigators
// simply the focus handles the date picker so we don't have to do
// anything special for them.
if (event.clientX !== 0 && event.clientY !== 0) {
// Focus is only necessary for Safari. But it has no impact on other
// browsers.
$(this).focus();
event.preventDefault();
}
});
// Clear date on backspace or delete.
$calendar.keyup(function (e) {
if (e.keyCode == 8 || e.keyCode == 46) {
$.datepicker._clearDate(this);
}
});
});
};
Drupal.webform.conditional = function (context) {
// Add the bindings to each webform on the page.
$.each(Drupal.settings.webform.conditionals, function (formKey, settings) {
var $form = $('.' + formKey + ':not(.webform-conditional-processed)');
$form.each(function (index, currentForm) {
var $currentForm = $(currentForm);
$currentForm.addClass('webform-conditional-processed');
$currentForm.bind('change', {'settings': settings}, Drupal.webform.conditionalCheck);
// Trigger all the elements that cause conditionals on this form.
Drupal.webform.doConditions($currentForm, settings);
});
});
};
/**
* Event handler to respond to field changes in a form.
*
* This event is bound to the entire form, not individual fields.
*/
Drupal.webform.conditionalCheck = function (e) {
var $triggerElement = $(e.target).closest('.webform-component');
if (!$triggerElement.length) {
return;
}
var $form = $triggerElement.closest('form');
var triggerElementKey = $triggerElement.attr('class').match(/webform-component--[^ ]+/)[0];
var settings = e.data.settings;
if (settings.sourceMap[triggerElementKey]) {
Drupal.webform.doConditions($form, settings);
}
};
/**
* Processes all conditional.
*/
Drupal.webform.doConditions = function ($form, settings) {
var stackPointer;
var resultStack;
/**
* Initializes an execution stack for a conditional group's rules.
*
* Also initializes sub-conditional rules.
*/
function executionStackInitialize(andor) {
stackPointer = -1;
resultStack = [];
executionStackPush(andor);
}
/**
* Starts a new subconditional for the given and/or operator.
*/
function executionStackPush(andor) {
resultStack[++stackPointer] = {
results: [],
andor: andor,
};
}
/**
* Adds a rule's result to the current sub-conditional.
*/
function executionStackAccumulate(result) {
resultStack[stackPointer]['results'].push(result);
}
/**
* Finishes a sub-conditional and adds the result to the parent stack frame.
*/
function executionStackPop() {
// Calculate the and/or result.
var stackFrame = resultStack[stackPointer];
// Pop stack and protect against stack underflow.
stackPointer = Math.max(0, stackPointer - 1);
var $conditionalResults = stackFrame['results'];
var filteredResults = $.map($conditionalResults, function (val) {
return val ? val : null;
});
return stackFrame['andor'] === 'or'
? filteredResults.length > 0
: filteredResults.length === $conditionalResults.length;
}
// Track what has been set/hidden for each target component's elements.
// Hidden elements must be disabled because if they are required and don't
// have a value, they will prevent submission due to html5 validation.
// Each execution of the conditionals adds a temporary class
// webform-disabled-flag so that elements hidden or set can be disabled and
// also be prevented from being re-enabled by another conditional (such as a
// parent fieldset). After processing conditionals, this temporary class
// must be removed in preparation for the next execution of the
// conditionals.
$.each(settings.ruleGroups, function (rgid_key, rule_group) {
var ruleGroup = settings.ruleGroups[rgid_key];
// Perform the comparison callback and build the results for this group.
executionStackInitialize(ruleGroup['andor']);
$.each(ruleGroup['rules'], function (m, rule) {
switch (rule['source_type']) {
case 'component':
var elementKey = rule['source'];
var element = $form.find('.' + elementKey)[0];
var existingValue = settings.values[elementKey] ? settings.values[elementKey] : null;
executionStackAccumulate(window['Drupal']['webform'][rule.callback](element, existingValue, rule['value']));
break;
case 'conditional_start':
executionStackPush(rule['andor']);
break;
case 'conditional_end':
executionStackAccumulate(executionStackPop());
break;
}
});
var conditionalResult = executionStackPop();
$.each(ruleGroup['actions'], function (aid, action) {
var $target = $form.find('.' + action['target']);
var actionResult = action['invert'] ? !conditionalResult : conditionalResult;
switch (action['action']) {
case 'show':
var changed = actionResult != Drupal.webform.isVisible($target);
if (actionResult) {
$target.find('.webform-conditional-disabled:not(.webform-disabled-flag)')
.removeClass('webform-conditional-disabled')
.webformProp('disabled', false);
$target
.removeClass('webform-conditional-hidden')
.show();
$form.find('.chosen-disabled').prev().trigger('chosen:updated.chosen');
}
else {
$target
.hide()
.addClass('webform-conditional-hidden')
.find(':input')
.addClass('webform-conditional-disabled webform-disabled-flag')
.webformProp('disabled', true);
}
if (changed && $target.is('tr')) {
Drupal.webform.restripeTable($target.closest('table').first());
}
break;
case 'require':
var $requiredSpan = $target.find('.form-required, .form-optional').first();
if (actionResult != $requiredSpan.hasClass('form-required')) {
var $targetInputElements = $target.find("input:text,textarea,input[type='email'],select,input:radio,input:checkbox,input:file");
// Rather than hide the required tag, remove it so that other
// jQuery can respond via Drupal behaviors.
Drupal.detachBehaviors($requiredSpan);
$targetInputElements
.webformProp('required', actionResult)
.toggleClass('required', actionResult);
if (actionResult) {
$requiredSpan.replaceWith('*');
}
else {
$requiredSpan.replaceWith('');
}
Drupal.attachBehaviors($requiredSpan);
}
break;
case 'set':
var $texts = $target.find("input:text,textarea,input[type='email']");
var $selects = $target.find('select,select option,input:radio,input:checkbox');
var $markups = $target.filter('.webform-component-markup');
if (actionResult) {
var multiple = $.map(action['argument'].split(','), $.trim);
$selects
.webformVal(multiple)
.webformProp('disabled', true)
.addClass('webform-disabled-flag');
$texts
.val([action['argument']])
.webformProp('readonly', true)
.addClass('webform-disabled-flag');
// A special case is made for markup. It is sanitized with
// filter_xss_admin on the server. otherwise text() should be used
// to avoid an XSS vulnerability. text() however would preclude
// the use of tags like or .
$markups.html(action['argument']);
}
else {
$selects.not('.webform-disabled-flag')
.webformProp('disabled', false);
$texts.not('.webform-disabled-flag')
.webformProp('readonly', false);
// Markup not set? Then restore original markup as provided in
// the attribute data-webform-markup.
$markups.each(function () {
var $this = $(this);
var original = $this.data('webform-markup');
if (original !== undefined) {
$this.html(original);
}
});
}
break;
}
}); // End look on each action for one conditional.
}); // End loop on each conditional.
$form.find('.webform-disabled-flag').removeClass('webform-disabled-flag');
};
/**
* Event handler to prevent propagation of events.
*
* Typically click for disabling radio and checkboxes.
*/
Drupal.webform.stopEvent = function () {
return false;
};
Drupal.webform.conditionalOperatorStringEqual = function (element, existingValue, ruleValue) {
var returnValue = false;
var currentValue = Drupal.webform.stringValue(element, existingValue);
$.each(currentValue, function (n, value) {
if (value.toLowerCase() === ruleValue.toLowerCase()) {
returnValue = true;
return false; // break.
}
});
return returnValue;
};
Drupal.webform.conditionalOperatorStringNotEqual = function (element, existingValue, ruleValue) {
var found = false;
var currentValue = Drupal.webform.stringValue(element, existingValue);
$.each(currentValue, function (n, value) {
if (value.toLowerCase() === ruleValue.toLowerCase()) {
found = true;
}
});
return !found;
};
Drupal.webform.conditionalOperatorStringContains = function (element, existingValue, ruleValue) {
var returnValue = false;
var currentValue = Drupal.webform.stringValue(element, existingValue);
$.each(currentValue, function (n, value) {
if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
returnValue = true;
return false; // break.
}
});
return returnValue;
};
Drupal.webform.conditionalOperatorStringDoesNotContain = function (element, existingValue, ruleValue) {
var found = false;
var currentValue = Drupal.webform.stringValue(element, existingValue);
$.each(currentValue, function (n, value) {
if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) > -1) {
found = true;
}
});
return !found;
};
Drupal.webform.conditionalOperatorStringBeginsWith = function (element, existingValue, ruleValue) {
var returnValue = false;
var currentValue = Drupal.webform.stringValue(element, existingValue);
$.each(currentValue, function (n, value) {
if (value.toLowerCase().indexOf(ruleValue.toLowerCase()) === 0) {
returnValue = true;
return false; // break.
}
});
return returnValue;
};
Drupal.webform.conditionalOperatorStringEndsWith = function (element, existingValue, ruleValue) {
var returnValue = false;
var currentValue = Drupal.webform.stringValue(element, existingValue);
$.each(currentValue, function (n, value) {
if (value.toLowerCase().lastIndexOf(ruleValue.toLowerCase()) === value.length - ruleValue.length) {
returnValue = true;
return false; // break.
}
});
return returnValue;
};
Drupal.webform.conditionalOperatorStringEmpty = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
var returnValue = true;
$.each(currentValue, function (n, value) {
if (value !== '') {
returnValue = false;
return false; // break.
}
});
return returnValue;
};
Drupal.webform.conditionalOperatorStringNotEmpty = function (element, existingValue, ruleValue) {
return !Drupal.webform.conditionalOperatorStringEmpty(element, existingValue, ruleValue);
};
Drupal.webform.conditionalOperatorSelectGreaterThan = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
return Drupal.webform.compare_select(currentValue[0], ruleValue, element) > 0;
};
Drupal.webform.conditionalOperatorSelectGreaterThanEqual = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
return comparison > 0 || comparison === 0;
};
Drupal.webform.conditionalOperatorSelectLessThan = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
return Drupal.webform.compare_select(currentValue[0], ruleValue, element) < 0;
};
Drupal.webform.conditionalOperatorSelectLessThanEqual = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
var comparison = Drupal.webform.compare_select(currentValue[0], ruleValue, element);
return comparison < 0 || comparison === 0;
};
Drupal.webform.conditionalOperatorNumericEqual = function (element, existingValue, ruleValue) {
// See float comparison: http://php.net/manual/en/language.types.float.php
var currentValue = Drupal.webform.stringValue(element, existingValue);
var epsilon = 0.000001;
// An empty string does not match any number.
return currentValue[0] === '' ? false : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) < epsilon);
};
Drupal.webform.conditionalOperatorNumericNotEqual = function (element, existingValue, ruleValue) {
// See float comparison: http://php.net/manual/en/language.types.float.php
var currentValue = Drupal.webform.stringValue(element, existingValue);
var epsilon = 0.000001;
// An empty string does not match any number.
return currentValue[0] === '' ? true : (Math.abs(parseFloat(currentValue[0]) - parseFloat(ruleValue)) >= epsilon);
};
Drupal.webform.conditionalOperatorNumericGreaterThan = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
return parseFloat(currentValue[0]) > parseFloat(ruleValue);
};
Drupal.webform.conditionalOperatorNumericGreaterThanEqual = function (element, existingValue, ruleValue) {
return Drupal.webform.conditionalOperatorNumericGreaterThan(element, existingValue, ruleValue) ||
Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
};
Drupal.webform.conditionalOperatorNumericLessThan = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.stringValue(element, existingValue);
return parseFloat(currentValue[0]) < parseFloat(ruleValue);
};
Drupal.webform.conditionalOperatorNumericLessThanEqual = function (element, existingValue, ruleValue) {
return Drupal.webform.conditionalOperatorNumericLessThan(element, existingValue, ruleValue) ||
Drupal.webform.conditionalOperatorNumericEqual(element, existingValue, ruleValue);
};
Drupal.webform.conditionalOperatorDateEqual = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.dateValue(element, existingValue);
return currentValue === ruleValue;
};
Drupal.webform.conditionalOperatorDateNotEqual = function (element, existingValue, ruleValue) {
return !Drupal.webform.conditionalOperatorDateEqual(element, existingValue, ruleValue);
};
Drupal.webform.conditionalOperatorDateBefore = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.dateValue(element, existingValue);
return (currentValue !== false) && currentValue < ruleValue;
};
Drupal.webform.conditionalOperatorDateBeforeEqual = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.dateValue(element, existingValue);
return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
};
Drupal.webform.conditionalOperatorDateAfter = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.dateValue(element, existingValue);
return (currentValue !== false) && currentValue > ruleValue;
};
Drupal.webform.conditionalOperatorDateAfterEqual = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.dateValue(element, existingValue);
return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
};
Drupal.webform.conditionalOperatorTimeEqual = function (element, existingValue, ruleValue) {
var currentValue = Drupal.webform.timeValue(element, existingValue);
return currentValue === ruleValue;
};
Drupal.webform.conditionalOperatorTimeNotEqual = function (element, existingValue, ruleValue) {
return !Drupal.webform.conditionalOperatorTimeEqual(element, existingValue, ruleValue);
};
Drupal.webform.conditionalOperatorTimeBefore = function (element, existingValue, ruleValue) {
// Date and time operators intentionally exclusive for "before".
var currentValue = Drupal.webform.timeValue(element, existingValue);
return (currentValue !== false) && (currentValue < ruleValue);
};
Drupal.webform.conditionalOperatorTimeBeforeEqual = function (element, existingValue, ruleValue) {
// Date and time operators intentionally exclusive for "before".
var currentValue = Drupal.webform.timeValue(element, existingValue);
return (currentValue !== false) && (currentValue < ruleValue || currentValue === ruleValue);
};
Drupal.webform.conditionalOperatorTimeAfter = function (element, existingValue, ruleValue) {
// Date and time operators intentionally inclusive for "after".
var currentValue = Drupal.webform.timeValue(element, existingValue);
return (currentValue !== false) && (currentValue > ruleValue);
};
Drupal.webform.conditionalOperatorTimeAfterEqual = function (element, existingValue, ruleValue) {
// Date and time operators intentionally inclusive for "after".
var currentValue = Drupal.webform.timeValue(element, existingValue);
return (currentValue !== false) && (currentValue > ruleValue || currentValue === ruleValue);
};
/**
* Utility function to compare values of a select component.
*
* @param string a
* First select option key to compare
* @param string b
* Second select option key to compare
* @param array options
* Associative array where the a and b are within the keys
*
* @return integer based upon position of $a and $b in $options
* -N if $a above (<) $b
* 0 if $a = $b
* +N if $a is below (>) $b
*/
Drupal.webform.compare_select = function (a, b, element) {
var optionList = [];
$('option,input:radio,input:checkbox', element).each(function () {
optionList.push($(this).val());
});
var a_position = optionList.indexOf(a);
var b_position = optionList.indexOf(b);
return (a_position < 0 || b_position < 0) ? null : a_position - b_position;
};
/**
* Utility to return current visibility.
*
* Uses actual visibility, except for hidden components which use the applied
* disabled class.
*/
Drupal.webform.isVisible = function ($element) {
return $element.hasClass('webform-component-hidden')
? !$element.find('input').first().hasClass('webform-conditional-disabled')
: $element.closest('.webform-conditional-hidden').length == 0;
};
/**
* Function to get a string value from a select/radios/text/etc. field.
*/
Drupal.webform.stringValue = function (element, existingValue) {
var value = [];
if (element) {
var $element = $(element);
if (Drupal.webform.isVisible($element)) {
// Checkboxes and radios.
$element.find('input[type=checkbox]:checked,input[type=radio]:checked').each(function () {
value.push(this.value);
});
// Select lists.
if (!value.length) {
var selectValue = $element.find('select').val();
if (selectValue) {
if ($.isArray(selectValue)) {
value = selectValue;
}
else {
value.push(selectValue);
}
}
}
// Simple text fields. This check is done last so that the select list
// in select-or-other fields comes before the "other" text field.
if (!value.length) {
$element.find('input:not([type=checkbox],[type=radio]),textarea').each(function () {
value.push(this.value);
});
}
}
}
else {
switch ($.type(existingValue)) {
case 'array':
value = existingValue;
break;
case 'string':
value.push(existingValue);
break;
}
}
return value;
};
/**
* Utility function to calculate a second-based timestamp from a time field.
*/
Drupal.webform.dateValue = function (element, existingValue) {
var value = false;
if (element) {
var $element = $(element);
if (Drupal.webform.isVisible($element)) {
var day = $element.find('[name*=day]').val();
var month = $element.find('[name*=month]').val();
var year = $element.find('[name*=year]').val();
// Months are 0 indexed in JavaScript.
if (month) {
month--;
}
if (year !== '' && month !== '' && day !== '') {
value = Date.UTC(year, month, day) / 1000;
}
}
}
else {
if ($.type(existingValue) === 'array' && existingValue.length) {
existingValue = existingValue[0];
}
if ($.type(existingValue) === 'string') {
existingValue = existingValue.split('-');
}
if (existingValue.length === 3) {
value = Date.UTC(existingValue[0], existingValue[1], existingValue[2]) / 1000;
}
}
return value;
};
/**
* Utility function to calculate a millisecond timestamp from a time field.
*/
Drupal.webform.timeValue = function (element, existingValue) {
var value = false;
if (element) {
var $element = $(element);
if (Drupal.webform.isVisible($element)) {
var hour = $element.find('[name*=hour]').val();
var minute = $element.find('[name*=minute]').val();
var ampm = $element.find('[name*=ampm]:checked').val();
// Convert to integers if set.
hour = (hour === '') ? hour : parseInt(hour);
minute = (minute === '') ? minute : parseInt(minute);
if (hour !== '') {
hour = (hour < 12 && ampm == 'pm') ? hour + 12 : hour;
hour = (hour === 12 && ampm == 'am') ? 0 : hour;
}
if (hour !== '' && minute !== '') {
value = Date.UTC(1970, 0, 1, hour, minute) / 1000;
}
}
}
else {
if ($.type(existingValue) === 'array' && existingValue.length) {
existingValue = existingValue[0];
}
if ($.type(existingValue) === 'string') {
existingValue = existingValue.split(':');
}
if (existingValue.length >= 2) {
value = Date.UTC(1970, 0, 1, existingValue[0], existingValue[1]) / 1000;
}
}
return value;
};
/**
* Make a prop shim for jQuery < 1.9.
*/
$.fn.webformProp = $.fn.webformProp || function (name, value) {
if (value) {
return $.fn.prop ? this.prop(name, true) : this.attr(name, true);
}
else {
return $.fn.prop ? this.prop(name, false) : this.removeAttr(name);
}
};
/**
* Make a multi-valued val() function.
*
* This is for setting checkboxes, radios, and select elements.
*/
$.fn.webformVal = function (values) {
this.each(function () {
var $this = $(this);
var value = $this.val();
var on = $.inArray($this.val(), values) != -1;
if (this.nodeName == 'OPTION') {
$this.webformProp('selected', on ? value : false);
}
else {
$this.val(on ? [value] : false);
}
});
return this;
};
/**
* Given a table's DOM element, restripe the odd/even classes.
*/
Drupal.webform.restripeTable = function (table) {
// :even and :odd are reversed because jQuery counts from 0 and
// we count from 1, so we're out of sync.
// Match immediate children of the parent element to allow nesting.
$('> tbody > tr, > tr', table)
.filter(':visible:odd').filter('.odd')
.removeClass('odd').addClass('even')
.end().end()
.filter(':visible:even').filter('.even')
.removeClass('even').addClass('odd');
};
})(jQuery);
;
/*!
* jQuery Cycle Plugin (with Transition Definitions)
* Examples and documentation at: http://jquery.malsup.com/cycle/
* Copyright (c) 2007-2013 M. Alsup
* Version: 3.0.3 (11-JUL-2013)
* Dual licensed under the MIT and GPL licenses.
* http://jquery.malsup.com/license.html
* Requires: jQuery v1.7.1 or later
*/
;(function($, undefined) {
"use strict";
var ver = '3.0.3';
function debug(s) {
if ($.fn.cycle.debug)
log(s);
}
function log() {
/*global console */
if (window.console && console.log)
console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
}
$.expr[':'].paused = function(el) {
return el.cyclePause;
};
// the options arg can be...
// a number - indicates an immediate transition should occur to the given slide index
// a string - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
// an object - properties to control the slideshow
//
// the arg2 arg can be...
// the name of an fx (only used in conjunction with a numeric value for 'options')
// the value true (only used in first arg == 'resume') and indicates
// that the resume should occur immediately (not wait for next timeout)
$.fn.cycle = function(options, arg2) {
var o = { s: this.selector, c: this.context };
// in 1.3+ we can fix mistakes with the ready state
if (this.length === 0 && options != 'stop') {
if (!$.isReady && o.s) {
log('DOM not ready, queuing slideshow');
$(function() {
$(o.s,o.c).cycle(options,arg2);
});
return this;
}
// is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
return this;
}
// iterate the matched nodeset
return this.each(function() {
var opts = handleArguments(this, options, arg2);
if (opts === false)
return;
opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
// stop existing slideshow for this container (if there is one)
if (this.cycleTimeout)
clearTimeout(this.cycleTimeout);
this.cycleTimeout = this.cyclePause = 0;
this.cycleStop = 0; // issue #108
var $cont = $(this);
var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
var els = $slides.get();
if (els.length < 2) {
log('terminating; too few slides: ' + els.length);
return;
}
var opts2 = buildOptions($cont, $slides, els, opts, o);
if (opts2 === false)
return;
var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards);
// if it's an auto slideshow, kick it off
if (startTime) {
startTime += (opts2.delay || 0);
if (startTime < 10)
startTime = 10;
debug('first timeout: ' + startTime);
this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime);
}
});
};
function triggerPause(cont, byHover, onPager) {
var opts = $(cont).data('cycle.opts');
if (!opts)
return;
var paused = !!cont.cyclePause;
if (paused && opts.paused)
opts.paused(cont, opts, byHover, onPager);
else if (!paused && opts.resumed)
opts.resumed(cont, opts, byHover, onPager);
}
// process the args that were passed to the plugin fn
function handleArguments(cont, options, arg2) {
if (cont.cycleStop === undefined)
cont.cycleStop = 0;
if (options === undefined || options === null)
options = {};
if (options.constructor == String) {
switch(options) {
case 'destroy':
case 'stop':
var opts = $(cont).data('cycle.opts');
if (!opts)
return false;
cont.cycleStop++; // callbacks look for change
if (cont.cycleTimeout)
clearTimeout(cont.cycleTimeout);
cont.cycleTimeout = 0;
if (opts.elements)
$(opts.elements).stop();
$(cont).removeData('cycle.opts');
if (options == 'destroy')
destroy(cont, opts);
return false;
case 'toggle':
cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
checkInstantResume(cont.cyclePause, arg2, cont);
triggerPause(cont);
return false;
case 'pause':
cont.cyclePause = 1;
triggerPause(cont);
return false;
case 'resume':
cont.cyclePause = 0;
checkInstantResume(false, arg2, cont);
triggerPause(cont);
return false;
case 'prev':
case 'next':
opts = $(cont).data('cycle.opts');
if (!opts) {
log('options not found, "prev/next" ignored');
return false;
}
if (typeof arg2 == 'string')
opts.oneTimeFx = arg2;
$.fn.cycle[options](opts);
return false;
default:
options = { fx: options };
}
return options;
}
else if (options.constructor == Number) {
// go to the requested slide
var num = options;
options = $(cont).data('cycle.opts');
if (!options) {
log('options not found, can not advance slide');
return false;
}
if (num < 0 || num >= options.elements.length) {
log('invalid slide index: ' + num);
return false;
}
options.nextSlide = num;
if (cont.cycleTimeout) {
clearTimeout(cont.cycleTimeout);
cont.cycleTimeout = 0;
}
if (typeof arg2 == 'string')
options.oneTimeFx = arg2;
go(options.elements, options, 1, num >= options.currSlide);
return false;
}
return options;
function checkInstantResume(isPaused, arg2, cont) {
if (!isPaused && arg2 === true) { // resume now!
var options = $(cont).data('cycle.opts');
if (!options) {
log('options not found, can not resume');
return false;
}
if (cont.cycleTimeout) {
clearTimeout(cont.cycleTimeout);
cont.cycleTimeout = 0;
}
go(options.elements, options, 1, !options.backwards);
}
}
}
function removeFilter(el, opts) {
if (!$.support.opacity && opts.cleartype && el.style.filter) {
try { el.style.removeAttribute('filter'); }
catch(smother) {} // handle old opera versions
}
}
// unbind event handlers
function destroy(cont, opts) {
if (opts.next)
$(opts.next).unbind(opts.prevNextEvent);
if (opts.prev)
$(opts.prev).unbind(opts.prevNextEvent);
if (opts.pager || opts.pagerAnchorBuilder)
$.each(opts.pagerAnchors || [], function() {
this.unbind().remove();
});
opts.pagerAnchors = null;
$(cont).unbind('mouseenter.cycle mouseleave.cycle');
if (opts.destroy) // callback
opts.destroy(opts);
}
// one-time initialization
function buildOptions($cont, $slides, els, options, o) {
var startingSlideSpecified;
// support metadata plugin (v1.0 and v2.0)
var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null;
if (meta)
opts = $.extend(opts, meta);
if (opts.autostop)
opts.countdown = opts.autostopCount || els.length;
var cont = $cont[0];
$cont.data('cycle.opts', opts);
opts.$cont = $cont;
opts.stopCount = cont.cycleStop;
opts.elements = els;
opts.before = opts.before ? [opts.before] : [];
opts.after = opts.after ? [opts.after] : [];
// push some after callbacks
if (!$.support.opacity && opts.cleartype)
opts.after.push(function() { removeFilter(this, opts); });
if (opts.continuous)
opts.after.push(function() { go(els,opts,0,!opts.backwards); });
saveOriginalOpts(opts);
// clearType corrections
if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
clearTypeFix($slides);
// container requires non-static position so that slides can be position within
if ($cont.css('position') == 'static')
$cont.css('position', 'relative');
if (opts.width)
$cont.width(opts.width);
if (opts.height && opts.height != 'auto')
$cont.height(opts.height);
if (opts.startingSlide !== undefined) {
opts.startingSlide = parseInt(opts.startingSlide,10);
if (opts.startingSlide >= els.length || opts.startSlide < 0)
opts.startingSlide = 0; // catch bogus input
else
startingSlideSpecified = true;
}
else if (opts.backwards)
opts.startingSlide = els.length - 1;
else
opts.startingSlide = 0;
// if random, mix up the slide array
if (opts.random) {
opts.randomMap = [];
for (var i = 0; i < els.length; i++)
opts.randomMap.push(i);
opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
if (startingSlideSpecified) {
// try to find the specified starting slide and if found set start slide index in the map accordingly
for ( var cnt = 0; cnt < els.length; cnt++ ) {
if ( opts.startingSlide == opts.randomMap[cnt] ) {
opts.randomIndex = cnt;
}
}
}
else {
opts.randomIndex = 1;
opts.startingSlide = opts.randomMap[1];
}
}
else if (opts.startingSlide >= els.length)
opts.startingSlide = 0; // catch bogus input
opts.currSlide = opts.startingSlide || 0;
var first = opts.startingSlide;
// set position and zIndex on all the slides
$slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
var z;
if (opts.backwards)
z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
else
z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
$(this).css('z-index', z);
});
// make sure first slide is visible
$(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
removeFilter(els[first], opts);
// stretch slides
if (opts.fit) {
if (!opts.aspect) {
if (opts.width)
$slides.width(opts.width);
if (opts.height && opts.height != 'auto')
$slides.height(opts.height);
} else {
$slides.each(function(){
var $slide = $(this);
var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect;
if( opts.width && $slide.width() != opts.width ) {
$slide.width( opts.width );
$slide.height( opts.width / ratio );
}
if( opts.height && $slide.height() < opts.height ) {
$slide.height( opts.height );
$slide.width( opts.height * ratio );
}
});
}
}
if (opts.center && ((!opts.fit) || opts.aspect)) {
$slides.each(function(){
var $slide = $(this);
$slide.css({
"margin-left": opts.width ?
((opts.width - $slide.width()) / 2) + "px" :
0,
"margin-top": opts.height ?
((opts.height - $slide.height()) / 2) + "px" :
0
});
});
}
if (opts.center && !opts.fit && !opts.slideResize) {
$slides.each(function(){
var $slide = $(this);
$slide.css({
"margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0,
"margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0
});
});
}
// stretch container
var reshape = (opts.containerResize || opts.containerResizeHeight) && $cont.innerHeight() < 1;
if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
var maxw = 0, maxh = 0;
for(var j=0; j < els.length; j++) {
var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
if (!w) w = e.offsetWidth || e.width || $e.attr('width');
if (!h) h = e.offsetHeight || e.height || $e.attr('height');
maxw = w > maxw ? w : maxw;
maxh = h > maxh ? h : maxh;
}
if (opts.containerResize && maxw > 0 && maxh > 0)
$cont.css({width:maxw+'px',height:maxh+'px'});
if (opts.containerResizeHeight && maxh > 0)
$cont.css({height:maxh+'px'});
}
var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
if (opts.pause)
$cont.bind('mouseenter.cycle', function(){
pauseFlag = true;
this.cyclePause++;
triggerPause(cont, true);
}).bind('mouseleave.cycle', function(){
if (pauseFlag)
this.cyclePause--;
triggerPause(cont, true);
});
if (supportMultiTransitions(opts) === false)
return false;
// apparently a lot of people use image slideshows without height/width attributes on the images.
// Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
var requeue = false;
options.requeueAttempts = options.requeueAttempts || 0;
$slides.each(function() {
// try to get height/width of each slide
var $el = $(this);
this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);
if ( $el.is('img') ) {
var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete);
// don't requeue for images that are still loading but have a valid size
if (loading) {
if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout);
requeue = true;
return false; // break each loop
}
else {
log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
}
}
}
return true;
});
if (requeue)
return false;
opts.cssBefore = opts.cssBefore || {};
opts.cssAfter = opts.cssAfter || {};
opts.cssFirst = opts.cssFirst || {};
opts.animIn = opts.animIn || {};
opts.animOut = opts.animOut || {};
$slides.not(':eq('+first+')').css(opts.cssBefore);
$($slides[first]).css(opts.cssFirst);
if (opts.timeout) {
opts.timeout = parseInt(opts.timeout,10);
// ensure that timeout and speed settings are sane
if (opts.speed.constructor == String)
opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
if (!opts.sync)
opts.speed = opts.speed / 2;
var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
while((opts.timeout - opts.speed) < buffer) // sanitize timeout
opts.timeout += opts.speed;
}
if (opts.easing)
opts.easeIn = opts.easeOut = opts.easing;
if (!opts.speedIn)
opts.speedIn = opts.speed;
if (!opts.speedOut)
opts.speedOut = opts.speed;
opts.slideCount = els.length;
opts.currSlide = opts.lastSlide = first;
if (opts.random) {
if (++opts.randomIndex == els.length)
opts.randomIndex = 0;
opts.nextSlide = opts.randomMap[opts.randomIndex];
}
else if (opts.backwards)
opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1;
else
opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
// run transition init fn
if (!opts.multiFx) {
var init = $.fn.cycle.transitions[opts.fx];
if ($.isFunction(init))
init($cont, $slides, opts);
else if (opts.fx != 'custom' && !opts.multiFx) {
log('unknown transition: ' + opts.fx,'; slideshow terminating');
return false;
}
}
// fire artificial events
var e0 = $slides[first];
if (!opts.skipInitializationCallbacks) {
if (opts.before.length)
opts.before[0].apply(e0, [e0, e0, opts, true]);
if (opts.after.length)
opts.after[0].apply(e0, [e0, e0, opts, true]);
}
if (opts.next)
$(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);});
if (opts.prev)
$(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);});
if (opts.pager || opts.pagerAnchorBuilder)
buildPager(els,opts);
exposeAddSlide(opts, els);
return opts;
}
// save off original opts so we can restore after clearing state
function saveOriginalOpts(opts) {
opts.original = { before: [], after: [] };
opts.original.cssBefore = $.extend({}, opts.cssBefore);
opts.original.cssAfter = $.extend({}, opts.cssAfter);
opts.original.animIn = $.extend({}, opts.animIn);
opts.original.animOut = $.extend({}, opts.animOut);
$.each(opts.before, function() { opts.original.before.push(this); });
$.each(opts.after, function() { opts.original.after.push(this); });
}
function supportMultiTransitions(opts) {
var i, tx, txs = $.fn.cycle.transitions;
// look for multiple effects
if (opts.fx.indexOf(',') > 0) {
opts.multiFx = true;
opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
// discard any bogus effect names
for (i=0; i < opts.fxs.length; i++) {
var fx = opts.fxs[i];
tx = txs[fx];
if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
log('discarding unknown transition: ',fx);
opts.fxs.splice(i,1);
i--;
}
}
// if we have an empty list then we threw everything away!
if (!opts.fxs.length) {
log('No valid transitions named; slideshow terminating.');
return false;
}
}
else if (opts.fx == 'all') { // auto-gen the list of transitions
opts.multiFx = true;
opts.fxs = [];
for (var p in txs) {
if (txs.hasOwnProperty(p)) {
tx = txs[p];
if (txs.hasOwnProperty(p) && $.isFunction(tx))
opts.fxs.push(p);
}
}
}
if (opts.multiFx && opts.randomizeEffects) {
// munge the fxs array to make effect selection random
var r1 = Math.floor(Math.random() * 20) + 30;
for (i = 0; i < r1; i++) {
var r2 = Math.floor(Math.random() * opts.fxs.length);
opts.fxs.push(opts.fxs.splice(r2,1)[0]);
}
debug('randomized fx sequence: ',opts.fxs);
}
return true;
}
// provide a mechanism for adding slides after the slideshow has started
function exposeAddSlide(opts, els) {
opts.addSlide = function(newSlide, prepend) {
var $s = $(newSlide), s = $s[0];
if (!opts.autostopCount)
opts.countdown++;
els[prepend?'unshift':'push'](s);
if (opts.els)
opts.els[prepend?'unshift':'push'](s); // shuffle needs this
opts.slideCount = els.length;
// add the slide to the random map and resort
if (opts.random) {
opts.randomMap.push(opts.slideCount-1);
opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
}
$s.css('position','absolute');
$s[prepend?'prependTo':'appendTo'](opts.$cont);
if (prepend) {
opts.currSlide++;
opts.nextSlide++;
}
if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
clearTypeFix($s);
if (opts.fit && opts.width)
$s.width(opts.width);
if (opts.fit && opts.height && opts.height != 'auto')
$s.height(opts.height);
s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();
$s.css(opts.cssBefore);
if (opts.pager || opts.pagerAnchorBuilder)
$.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);
if ($.isFunction(opts.onAddSlide))
opts.onAddSlide($s);
else
$s.hide(); // default behavior
};
}
// reset internal state; we do this on every pass in order to support multiple effects
$.fn.cycle.resetState = function(opts, fx) {
fx = fx || opts.fx;
opts.before = []; opts.after = [];
opts.cssBefore = $.extend({}, opts.original.cssBefore);
opts.cssAfter = $.extend({}, opts.original.cssAfter);
opts.animIn = $.extend({}, opts.original.animIn);
opts.animOut = $.extend({}, opts.original.animOut);
opts.fxFn = null;
$.each(opts.original.before, function() { opts.before.push(this); });
$.each(opts.original.after, function() { opts.after.push(this); });
// re-init
var init = $.fn.cycle.transitions[fx];
if ($.isFunction(init))
init(opts.$cont, $(opts.elements), opts);
};
// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
function go(els, opts, manual, fwd) {
var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];
// opts.busy is true if we're in the middle of an animation
if (manual && opts.busy && opts.manualTrump) {
// let manual transitions requests trump active ones
debug('manualTrump in go(), stopping active transition');
$(els).stop(true,true);
opts.busy = 0;
clearTimeout(p.cycleTimeout);
}
// don't begin another timeout-based transition if there is one active
if (opts.busy) {
debug('transition active, ignoring new tx request');
return;
}
// stop cycling if we have an outstanding stop request
if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
return;
// check to see if we should stop cycling based on autostop options
if (!manual && !p.cyclePause && !opts.bounce &&
((opts.autostop && (--opts.countdown <= 0)) ||
(opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
if (opts.end)
opts.end(opts);
return;
}
// if slideshow is paused, only transition on a manual trigger
var changed = false;
if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
changed = true;
var fx = opts.fx;
// keep trying to get the slide size if we don't have it yet
curr.cycleH = curr.cycleH || $(curr).height();
curr.cycleW = curr.cycleW || $(curr).width();
next.cycleH = next.cycleH || $(next).height();
next.cycleW = next.cycleW || $(next).width();
// support multiple transition types
if (opts.multiFx) {
if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length))
opts.lastFx = 0;
else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0))
opts.lastFx = opts.fxs.length - 1;
fx = opts.fxs[opts.lastFx];
}
// one-time fx overrides apply to: $('div').cycle(3,'zoom');
if (opts.oneTimeFx) {
fx = opts.oneTimeFx;
opts.oneTimeFx = null;
}
$.fn.cycle.resetState(opts, fx);
// run the before callbacks
if (opts.before.length)
$.each(opts.before, function(i,o) {
if (p.cycleStop != opts.stopCount) return;
o.apply(next, [curr, next, opts, fwd]);
});
// stage the after callacks
var after = function() {
opts.busy = 0;
$.each(opts.after, function(i,o) {
if (p.cycleStop != opts.stopCount) return;
o.apply(next, [curr, next, opts, fwd]);
});
if (!p.cycleStop) {
// queue next transition
queueNext();
}
};
debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
// get ready to perform the transition
opts.busy = 1;
if (opts.fxFn) // fx function provided?
opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ?
$.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
else
$.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
}
else {
queueNext();
}
if (changed || opts.nextSlide == opts.currSlide) {
// calculate the next slide
var roll;
opts.lastSlide = opts.currSlide;
if (opts.random) {
opts.currSlide = opts.nextSlide;
if (++opts.randomIndex == els.length) {
opts.randomIndex = 0;
opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
}
opts.nextSlide = opts.randomMap[opts.randomIndex];
if (opts.nextSlide == opts.currSlide)
opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
}
else if (opts.backwards) {
roll = (opts.nextSlide - 1) < 0;
if (roll && opts.bounce) {
opts.backwards = !opts.backwards;
opts.nextSlide = 1;
opts.currSlide = 0;
}
else {
opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1;
opts.currSlide = roll ? 0 : opts.nextSlide+1;
}
}
else { // sequence
roll = (opts.nextSlide + 1) == els.length;
if (roll && opts.bounce) {
opts.backwards = !opts.backwards;
opts.nextSlide = els.length-2;
opts.currSlide = els.length-1;
}
else {
opts.nextSlide = roll ? 0 : opts.nextSlide+1;
opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
}
}
}
if (changed && opts.pager)
opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
function queueNext() {
// stage the next transition
var ms = 0, timeout = opts.timeout;
if (opts.timeout && !opts.continuous) {
ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd);
if (opts.fx == 'shuffle')
ms -= opts.speedOut;
}
else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
ms = 10;
if (ms > 0)
p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms);
}
}
// invoked after transition
$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
$(pager).each(function() {
$(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
});
};
// calculate timeout value for current transition
function getTimeout(curr, next, opts, fwd) {
if (opts.timeoutFn) {
// call user provided calc fn
var t = opts.timeoutFn.call(curr,curr,next,opts,fwd);
while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout
t += opts.speed;
debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
if (t !== false)
return t;
}
return opts.timeout;
}
// expose next/prev function, caller must pass in state
$.fn.cycle.next = function(opts) { advance(opts,1); };
$.fn.cycle.prev = function(opts) { advance(opts,0);};
// advance slide forward or back
function advance(opts, moveForward) {
var val = moveForward ? 1 : -1;
var els = opts.elements;
var p = opts.$cont[0], timeout = p.cycleTimeout;
if (timeout) {
clearTimeout(timeout);
p.cycleTimeout = 0;
}
if (opts.random && val < 0) {
// move back to the previously display slide
opts.randomIndex--;
if (--opts.randomIndex == -2)
opts.randomIndex = els.length-2;
else if (opts.randomIndex == -1)
opts.randomIndex = els.length-1;
opts.nextSlide = opts.randomMap[opts.randomIndex];
}
else if (opts.random) {
opts.nextSlide = opts.randomMap[opts.randomIndex];
}
else {
opts.nextSlide = opts.currSlide + val;
if (opts.nextSlide < 0) {
if (opts.nowrap) return false;
opts.nextSlide = els.length - 1;
}
else if (opts.nextSlide >= els.length) {
if (opts.nowrap) return false;
opts.nextSlide = 0;
}
}
var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
if ($.isFunction(cb))
cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
go(els, opts, 1, moveForward);
return false;
}
function buildPager(els, opts) {
var $p = $(opts.pager);
$.each(els, function(i,o) {
$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
});
opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
}
$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
var a;
if ($.isFunction(opts.pagerAnchorBuilder)) {
a = opts.pagerAnchorBuilder(i,el);
debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
}
else
a = ''+(i+1)+'';
if (!a)
return;
var $a = $(a);
// don't reparent if anchor is in the dom
if ($a.parents('body').length === 0) {
var arr = [];
if ($p.length > 1) {
$p.each(function() {
var $clone = $a.clone(true);
$(this).append($clone);
arr.push($clone[0]);
});
$a = $(arr);
}
else {
$a.appendTo($p);
}
}
opts.pagerAnchors = opts.pagerAnchors || [];
opts.pagerAnchors.push($a);
var pagerFn = function(e) {
e.preventDefault();
opts.nextSlide = i;
var p = opts.$cont[0], timeout = p.cycleTimeout;
if (timeout) {
clearTimeout(timeout);
p.cycleTimeout = 0;
}
var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
if ($.isFunction(cb))
cb(opts.nextSlide, els[opts.nextSlide]);
go(els,opts,1,opts.currSlide < i); // trigger the trans
// return false; // <== allow bubble
};
if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
$a.hover(pagerFn, function(){/* no-op */} );
}
else {
$a.bind(opts.pagerEvent, pagerFn);
}
if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
$a.bind('click.cycle', function(){return false;}); // suppress click
var cont = opts.$cont[0];
var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
if (opts.pauseOnPagerHover) {
$a.hover(
function() {
pauseFlag = true;
cont.cyclePause++;
triggerPause(cont,true,true);
}, function() {
if (pauseFlag)
cont.cyclePause--;
triggerPause(cont,true,true);
}
);
}
};
// helper fn to calculate the number of slides between the current and the next
$.fn.cycle.hopsFromLast = function(opts, fwd) {
var hops, l = opts.lastSlide, c = opts.currSlide;
if (fwd)
hops = c > l ? c - l : opts.slideCount - l;
else
hops = c < l ? l - c : l + opts.slideCount - c;
return hops;
};
// fix clearType problems in ie6 by setting an explicit bg color
// (otherwise text slides look horrible during a fade transition)
function clearTypeFix($slides) {
debug('applying clearType background-color hack');
function hex(s) {
s = parseInt(s,10).toString(16);
return s.length < 2 ? '0'+s : s;
}
function getBg(e) {
for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
var v = $.css(e,'background-color');
if (v && v.indexOf('rgb') >= 0 ) {
var rgb = v.match(/\d+/g);
return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}
if (v && v != 'transparent')
return v;
}
return '#ffffff';
}
$slides.each(function() { $(this).css('background-color', getBg(this)); });
}
// reset common props before the next transition
$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
$(opts.elements).not(curr).hide();
if (typeof opts.cssBefore.opacity == 'undefined')
opts.cssBefore.opacity = 1;
opts.cssBefore.display = 'block';
if (opts.slideResize && w !== false && next.cycleW > 0)
opts.cssBefore.width = next.cycleW;
if (opts.slideResize && h !== false && next.cycleH > 0)
opts.cssBefore.height = next.cycleH;
opts.cssAfter = opts.cssAfter || {};
opts.cssAfter.display = 'none';
$(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
$(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
};
// the actual fn for effecting a transition
$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
var $l = $(curr), $n = $(next);
var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut, animInDelay = opts.animInDelay, animOutDelay = opts.animOutDelay;
$n.css(opts.cssBefore);
if (speedOverride) {
if (typeof speedOverride == 'number')
speedIn = speedOut = speedOverride;
else
speedIn = speedOut = 1;
easeIn = easeOut = null;
}
var fn = function() {
$n.delay(animInDelay).animate(opts.animIn, speedIn, easeIn, function() {
cb();
});
};
$l.delay(animOutDelay).animate(opts.animOut, speedOut, easeOut, function() {
$l.css(opts.cssAfter);
if (!opts.sync)
fn();
});
if (opts.sync) fn();
};
// transition definitions - only fade is defined here, transition pack defines the rest
$.fn.cycle.transitions = {
fade: function($cont, $slides, opts) {
$slides.not(':eq('+opts.currSlide+')').css('opacity',0);
opts.before.push(function(curr,next,opts) {
$.fn.cycle.commonReset(curr,next,opts);
opts.cssBefore.opacity = 0;
});
opts.animIn = { opacity: 1 };
opts.animOut = { opacity: 0 };
opts.cssBefore = { top: 0, left: 0 };
}
};
$.fn.cycle.ver = function() { return ver; };
// override these globally if you like (they are all optional)
$.fn.cycle.defaults = {
activePagerClass: 'activeSlide', // class name used for the active pager link
after: null, // transition callback (scope set to element that was shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
animIn: null, // properties that define how the slide animates in
animInDelay: 0, // allows delay before next slide transitions in
animOut: null, // properties that define how the slide animates out
animOutDelay: 0, // allows delay before current slide transitions out
aspect: false, // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option)
autostop: 0, // true to end slideshow after X transitions (where X == slide count)
autostopCount: 0, // number of transitions (optionally used with autostop to define X)
backwards: false, // true to start slideshow at last slide and move backwards through the stack
before: null, // transition callback (scope set to element to be shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
center: null, // set to true to have cycle add top/left margin to each slide (use with width and height options)
cleartype: !$.support.opacity, // true if clearType corrections should be applied (for IE)
cleartypeNoBg: false, // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
containerResize: 1, // resize container to fit largest slide
containerResizeHeight: 0, // resize containers height to fit the largest slide but leave the width dynamic
continuous: 0, // true to start next transition immediately after current one completes
cssAfter: null, // properties that defined the state of the slide after transitioning out
cssBefore: null, // properties that define the initial state of the slide before transitioning in
delay: 0, // additional delay (in ms) for first transition (hint: can be negative)
easeIn: null, // easing for "in" transition
easeOut: null, // easing for "out" transition
easing: null, // easing method for both in and out transitions
end: null, // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
fastOnEvent: 0, // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
fit: 0, // force slides to fit container
fx: 'fade', // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
fxFn: null, // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
height: 'auto', // container height (if the 'fit' option is true, the slides will be set to this height as well)
manualTrump: true, // causes manual transition to stop an active transition instead of being ignored
metaAttr: 'cycle', // data- attribute that holds the option data for the slideshow
next: null, // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide
nowrap: 0, // true to prevent slideshow from wrapping
onPagerEvent: null, // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
onPrevNextEvent: null, // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
pager: null, // element, jQuery object, or jQuery selector string for the element to use as pager container
pagerAnchorBuilder: null, // callback fn for building anchor links: function(index, DOMelement)
pagerEvent: 'click.cycle', // name of event which drives the pager navigation
pause: 0, // true to enable "pause on hover"
pauseOnPagerHover: 0, // true to pause when hovering over pager link
prev: null, // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide
prevNextEvent: 'click.cycle',// event which drives the manual transition to the previous or next slide
random: 0, // true for random, false for sequence (not applicable to shuffle fx)
randomizeEffects: 1, // valid when multiple effects are used; true to make the effect sequence random
requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
requeueTimeout: 250, // ms delay for requeue
rev: 0, // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle)
shuffle: null, // coords for shuffle animation, ex: { top:15, left: 200 }
skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition
slideExpr: null, // expression for selecting slides (if something other than all children is required)
slideResize: 1, // force slide width/height to fixed size before every transition
speed: 1000, // speed of the transition (any valid fx speed value)
speedIn: null, // speed of the 'in' transition
speedOut: null, // speed of the 'out' transition
startingSlide: undefined,// zero-based index of the first slide to be displayed
sync: 1, // true if in/out transitions should occur simultaneously
timeout: 4000, // milliseconds between slide transitions (0 to disable auto advance)
timeoutFn: null, // callback for determining per-slide timeout value: function(currSlideElement, nextSlideElement, options, forwardFlag)
updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
width: null // container width (if the 'fit' option is true, the slides will be set to this width as well)
};
})(jQuery);
/*!
* jQuery Cycle Plugin Transition Definitions
* This script is a plugin for the jQuery Cycle Plugin
* Examples and documentation at: http://malsup.com/jquery/cycle/
* Copyright (c) 2007-2010 M. Alsup
* Version: 2.73
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
(function($) {
"use strict";
//
// These functions define slide initialization and properties for the named
// transitions. To save file size feel free to remove any of these that you
// don't need.
//
$.fn.cycle.transitions.none = function($cont, $slides, opts) {
opts.fxFn = function(curr,next,opts,after){
$(next).show();
$(curr).hide();
after();
};
};
// not a cross-fade, fadeout only fades out the top slide
$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) {
$slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 });
opts.before.push(function(curr,next,opts,w,h,rev) {
$(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0));
$(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1));
});
opts.animIn.opacity = 1;
opts.animOut.opacity = 0;
opts.cssBefore.opacity = 1;
opts.cssBefore.display = 'block';
opts.cssAfter.zIndex = 0;
};
// scrollUp/Down/Left/Right
$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) {
$cont.css('overflow','hidden');
opts.before.push($.fn.cycle.commonReset);
var h = $cont.height();
opts.cssBefore.top = h;
opts.cssBefore.left = 0;
opts.cssFirst.top = 0;
opts.animIn.top = 0;
opts.animOut.top = -h;
};
$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) {
$cont.css('overflow','hidden');
opts.before.push($.fn.cycle.commonReset);
var h = $cont.height();
opts.cssFirst.top = 0;
opts.cssBefore.top = -h;
opts.cssBefore.left = 0;
opts.animIn.top = 0;
opts.animOut.top = h;
};
$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) {
$cont.css('overflow','hidden');
opts.before.push($.fn.cycle.commonReset);
var w = $cont.width();
opts.cssFirst.left = 0;
opts.cssBefore.left = w;
opts.cssBefore.top = 0;
opts.animIn.left = 0;
opts.animOut.left = 0-w;
};
$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) {
$cont.css('overflow','hidden');
opts.before.push($.fn.cycle.commonReset);
var w = $cont.width();
opts.cssFirst.left = 0;
opts.cssBefore.left = -w;
opts.cssBefore.top = 0;
opts.animIn.left = 0;
opts.animOut.left = w;
};
$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) {
$cont.css('overflow','hidden').width();
opts.before.push(function(curr, next, opts, fwd) {
if (opts.rev)
fwd = !fwd;
$.fn.cycle.commonReset(curr,next,opts);
opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW);
opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW;
});
opts.cssFirst.left = 0;
opts.cssBefore.top = 0;
opts.animIn.left = 0;
opts.animOut.top = 0;
};
$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) {
$cont.css('overflow','hidden');
opts.before.push(function(curr, next, opts, fwd) {
if (opts.rev)
fwd = !fwd;
$.fn.cycle.commonReset(curr,next,opts);
opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1);
opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH;
});
opts.cssFirst.top = 0;
opts.cssBefore.left = 0;
opts.animIn.top = 0;
opts.animOut.left = 0;
};
// slideX/slideY
$.fn.cycle.transitions.slideX = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$(opts.elements).not(curr).hide();
$.fn.cycle.commonReset(curr,next,opts,false,true);
opts.animIn.width = next.cycleW;
});
opts.cssBefore.left = 0;
opts.cssBefore.top = 0;
opts.cssBefore.width = 0;
opts.animIn.width = 'show';
opts.animOut.width = 0;
};
$.fn.cycle.transitions.slideY = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$(opts.elements).not(curr).hide();
$.fn.cycle.commonReset(curr,next,opts,true,false);
opts.animIn.height = next.cycleH;
});
opts.cssBefore.left = 0;
opts.cssBefore.top = 0;
opts.cssBefore.height = 0;
opts.animIn.height = 'show';
opts.animOut.height = 0;
};
// shuffle
$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) {
var i, w = $cont.css('overflow', 'visible').width();
$slides.css({left: 0, top: 0});
opts.before.push(function(curr,next,opts) {
$.fn.cycle.commonReset(curr,next,opts,true,true,true);
});
// only adjust speed once!
if (!opts.speedAdjusted) {
opts.speed = opts.speed / 2; // shuffle has 2 transitions
opts.speedAdjusted = true;
}
opts.random = 0;
opts.shuffle = opts.shuffle || {left:-w, top:15};
opts.els = [];
for (i=0; i < $slides.length; i++)
opts.els.push($slides[i]);
for (i=0; i < opts.currSlide; i++)
opts.els.push(opts.els.shift());
// custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!)
opts.fxFn = function(curr, next, opts, cb, fwd) {
if (opts.rev)
fwd = !fwd;
var $el = fwd ? $(curr) : $(next);
$(next).css(opts.cssBefore);
var count = opts.slideCount;
$el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() {
var hops = $.fn.cycle.hopsFromLast(opts, fwd);
for (var k=0; k < hops; k++) {
if (fwd)
opts.els.push(opts.els.shift());
else
opts.els.unshift(opts.els.pop());
}
if (fwd) {
for (var i=0, len=opts.els.length; i < len; i++)
$(opts.els[i]).css('z-index', len-i+count);
}
else {
var z = $(curr).css('z-index');
$el.css('z-index', parseInt(z,10)+1+count);
}
$el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
$(fwd ? this : curr).hide();
if (cb) cb();
});
});
};
$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
};
// turnUp/Down/Left/Right
$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,true,false);
opts.cssBefore.top = next.cycleH;
opts.animIn.height = next.cycleH;
opts.animOut.width = next.cycleW;
});
opts.cssFirst.top = 0;
opts.cssBefore.left = 0;
opts.cssBefore.height = 0;
opts.animIn.top = 0;
opts.animOut.height = 0;
};
$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,true,false);
opts.animIn.height = next.cycleH;
opts.animOut.top = curr.cycleH;
});
opts.cssFirst.top = 0;
opts.cssBefore.left = 0;
opts.cssBefore.top = 0;
opts.cssBefore.height = 0;
opts.animOut.height = 0;
};
$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,false,true);
opts.cssBefore.left = next.cycleW;
opts.animIn.width = next.cycleW;
});
opts.cssBefore.top = 0;
opts.cssBefore.width = 0;
opts.animIn.left = 0;
opts.animOut.width = 0;
};
$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,false,true);
opts.animIn.width = next.cycleW;
opts.animOut.left = curr.cycleW;
});
$.extend(opts.cssBefore, { top: 0, left: 0, width: 0 });
opts.animIn.left = 0;
opts.animOut.width = 0;
};
// zoom
$.fn.cycle.transitions.zoom = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,false,false,true);
opts.cssBefore.top = next.cycleH/2;
opts.cssBefore.left = next.cycleW/2;
$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
$.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 });
});
opts.cssFirst.top = 0;
opts.cssFirst.left = 0;
opts.cssBefore.width = 0;
opts.cssBefore.height = 0;
};
// fadeZoom
$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,false,false);
opts.cssBefore.left = next.cycleW/2;
opts.cssBefore.top = next.cycleH/2;
$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
});
opts.cssBefore.width = 0;
opts.cssBefore.height = 0;
opts.animOut.opacity = 0;
};
// blindX
$.fn.cycle.transitions.blindX = function($cont, $slides, opts) {
var w = $cont.css('overflow','hidden').width();
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts);
opts.animIn.width = next.cycleW;
opts.animOut.left = curr.cycleW;
});
opts.cssBefore.left = w;
opts.cssBefore.top = 0;
opts.animIn.left = 0;
opts.animOut.left = w;
};
// blindY
$.fn.cycle.transitions.blindY = function($cont, $slides, opts) {
var h = $cont.css('overflow','hidden').height();
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts);
opts.animIn.height = next.cycleH;
opts.animOut.top = curr.cycleH;
});
opts.cssBefore.top = h;
opts.cssBefore.left = 0;
opts.animIn.top = 0;
opts.animOut.top = h;
};
// blindZ
$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) {
var h = $cont.css('overflow','hidden').height();
var w = $cont.width();
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts);
opts.animIn.height = next.cycleH;
opts.animOut.top = curr.cycleH;
});
opts.cssBefore.top = h;
opts.cssBefore.left = w;
opts.animIn.top = 0;
opts.animIn.left = 0;
opts.animOut.top = h;
opts.animOut.left = w;
};
// growX - grow horizontally from centered 0 width
$.fn.cycle.transitions.growX = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,false,true);
opts.cssBefore.left = this.cycleW/2;
opts.animIn.left = 0;
opts.animIn.width = this.cycleW;
opts.animOut.left = 0;
});
opts.cssBefore.top = 0;
opts.cssBefore.width = 0;
};
// growY - grow vertically from centered 0 height
$.fn.cycle.transitions.growY = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,true,false);
opts.cssBefore.top = this.cycleH/2;
opts.animIn.top = 0;
opts.animIn.height = this.cycleH;
opts.animOut.top = 0;
});
opts.cssBefore.height = 0;
opts.cssBefore.left = 0;
};
// curtainX - squeeze in both edges horizontally
$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,false,true,true);
opts.cssBefore.left = next.cycleW/2;
opts.animIn.left = 0;
opts.animIn.width = this.cycleW;
opts.animOut.left = curr.cycleW/2;
opts.animOut.width = 0;
});
opts.cssBefore.top = 0;
opts.cssBefore.width = 0;
};
// curtainY - squeeze in both edges vertically
$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) {
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,true,false,true);
opts.cssBefore.top = next.cycleH/2;
opts.animIn.top = 0;
opts.animIn.height = next.cycleH;
opts.animOut.top = curr.cycleH/2;
opts.animOut.height = 0;
});
opts.cssBefore.height = 0;
opts.cssBefore.left = 0;
};
// cover - curr slide covered by next slide
$.fn.cycle.transitions.cover = function($cont, $slides, opts) {
var d = opts.direction || 'left';
var w = $cont.css('overflow','hidden').width();
var h = $cont.height();
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts);
opts.cssAfter.display = '';
if (d == 'right')
opts.cssBefore.left = -w;
else if (d == 'up')
opts.cssBefore.top = h;
else if (d == 'down')
opts.cssBefore.top = -h;
else
opts.cssBefore.left = w;
});
opts.animIn.left = 0;
opts.animIn.top = 0;
opts.cssBefore.top = 0;
opts.cssBefore.left = 0;
};
// uncover - curr slide moves off next slide
$.fn.cycle.transitions.uncover = function($cont, $slides, opts) {
var d = opts.direction || 'left';
var w = $cont.css('overflow','hidden').width();
var h = $cont.height();
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,true,true,true);
if (d == 'right')
opts.animOut.left = w;
else if (d == 'up')
opts.animOut.top = -h;
else if (d == 'down')
opts.animOut.top = h;
else
opts.animOut.left = -w;
});
opts.animIn.left = 0;
opts.animIn.top = 0;
opts.cssBefore.top = 0;
opts.cssBefore.left = 0;
};
// toss - move top slide and fade away
$.fn.cycle.transitions.toss = function($cont, $slides, opts) {
var w = $cont.css('overflow','visible').width();
var h = $cont.height();
opts.before.push(function(curr, next, opts) {
$.fn.cycle.commonReset(curr,next,opts,true,true,true);
// provide default toss settings if animOut not provided
if (!opts.animOut.left && !opts.animOut.top)
$.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 });
else
opts.animOut.opacity = 0;
});
opts.cssBefore.left = 0;
opts.cssBefore.top = 0;
opts.animIn.left = 0;
};
// wipe - clip animation
$.fn.cycle.transitions.wipe = function($cont, $slides, opts) {
var w = $cont.css('overflow','hidden').width();
var h = $cont.height();
opts.cssBefore = opts.cssBefore || {};
var clip;
if (opts.clip) {
if (/l2r/.test(opts.clip))
clip = 'rect(0px 0px '+h+'px 0px)';
else if (/r2l/.test(opts.clip))
clip = 'rect(0px '+w+'px '+h+'px '+w+'px)';
else if (/t2b/.test(opts.clip))
clip = 'rect(0px '+w+'px 0px 0px)';
else if (/b2t/.test(opts.clip))
clip = 'rect('+h+'px '+w+'px '+h+'px 0px)';
else if (/zoom/.test(opts.clip)) {
var top = parseInt(h/2,10);
var left = parseInt(w/2,10);
clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)';
}
}
opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)';
var d = opts.cssBefore.clip.match(/(\d+)/g);
var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10);
opts.before.push(function(curr, next, opts) {
if (curr == next) return;
var $curr = $(curr), $next = $(next);
$.fn.cycle.commonReset(curr,next,opts,true,true,false);
opts.cssAfter.display = 'block';
var step = 1, count = parseInt((opts.speedIn / 13),10) - 1;
(function f() {
var tt = t ? t - parseInt(step * (t/count),10) : 0;
var ll = l ? l - parseInt(step * (l/count),10) : 0;
var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h;
var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w;
$next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' });
(step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none');
})();
});
$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
opts.animIn = { left: 0 };
opts.animOut = { left: 0 };
};
})(jQuery);
;
/**
* @file
* A simple jQuery Cycle Div Slideshow Rotator.
*/
/**
* This will set our initial behavior, by starting up each individual slideshow.
*/
(function ($) {
Drupal.behaviors.viewsSlideshowCycle = {
attach: function (context) {
$('.views_slideshow_cycle_main:not(.viewsSlideshowCycle-processed)', context).addClass('viewsSlideshowCycle-processed').each(function() {
var fullId = '#' + $(this).attr('id');
var settings = Drupal.settings.viewsSlideshowCycle[fullId];
settings.targetId = '#' + $(fullId + " :first").attr('id');
settings.slideshowId = settings.targetId.replace('#views_slideshow_cycle_teaser_section_', '');
// Pager after function.
var pager_after_fn = function(curr, next, opts) {
// Need to do some special handling on first load.
var slideNum = opts.currSlide;
if (typeof settings.processedAfter == 'undefined' || !settings.processedAfter) {
settings.processedAfter = 1;
slideNum = (typeof settings.opts.startingSlide == 'undefined') ? 0 : settings.opts.startingSlide;
}
Drupal.viewsSlideshow.action({ "action": 'transitionEnd', "slideshowID": settings.slideshowId, "slideNum": slideNum });
}
// Pager before function.
var pager_before_fn = function(curr, next, opts) {
var slideNum = opts.nextSlide;
// Remember last slide.
if (settings.remember_slide) {
createCookie(settings.vss_id, slideNum, settings.remember_slide_days);
}
// Make variable height.
if (!settings.fixed_height) {
//get the height of the current slide
var $ht = $(next).height();
//set the container's height to that of the current slide
$(next).parent().animate({height: $ht});
}
// Need to do some special handling on first load.
if (typeof settings.processedBefore == 'undefined' || !settings.processedBefore) {
settings.processedBefore = 1;
slideNum = (typeof opts.startingSlide == 'undefined') ? 0 : opts.startingSlide;
}
Drupal.viewsSlideshow.action({ "action": 'transitionBegin', "slideshowID": settings.slideshowId, "slideNum": slideNum });
}
settings.loaded = false;
settings.opts = {
speed:settings.speed,
timeout:settings.timeout,
delay:settings.delay,
sync:settings.sync,
random:settings.random,
nowrap:settings.nowrap,
after:pager_after_fn,
before:pager_before_fn,
cleartype:(settings.cleartype)? true : false,
cleartypeNoBg:(settings.cleartypenobg)? true : false
}
// Set the starting slide if we are supposed to remember the slide
if (settings.remember_slide) {
var startSlide = readCookie(settings.vss_id);
if (startSlide == null) {
startSlide = 0;
}
settings.opts.startingSlide = parseInt(startSlide);
}
if (settings.effect == 'none') {
settings.opts.speed = 1;
}
else {
settings.opts.fx = settings.effect;
}
// Take starting item from fragment.
var hash = location.hash;
if (hash) {
var hash = hash.replace('#', '');
var aHash = hash.split(';');
var aHashLen = aHash.length;
// Loop through all the possible starting points.
for (var i = 0; i < aHashLen; i++) {
// Split the hash into two parts. One part is the slideshow id the
// other is the slide number.
var initialInfo = aHash[i].split(':');
// The id in the hash should match our slideshow.
// The slide number chosen shouldn't be larger than the number of
// slides we have.
if (settings.slideshowId == initialInfo[0] && settings.num_divs > initialInfo[1]) {
settings.opts.startingSlide = parseInt(initialInfo[1]);
}
}
}
// Pause on hover.
if (settings.pause) {
var mouseIn = function() {
Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId });
}
var mouseOut = function() {
Drupal.viewsSlideshow.action({ "action": 'play', "slideshowID": settings.slideshowId });
}
if (jQuery.fn.hoverIntent) {
$('#views_slideshow_cycle_teaser_section_' + settings.vss_id).hoverIntent(mouseIn, mouseOut);
}
else {
$('#views_slideshow_cycle_teaser_section_' + settings.vss_id).hover(mouseIn, mouseOut);
}
}
// Pause on clicking of the slide.
if (settings.pause_on_click) {
$('#views_slideshow_cycle_teaser_section_' + settings.vss_id).click(function() {
Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId, "force": true });
});
}
if (typeof JSON != 'undefined') {
var advancedOptions = JSON.parse(settings.advanced_options);
for (var option in advancedOptions) {
switch(option) {
// Standard Options
case "activePagerClass":
case "allowPagerClickBubble":
case "autostop":
case "autostopCount":
case "backwards":
case "bounce":
case "cleartype":
case "cleartypeNoBg":
case "containerResize":
case "continuous":
case "delay":
case "easeIn":
case "easeOut":
case "easing":
case "fastOnEvent":
case "fit":
case "fx":
case "height":
case "manualTrump":
case "metaAttr":
case "next":
case "nowrap":
case "pager":
case "pagerEvent":
case "pause":
case "pauseOnPagerHover":
case "prev":
case "prevNextEvent":
case "random":
case "randomizeEffects":
case "requeueOnImageNotLoaded":
case "requeueTimeout":
case "rev":
case "slideExpr":
case "slideResize":
case "speed":
case "speedIn":
case "speedOut":
case "startingSlide":
case "sync":
case "timeout":
case "width":
var optionValue = advancedOptions[option];
optionValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(optionValue);
settings.opts[option] = optionValue;
break;
// These process options that look like {top:50, bottom:20}
case "animIn":
case "animOut":
case "cssBefore":
case "cssAfter":
case "shuffle":
var cssValue = advancedOptions[option];
cssValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(cssValue);
settings.opts[option] = eval('(' + cssValue + ')');
break;
// These options have their own functions.
case "after":
var afterValue = advancedOptions[option];
afterValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(afterValue);
// transition callback (scope set to element that was shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
settings.opts[option] = function(currSlideElement, nextSlideElement, options, forwardFlag) {
pager_after_fn(currSlideElement, nextSlideElement, options);
eval(afterValue);
}
break;
case "before":
var beforeValue = advancedOptions[option];
beforeValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(beforeValue);
// transition callback (scope set to element to be shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
settings.opts[option] = function(currSlideElement, nextSlideElement, options, forwardFlag) {
pager_before_fn(currSlideElement, nextSlideElement, options);
eval(beforeValue);
}
break;
case "end":
var endValue = advancedOptions[option];
endValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(endValue);
// callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
settings.opts[option] = function(options) {
eval(endValue);
}
break;
case "fxFn":
var fxFnValue = advancedOptions[option];
fxFnValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(fxFnValue);
// function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
settings.opts[option] = function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag) {
eval(fxFnValue);
}
break;
case "onPagerEvent":
var onPagerEventValue = advancedOptions[option];
onPagerEventValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(onPagerEventValue);
settings.opts[option] = function(zeroBasedSlideIndex, slideElement) {
eval(onPagerEventValue);
}
break;
case "onPrevNextEvent":
var onPrevNextEventValue = advancedOptions[option];
onPrevNextEventValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(onPrevNextEventValue);
settings.opts[option] = function(isNext, zeroBasedSlideIndex, slideElement) {
eval(onPrevNextEventValue);
}
break;
case "pagerAnchorBuilder":
var pagerAnchorBuilderValue = advancedOptions[option];
pagerAnchorBuilderValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(pagerAnchorBuilderValue);
// callback fn for building anchor links: function(index, DOMelement)
settings.opts[option] = function(index, DOMelement) {
var returnVal = '';
eval(pagerAnchorBuilderValue);
return returnVal;
}
break;
case "pagerClick":
var pagerClickValue = advancedOptions[option];
pagerClickValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(pagerClickValue);
// callback fn for pager clicks: function(zeroBasedSlideIndex, slideElement)
settings.opts[option] = function(zeroBasedSlideIndex, slideElement) {
eval(pagerClickValue);
}
break;
case "paused":
var pausedValue = advancedOptions[option];
pausedValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(pausedValue);
// undocumented callback when slideshow is paused: function(cont, opts, byHover)
settings.opts[option] = function(cont, opts, byHover) {
eval(pausedValue);
}
break;
case "resumed":
var resumedValue = advancedOptions[option];
resumedValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(resumedValue);
// undocumented callback when slideshow is resumed: function(cont, opts, byHover)
settings.opts[option] = function(cont, opts, byHover) {
eval(resumedValue);
}
break;
case "timeoutFn":
var timeoutFnValue = advancedOptions[option];
timeoutFnValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(timeoutFnValue);
settings.opts[option] = function(currSlideElement, nextSlideElement, options, forwardFlag) {
eval(timeoutFnValue);
}
break;
case "updateActivePagerLink":
var updateActivePagerLinkValue = advancedOptions[option];
updateActivePagerLinkValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(updateActivePagerLinkValue);
// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
settings.opts[option] = function(pager, currSlideIndex) {
eval(updateActivePagerLinkValue);
}
break;
}
}
}
// If selected wait for the images to be loaded.
// otherwise just load the slideshow.
if (settings.wait_for_image_load) {
// For IE/Chrome/Opera we if there are images then we need to make
// sure the images are loaded before starting the slideshow.
settings.totalImages = $(settings.targetId + ' img').length;
if (settings.totalImages) {
settings.loadedImages = 0;
// Add a load event for each image.
$(settings.targetId + ' img').each(function() {
var $imageElement = $(this);
$imageElement.bind('load', function () {
Drupal.viewsSlideshowCycle.imageWait(fullId);
});
// Removing the source and adding it again will fire the load event.
var imgSrc = $imageElement.attr('src');
$imageElement.attr('src', '');
$imageElement.attr('src', imgSrc);
});
// We need to set a timeout so that the slideshow doesn't wait
// indefinitely for all images to load.
setTimeout("Drupal.viewsSlideshowCycle.load('" + fullId + "')", settings.wait_for_image_load_timeout);
}
else {
Drupal.viewsSlideshowCycle.load(fullId);
}
}
else {
Drupal.viewsSlideshowCycle.load(fullId);
}
});
}
};
Drupal.viewsSlideshowCycle = Drupal.viewsSlideshowCycle || {};
// Cleanup the values of advanced options.
Drupal.viewsSlideshowCycle.advancedOptionCleanup = function(value) {
value = $.trim(value);
value = value.replace(/\n/g, '');
if (!isNaN(parseInt(value))) {
value = parseInt(value);
}
else if (value.toLowerCase() == 'true') {
value = true;
}
else if (value.toLowerCase() == 'false') {
value = false;
}
return value;
}
// This checks to see if all the images have been loaded.
// If they have then it starts the slideshow.
Drupal.viewsSlideshowCycle.imageWait = function(fullId) {
if (++Drupal.settings.viewsSlideshowCycle[fullId].loadedImages == Drupal.settings.viewsSlideshowCycle[fullId].totalImages) {
Drupal.viewsSlideshowCycle.load(fullId);
}
};
// Start the slideshow.
Drupal.viewsSlideshowCycle.load = function (fullId) {
var settings = Drupal.settings.viewsSlideshowCycle[fullId];
// Make sure the slideshow isn't already loaded.
if (!settings.loaded) {
$(settings.targetId).cycle(settings.opts);
settings.loaded = true;
// Start Paused
if (settings.start_paused) {
Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId, "force": true });
}
// Pause if hidden.
if (settings.pause_when_hidden) {
var checkPause = function(settings) {
// If the slideshow is visible and it is paused then resume.
// otherwise if the slideshow is not visible and it is not paused then
// pause it.
var visible = viewsSlideshowCycleIsVisible(settings.targetId, settings.pause_when_hidden_type, settings.amount_allowed_visible);
if (visible) {
Drupal.viewsSlideshow.action({ "action": 'play', "slideshowID": settings.slideshowId });
}
else {
Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId });
}
}
// Check when scrolled.
$(window).scroll(function() {
checkPause(settings);
});
// Check when the window is resized.
$(window).resize(function() {
checkPause(settings);
});
}
}
};
Drupal.viewsSlideshowCycle.pause = function (options) {
//Eat TypeError, cycle doesn't handle pause well if options isn't defined.
try{
if (options.pause_in_middle && $.fn.pause) {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).pause();
}
else {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('pause');
}
}
catch(e){
if(!e instanceof TypeError){
throw e;
}
}
};
Drupal.viewsSlideshowCycle.play = function (options) {
Drupal.settings.viewsSlideshowCycle['#views_slideshow_cycle_main_' + options.slideshowID].paused = false;
if (options.pause_in_middle && $.fn.resume) {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).resume();
}
else {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('resume');
}
};
Drupal.viewsSlideshowCycle.previousSlide = function (options) {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('prev');
};
Drupal.viewsSlideshowCycle.nextSlide = function (options) {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('next');
};
Drupal.viewsSlideshowCycle.goToSlide = function (options) {
$('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle(options.slideNum);
};
// Verify that the value is a number.
function IsNumeric(sText) {
var ValidChars = "0123456789";
var IsNumber=true;
var Char;
for (var i=0; i < sText.length && IsNumber == true; i++) {
Char = sText.charAt(i);
if (ValidChars.indexOf(Char) == -1) {
IsNumber = false;
}
}
return IsNumber;
}
/**
* Cookie Handling Functions
*/
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else {
var expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}
/**
* Checks to see if the slide is visible enough.
* elem = element to check.
* type = The way to calculate how much is visible.
* amountVisible = amount that should be visible. Either in percent or px. If
* it's not defined then all of the slide must be visible.
*
* Returns true or false
*/
function viewsSlideshowCycleIsVisible(elem, type, amountVisible) {
// Get the top and bottom of the window;
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var docViewLeft = $(window).scrollLeft();
var docViewRight = docViewLeft + $(window).width();
// Get the top, bottom, and height of the slide;
var elemTop = $(elem).offset().top;
var elemHeight = $(elem).height();
var elemBottom = elemTop + elemHeight;
var elemLeft = $(elem).offset().left;
var elemWidth = $(elem).width();
var elemRight = elemLeft + elemWidth;
var elemArea = elemHeight * elemWidth;
// Calculate what's hiding in the slide.
var missingLeft = 0;
var missingRight = 0;
var missingTop = 0;
var missingBottom = 0;
// Find out how much of the slide is missing from the left.
if (elemLeft < docViewLeft) {
missingLeft = docViewLeft - elemLeft;
}
// Find out how much of the slide is missing from the right.
if (elemRight > docViewRight) {
missingRight = elemRight - docViewRight;
}
// Find out how much of the slide is missing from the top.
if (elemTop < docViewTop) {
missingTop = docViewTop - elemTop;
}
// Find out how much of the slide is missing from the bottom.
if (elemBottom > docViewBottom) {
missingBottom = elemBottom - docViewBottom;
}
// If there is no amountVisible defined then check to see if the whole slide
// is visible.
if (type == 'full') {
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
&& (elemBottom <= docViewBottom) && (elemTop >= docViewTop)
&& (elemLeft >= docViewLeft) && (elemRight <= docViewRight)
&& (elemLeft <= docViewRight) && (elemRight >= docViewLeft));
}
else if(type == 'vertical') {
var verticalShowing = elemHeight - missingTop - missingBottom;
// If user specified a percentage then find out if the current shown percent
// is larger than the allowed percent.
// Otherwise check to see if the amount of px shown is larger than the
// allotted amount.
if (amountVisible.indexOf('%')) {
return (((verticalShowing/elemHeight)*100) >= parseInt(amountVisible));
}
else {
return (verticalShowing >= parseInt(amountVisible));
}
}
else if(type == 'horizontal') {
var horizontalShowing = elemWidth - missingLeft - missingRight;
// If user specified a percentage then find out if the current shown percent
// is larger than the allowed percent.
// Otherwise check to see if the amount of px shown is larger than the
// allotted amount.
if (amountVisible.indexOf('%')) {
return (((horizontalShowing/elemWidth)*100) >= parseInt(amountVisible));
}
else {
return (horizontalShowing >= parseInt(amountVisible));
}
}
else if(type == 'area') {
var areaShowing = (elemWidth - missingLeft - missingRight) * (elemHeight - missingTop - missingBottom);
// If user specified a percentage then find out if the current shown percent
// is larger than the allowed percent.
// Otherwise check to see if the amount of px shown is larger than the
// allotted amount.
if (amountVisible.indexOf('%')) {
return (((areaShowing/elemArea)*100) >= parseInt(amountVisible));
}
else {
return (areaShowing >= parseInt(amountVisible));
}
}
}
})(jQuery);
;
(function ($) {
Drupal.googleanalytics = {};
$(document).ready(function() {
// Attach mousedown, keyup, touchstart events to document only and catch
// clicks on all elements.
$(document.body).bind("mousedown keyup touchstart", function(event) {
// Catch the closest surrounding link of a clicked element.
$(event.target).closest("a,area").each(function() {
// Is the clicked URL internal?
if (Drupal.googleanalytics.isInternal(this.href)) {
// Skip 'click' tracking, if custom tracking events are bound.
if ($(this).is('.colorbox') && (Drupal.settings.googleanalytics.trackColorbox)) {
// Do nothing here. The custom event will handle all tracking.
//console.info("Click on .colorbox item has been detected.");
}
// Is download tracking activated and the file extension configured for download tracking?
else if (Drupal.settings.googleanalytics.trackDownload && Drupal.googleanalytics.isDownload(this.href)) {
// Download link clicked.
gtag('event', Drupal.googleanalytics.getDownloadExtension(this.href).toUpperCase(), {
event_category: 'Downloads',
event_label: Drupal.googleanalytics.getPageUrl(this.href),
transport_type: 'beacon'
});
}
else if (Drupal.googleanalytics.isInternalSpecial(this.href)) {
// Keep the internal URL for Google Analytics website overlay intact.
// @todo: May require tracking ID
var target = this;
$.each(drupalSettings.google_analytics.account, function () {
gtag('config', this, {
page_path: Drupal.googleanalytics.getPageUrl(target.href),
transport_type: 'beacon'
});
});
}
}
else {
if (Drupal.settings.googleanalytics.trackMailto && $(this).is("a[href^='mailto:'],area[href^='mailto:']")) {
// Mailto link clicked.
gtag('event', 'Click', {
event_category: 'Mails',
event_label: this.href.substring(7),
transport_type: 'beacon'
});
}
else if (Drupal.settings.googleanalytics.trackOutbound && this.href.match(/^\w+:\/\//i)) {
if (Drupal.settings.googleanalytics.trackDomainMode !== 2 || (Drupal.settings.googleanalytics.trackDomainMode === 2 && !Drupal.googleanalytics.isCrossDomain(this.hostname, Drupal.settings.googleanalytics.trackCrossDomains))) {
// External link clicked / No top-level cross domain clicked.
gtag('event', 'Click', {
event_category: 'Outbound links',
event_label: this.href,
transport_type: 'beacon'
});
}
}
}
});
});
// Track hash changes as unique pageviews, if this option has been enabled.
if (Drupal.settings.googleanalytics.trackUrlFragments) {
window.onhashchange = function() {
$.each(drupalSettings.google_analytics.account, function () {
gtag('config', this, {
page_path: location.pathname + location.search + location.hash
});
});
};
}
// Colorbox: This event triggers when the transition has completed and the
// newly loaded content has been revealed.
if (Drupal.settings.googleanalytics.trackColorbox) {
$(document).bind("cbox_complete", function () {
var href = $.colorbox.element().attr("href");
if (href) {
$.each(drupalSettings.google_analytics.account, function () {
gtag('config', this, {
page_path: Drupal.googleanalytics.getPageUrl(href)
});
});
}
});
}
});
/**
* Check whether the hostname is part of the cross domains or not.
*
* @param string hostname
* The hostname of the clicked URL.
* @param array crossDomains
* All cross domain hostnames as JS array.
*
* @return boolean
*/
Drupal.googleanalytics.isCrossDomain = function (hostname, crossDomains) {
/**
* jQuery < 1.6.3 bug: $.inArray crushes IE6 and Chrome if second argument is
* `null` or `undefined`, https://bugs.jquery.com/ticket/10076,
* https://github.com/jquery/jquery/commit/a839af034db2bd934e4d4fa6758a3fed8de74174
*
* @todo: Remove/Refactor in D8
*/
if (!crossDomains) {
return false;
}
else {
return $.inArray(hostname, crossDomains) > -1 ? true : false;
}
};
/**
* Check whether this is a download URL or not.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isDownload = function (url) {
var isDownload = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
return isDownload.test(url);
};
/**
* Check whether this is an absolute internal URL or not.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isInternal = function (url) {
var isInternal = new RegExp("^(https?):\/\/" + window.location.host, "i");
return isInternal.test(url);
};
/**
* Check whether this is a special URL or not.
*
* URL types:
* - gotwo.module /go/* links.
*
* @param string url
* The web url to check.
*
* @return boolean
*/
Drupal.googleanalytics.isInternalSpecial = function (url) {
var isInternalSpecial = new RegExp("(\/go\/.*)$", "i");
return isInternalSpecial.test(url);
};
/**
* Extract the relative internal URL from an absolute internal URL.
*
* Examples:
* - https://mydomain.com/node/1 -> /node/1
* - https://example.com/foo/bar -> https://example.com/foo/bar
*
* @param string url
* The web url to check.
*
* @return string
* Internal website URL
*/
Drupal.googleanalytics.getPageUrl = function (url) {
var extractInternalUrl = new RegExp("^(https?):\/\/" + window.location.host, "i");
return url.replace(extractInternalUrl, '');
};
/**
* Extract the download file extension from the URL.
*
* @param string url
* The web url to check.
*
* @return string
* The file extension of the passed url. e.g. "zip", "txt"
*/
Drupal.googleanalytics.getDownloadExtension = function (url) {
var extractDownloadextension = new RegExp("\\.(" + Drupal.settings.googleanalytics.trackDownloadExtensions + ")([\?#].*)?$", "i");
var extension = extractDownloadextension.exec(url);
return (extension === null) ? '' : extension[1];
};
})(jQuery);
;