Linux ip-172-26-7-228 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64
Your IP : 18.116.85.96
/**
* @file
* Add jCarousel behaviors to the page and provide Views-support.
*/
(function($) {
Drupal.behaviors.jcarousel = {};
Drupal.behaviors.jcarousel.attach = function(context, settings) {
settings = settings || Drupal.settings;
// If no carousels exist on this part of the page, work no further.
if (!settings.jcarousel || !settings.jcarousel.carousels) {
return;
}
$("ul.jcarousel li").css("display", "");
$.each(settings.jcarousel.carousels, function(key, options) {
var $carousel = $(options.selector + ':not(.jcarousel-processed)', context);
// If this carousel has already been processed or doesn't exist, move on.
if (!$carousel.length) {
return;
}
// Callbacks need to be converted from a string to an actual function.
$.each(options, function(optionKey) {
if (optionKey.match(/Callback$/) && typeof options[optionKey] == 'string') {
var callbackFunction = window;
var callbackParents = options[optionKey].split('.');
$.each(callbackParents, function(objectParent) {
callbackFunction = callbackFunction[callbackParents[objectParent]];
});
options[optionKey] = callbackFunction;
}
});
// Add standard options required for AJAX functionality.
if (options.ajax && !options.itemLoadCallback) {
options.itemLoadCallback = Drupal.jcarousel.ajaxLoadCallback;
}
// If auto-scrolling, pause animation when hoving over the carousel.
if (options.auto && options.autoPause && !options.initCallback) {
options.initCallback = function(carousel, state) {
Drupal.jcarousel.autoPauseCallback(carousel, state);
};
}
// Add responsive behavior.
if (options.responsive && !options.reloadCallback) {
options.vertical = false;
options.visible = null;
options.reloadCallback = Drupal.jcarousel.reloadCallback;
}
// Add navigation to the carousel if enabled.
if (!options.setupCallback) {
options.setupCallback = function(carousel) {
Drupal.jcarousel.setupCarousel(carousel);
if (options.navigation) {
Drupal.jcarousel.addNavigation(carousel, options.navigation);
}
if (options.responsive) {
carousel.reload();
}
};
if (options.navigation && !options.itemVisibleInCallback) {
options.itemLastInCallback = {
onAfterAnimation: Drupal.jcarousel.updateNavigationActive
};
}
}
if (!options.hasOwnProperty('buttonNextHTML') && !options.hasOwnProperty('buttonPrevHTML')) {
options.buttonNextHTML = Drupal.theme('jCarouselButton', 'next');
options.buttonPrevHTML = Drupal.theme('jCarouselButton', 'previous');
}
// Initialize the jcarousel.
$carousel.addClass('jcarousel-processed').jcarousel(options);
});
};
Drupal.jcarousel = {};
Drupal.jcarousel.reloadCallback = function(carousel) {
// Set the clip and container to auto width so that they will fill
// the available space.
carousel.container.css('width', 'auto');
carousel.clip.css('width', 'auto');
var clipWidth = carousel.clip.width();
var containerExtra = carousel.container.width() - carousel.clip.outerWidth(true);
// Determine the width of an item.
var itemWidth = carousel.list.find('li').first().outerWidth(true);
var numItems = Math.floor(carousel.clip.width() / itemWidth) || 1;
// Set the new scroll number.
carousel.options.scroll = numItems;
var newClipWidth = numItems * itemWidth;
var newContainerWidth = newClipWidth + containerExtra;
// Resize the clip and container.
carousel.clip.width(newClipWidth);
carousel.container.width(newContainerWidth);
};
Drupal.jcarousel.ajaxLoadCallback = function(jcarousel, state) {
// Check if the requested items already exist.
if (state == 'init' || jcarousel.has(jcarousel.first, jcarousel.last)) {
return;
}
var $list = jcarousel.list;
var $view = $list.parents('.view:first');
var ajaxPath = Drupal.settings.jcarousel.ajaxPath;
var target = $view.get(0);
// Find this view's settings in the Views AJAX settings.
var settings;
$.each(Drupal.settings.jcarousel.carousels, function(domID, carouselSettings) {
if ($list.is('.' + domID)) {
settings = carouselSettings['view_options'];
}
});
// Copied from ajax_view.js:
var viewData = { 'js': 1, 'first': jcarousel.first - 1, 'last': jcarousel.last };
// Construct an object using the settings defaults and then overriding
// with data specific to the link.
$.extend(
viewData,
settings
);
$.ajax({
url: ajaxPath,
type: 'GET',
data: viewData,
success: function(response) {
Drupal.jcarousel.ajaxResponseCallback(jcarousel, target, response);
},
error: function(xhr) {
Drupal.jcarousel.ajaxErrorCallback(xhr, ajaxPath);
},
dataType: 'json'
});
};
/**
* Init callback for jCarousel. Pauses the carousel when hovering over.
*/
Drupal.jcarousel.autoPauseCallback = function(carousel, state) {
function pauseAuto() {
carousel.stopAuto();
}
function resumeAuto() {
carousel.startAuto();
}
carousel.clip.hover(pauseAuto, resumeAuto);
carousel.buttonNext.hover(pauseAuto, resumeAuto);
carousel.buttonPrev.hover(pauseAuto, resumeAuto);
};
/**
* Setup callback for jCarousel. Calculates number of pages.
*/
Drupal.jcarousel.setupCarousel = function(carousel) {
// Determine the number of pages this carousel includes.
// This only works for a positive starting point. Also, .first is 1-based
// while .last is a count, so we need to reset the .first number to be
// 0-based to make the math work.
carousel.pageSize = carousel.last - (carousel.first - 1);
// jCarousel's Views integration sets "size" in the carousel options. Use that
// if available, otherwise count the number of items in the carousel.
var itemCount = carousel.options.size ? carousel.options.size : $(carousel.list).children('li').length;
carousel.pageCount = Math.ceil(itemCount / carousel.pageSize);
carousel.pageNumber = 1;
// Disable the previous/next arrows if there is only one page.
if (carousel.options.wrap != 'circular' && carousel.pageCount == 1) {
carousel.buttons(false, false);
}
// Always remove the hard-coded display: block from the navigation.
carousel.buttonNext.css('display', '');
carousel.buttonPrev.css('display', '');
}
/**
* Setup callback for jCarousel. Adds the navigation to the carousel if enabled.
*/
Drupal.jcarousel.addNavigation = function(carousel, position) {
// Don't add a pager if there's only one page of results.
if (carousel.pageCount <= 1) {
return;
}
// Add a class to the wrapper so it can adjust CSS.
$(carousel.list).parents('.jcarousel-container:first').addClass('jcarousel-navigation-' + position);
var navigation = $('<ul class="jcarousel-navigation"></ul>');
for (var i = 1; i <= carousel.pageCount; i++) {
var pagerItem = $(Drupal.theme('jCarouselPageLink', i));
var listItem = $('<li></li>').attr('jcarousel-page', i).append(pagerItem);
navigation.append(listItem);
// Make the first page active by default.
if (i === 1) {
listItem.addClass('active');
}
// Scroll to the correct page when a pager is clicked.
pagerItem.bind('click', function() {
// We scroll to the new page based on item offsets. This works with
// circular carousels that do not divide items evenly, making it so that
// going back or forward in pages will not skip or repeat any items.
var newPageNumber = $(this).parent().attr('jcarousel-page');
var itemOffset = (newPageNumber - carousel.pageNumber) * carousel.pageSize;
if (itemOffset) {
carousel.scroll(carousel.first + itemOffset);
}
return false;
});
}
$(carousel.list).parents('.jcarousel-clip:first')[position](navigation);
}
/**
* itemVisibleInCallback for jCarousel. Update the navigation after page change.
*/
Drupal.jcarousel.updateNavigationActive = function(carousel, item, idx, state) {
// The navigation doesn't even exist yet when this is called on init.
var $listItems = $(carousel.list).parents('.jcarousel-container:first').find('.jcarousel-navigation li');
if ($listItems.length == 0) {
return;
}
// jCarousel does some very odd things with circular wraps. Items before the
// first item are given negative numbers and items after the last are given
// numbers beyond the total number of items. This complicated logic calculates
// which page number is active based off this numbering scheme.
var pageNumber = Math.ceil(idx / carousel.pageSize);
if (pageNumber <= 0 || pageNumber > carousel.pageCount) {
pageNumber = pageNumber % carousel.pageCount;
pageNumber = pageNumber == 0 ? carousel.pageCount : pageNumber;
pageNumber = pageNumber < 0 ? pageNumber + carousel.pageCount : pageNumber;
}
carousel.pageNumber = pageNumber;
var currentPage = $listItems.get(carousel.pageNumber - 1);
// Set the current page to be active.
$listItems.not(currentPage).removeClass('active');
$(currentPage).addClass('active');
}
/**
* AJAX callback for all jCarousel-style views.
*/
Drupal.jcarousel.ajaxResponseCallback = function(jcarousel, target, response) {
if (response.debug) {
alert(response.debug);
}
var $view = $(target);
var jcarousel = $view.find('ul.jcarousel').data('jcarousel');
// Add items to the jCarousel.
$('ul.jcarousel > li', response.display).each(function(i) {
var itemNumber = this.className.replace(/.*?jcarousel-item-(\d+).*/, '$1');
jcarousel.add(itemNumber, this.innerHTML);
});
// Add Drupal behaviors to the content of the carousel to affect new items.
Drupal.attachBehaviors(jcarousel.list.get(0));
// Treat messages the same way that Views typically handles messages.
if (response.messages) {
// Show any messages (but first remove old ones, if there are any).
$view.find('.views-messages').remove().end().prepend(response.messages);
}
};
/**
* Display error messages using the same mechanism as Views module.
*/
Drupal.jcarousel.ajaxErrorCallback = function (xhr, path) {
var error_text = '';
if ((xhr.status == 500 && xhr.responseText) || xhr.status == 200) {
error_text = xhr.responseText;
// Replace all < and > by < and >
error_text = error_text.replace("/&(lt|gt);/g", function (m, p) {
return (p == "lt")? "<" : ">";
});
// Now, replace all html tags by empty spaces
error_text = error_text.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,"");
// Fix end lines
error_text = error_text.replace(/[\n]+\s+/g,"\n");
}
else if (xhr.status == 500) {
error_text = xhr.status + ': ' + Drupal.t("Internal server error. Please see server or PHP logs for error information.");
}
else {
error_text = xhr.status + ': ' + xhr.statusText;
}
alert(Drupal.t("An error occurred at @path.\n\nError Description: @error", {'@path': path, '@error': error_text}));
};
Drupal.theme.prototype.jCarouselButton = function(type) {
// Use links for buttons for accessibility.
return '<a href="javascript:void(0)"></a>';
};
Drupal.theme.prototype.jCarouselPageLink = function(pageNumber) {
return '<a href="javascript:void(0)"><span>' + (pageNumber) + '</span></a>';
};
})(jQuery);
|