X-Git-Url: https://git.toastfreeware.priv.at/philipp/winterrodeln/wradmin.git/blobdiff_plain/47e86061cfc74f70ea67b8e41df9ca7b2d06b203..7170338241015cb2aee98f126ebf088e92284987:/wradmin/static/yui/carousel/carousel.js diff --git a/wradmin/static/yui/carousel/carousel.js b/wradmin/static/yui/carousel/carousel.js deleted file mode 100644 index f957c1f..0000000 --- a/wradmin/static/yui/carousel/carousel.js +++ /dev/null @@ -1,3616 +0,0 @@ -/* -Copyright (c) 2009, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 2.7.0 -*/ -/** - * The Carousel module provides a widget for browsing among a set of like - * objects represented pictorially. - * - * @module carousel - * @requires yahoo, dom, event, element - * @optional animation - * @namespace YAHOO.widget - * @title Carousel Widget - * @beta - */ -(function () { - - var WidgetName; // forward declaration - - /** - * The Carousel widget. - * - * @class Carousel - * @extends YAHOO.util.Element - * @constructor - * @param el {HTMLElement | String} The HTML element that represents the - * the container that houses the Carousel. - * @param cfg {Object} (optional) The configuration values - */ - YAHOO.widget.Carousel = function (el, cfg) { - - YAHOO.widget.Carousel.superclass.constructor.call(this, el, cfg); - }; - - /* - * Private variables of the Carousel component - */ - - /* Some abbreviations to avoid lengthy typing and lookups. */ - var Carousel = YAHOO.widget.Carousel, - Dom = YAHOO.util.Dom, - Event = YAHOO.util.Event, - JS = YAHOO.lang; - - /** - * The widget name. - * @private - * @static - */ - WidgetName = "Carousel"; - - /** - * The internal table of Carousel instances. - * @private - * @static - */ - var instances = {}, - - /* - * Custom events of the Carousel component - */ - - /** - * @event afterScroll - * @description Fires when the Carousel has scrolled to the previous or - * next page. Passes back the index of the first and last visible items in - * the Carousel. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - afterScrollEvent = "afterScroll", - - /** - * @event allItemsRemovedEvent - * @description Fires when all items have been removed from the Carousel. - * See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - allItemsRemovedEvent = "allItemsRemoved", - - /** - * @event beforeHide - * @description Fires before the Carousel is hidden. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - beforeHideEvent = "beforeHide", - - /** - * @event beforePageChange - * @description Fires when the Carousel is about to scroll to the previous - * or next page. Passes back the page number of the current page. Note - * that the first page number is zero. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - beforePageChangeEvent = "beforePageChange", - - /** - * @event beforeScroll - * @description Fires when the Carousel is about to scroll to the previous - * or next page. Passes back the index of the first and last visible items - * in the Carousel and the direction (backward/forward) of the scroll. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - beforeScrollEvent = "beforeScroll", - - /** - * @event beforeShow - * @description Fires when the Carousel is about to be shown. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - beforeShowEvent = "beforeShow", - - /** - * @event blur - * @description Fires when the Carousel loses focus. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - blurEvent = "blur", - - /** - * @event focus - * @description Fires when the Carousel gains focus. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - focusEvent = "focus", - - /** - * @event hide - * @description Fires when the Carousel is hidden. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - hideEvent = "hide", - - /** - * @event itemAdded - * @description Fires when an item has been added to the Carousel. Passes - * back the content of the item that would be added, the index at which the - * item would be added, and the event itself. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - itemAddedEvent = "itemAdded", - - /** - * @event itemRemoved - * @description Fires when an item has been removed from the Carousel. - * Passes back the content of the item that would be removed, the index - * from which the item would be removed, and the event itself. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - itemRemovedEvent = "itemRemoved", - - /** - * @event itemSelected - * @description Fires when an item has been selected in the Carousel. - * Passes back the index of the selected item in the Carousel. Note, that - * the index begins from zero. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - itemSelectedEvent = "itemSelected", - - /** - * @event loadItems - * @description Fires when the Carousel needs more items to be loaded for - * displaying them. Passes back the first and last visible items in the - * Carousel, and the number of items needed to be loaded. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - loadItemsEvent = "loadItems", - - /** - * @event navigationStateChange - * @description Fires when the state of either one of the navigation - * buttons are changed from enabled to disabled or vice versa. Passes back - * the state (true/false) of the previous and next buttons. The value true - * signifies the button is enabled, false signifies disabled. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - navigationStateChangeEvent = "navigationStateChange", - - /** - * @event pageChange - * @description Fires after the Carousel has scrolled to the previous or - * next page. Passes back the page number of the current page. Note - * that the first page number is zero. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - pageChangeEvent = "pageChange", - - /* - * Internal event. - * @event render - * @description Fires when the Carousel is rendered. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - renderEvent = "render", - - /** - * @event show - * @description Fires when the Carousel is shown. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - showEvent = "show", - - /** - * @event startAutoPlay - * @description Fires when the auto play has started in the Carousel. See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - startAutoPlayEvent = "startAutoPlay", - - /** - * @event stopAutoPlay - * @description Fires when the auto play has been stopped in the Carousel. - * See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - stopAutoPlayEvent = "stopAutoPlay", - - /* - * Internal event. - * @event uiUpdateEvent - * @description Fires when the UI has been updated. - * See - * Element.addListener - * for more information on listening for this event. - * @type YAHOO.util.CustomEvent - */ - uiUpdateEvent = "uiUpdate"; - - /* - * Private helper functions used by the Carousel component - */ - - /** - * Create an element, set its class name and optionally install the element - * to its parent. - * @method createElement - * @param el {String} The element to be created - * @param attrs {Object} Configuration of parent, class and id attributes. - * If the content is specified, it is inserted after creation of the - * element. The content can also be an HTML element in which case it would - * be appended as a child node of the created element. - * @private - */ - function createElement(el, attrs) { - var newEl = document.createElement(el); - - attrs = attrs || {}; - if (attrs.className) { - Dom.addClass(newEl, attrs.className); - } - - if (attrs.parent) { - attrs.parent.appendChild(newEl); - } - - if (attrs.id) { - newEl.setAttribute("id", attrs.id); - } - - if (attrs.content) { - if (attrs.content.nodeName) { - newEl.appendChild(attrs.content); - } else { - newEl.innerHTML = attrs.content; - } - } - - return newEl; - } - - /** - * Get the computed style of an element. - * - * @method getStyle - * @param el {HTMLElement} The element for which the style needs to be - * returned. - * @param style {String} The style attribute - * @param type {String} "int", "float", etc. (defaults to int) - * @private - */ - function getStyle(el, style, type) { - var value; - - if (!el) { - return 0; - } - - function getStyleIntVal(el, style) { - var val; - - /* - * XXX: Safari calculates incorrect marginRight for an element - * which has its parent element style set to overflow: hidden - * https://bugs.webkit.org/show_bug.cgi?id=13343 - * Let us assume marginLeft == marginRight - */ - if (style == "marginRight" && YAHOO.env.ua.webkit) { - val = parseInt(Dom.getStyle(el, "marginLeft"), 10); - } else { - val = parseInt(Dom.getStyle(el, style), 10); - } - - return JS.isNumber(val) ? val : 0; - } - - function getStyleFloatVal(el, style) { - var val; - - /* - * XXX: Safari calculates incorrect marginRight for an element - * which has its parent element style set to overflow: hidden - * https://bugs.webkit.org/show_bug.cgi?id=13343 - * Let us assume marginLeft == marginRight - */ - if (style == "marginRight" && YAHOO.env.ua.webkit) { - val = parseFloat(Dom.getStyle(el, "marginLeft")); - } else { - val = parseFloat(Dom.getStyle(el, style)); - } - - return JS.isNumber(val) ? val : 0; - } - - if (typeof type == "undefined") { - type = "int"; - } - - switch (style) { - case "height": - value = el.offsetHeight; - if (value > 0) { - value += getStyleIntVal(el, "marginTop") + - getStyleIntVal(el, "marginBottom"); - } else { - value = getStyleFloatVal(el, "height") + - getStyleIntVal(el, "marginTop") + - getStyleIntVal(el, "marginBottom") + - getStyleIntVal(el, "borderTopWidth") + - getStyleIntVal(el, "borderBottomWidth") + - getStyleIntVal(el, "paddingTop") + - getStyleIntVal(el, "paddingBottom"); - } - break; - case "width": - value = el.offsetWidth; - if (value > 0) { - value += getStyleIntVal(el, "marginLeft") + - getStyleIntVal(el, "marginRight"); - } else { - value = getStyleFloatVal(el, "width") + - getStyleIntVal(el, "marginLeft") + - getStyleIntVal(el, "marginRight") + - getStyleIntVal(el, "borderLeftWidth") + - getStyleIntVal(el, "borderRightWidth") + - getStyleIntVal(el, "paddingLeft") + - getStyleIntVal(el, "paddingRight"); - } - break; - default: - if (type == "int") { - value = getStyleIntVal(el, style); - } else if (type == "float") { - value = getStyleFloatVal(el, style); - } else { - value = Dom.getStyle(el, style); - } - break; - } - - return value; - } - - /** - * Compute and return the height or width of a single Carousel item - * depending upon the orientation. - * - * @method getCarouselItemSize - * @param which {String} "height" or "width" to be returned. If this is - * passed explicitly, the calculated size is not cached. - * @private - */ - function getCarouselItemSize(which) { - var carousel = this, - child, - size = 0, - vertical = false; - - if (carousel._itemsTable.numItems === 0) { - return 0; - } - - if (typeof which == "undefined") { - if (carousel._itemsTable.size > 0) { - return carousel._itemsTable.size; - } - } - - if (JS.isUndefined(carousel._itemsTable.items[0])) { - return 0; - } - - child = Dom.get(carousel._itemsTable.items[0].id); - - if (typeof which == "undefined") { - vertical = carousel.get("isVertical"); - } else { - vertical = which == "height"; - } - - if (vertical) { - size = getStyle(child, "height"); - } else { - size = getStyle(child, "width"); - } - - if (typeof which == "undefined") { - carousel._itemsTable.size = size; // save the size for later - } - - return size; - } - - /** - * Return the index of the first item in the view port for displaying item - * in "pos". - * - * @method getFirstVisibleForPosition - * @param pos {Number} The position of the item to be displayed - * @private - */ - function getFirstVisibleForPosition(pos) { - var num = this.get("numVisible"); - - return Math.floor(pos / num) * num; - } - - /** - * Return the scrolling offset size given the number of elements to - * scroll. - * - * @method getScrollOffset - * @param delta {Number} The delta number of elements to scroll by. - * @private - */ - function getScrollOffset(delta) { - var itemSize = 0, - size = 0; - - itemSize = getCarouselItemSize.call(this); - size = itemSize * delta; - - // XXX: really, when the orientation is vertical, the scrolling - // is not exactly the number of elements into element size. - if (this.get("isVertical")) { - size -= delta; - } - - return size; - } - - /** - * Scroll the Carousel by a page backward. - * - * @method scrollPageBackward - * @param {Event} ev The event object - * @param {Object} obj The context object - * @private - */ - function scrollPageBackward(ev, obj) { - obj.scrollPageBackward(); - Event.preventDefault(ev); - } - - /** - * Scroll the Carousel by a page forward. - * - * @method scrollPageForward - * @param {Event} ev The event object - * @param {Object} obj The context object - * @private - */ - function scrollPageForward(ev, obj) { - obj.scrollPageForward(); - Event.preventDefault(ev); - } - - /** - * Set the selected item. - * - * @method setItemSelection - * @param {Number} newpos The index of the new position - * @param {Number} oldpos The index of the previous position - * @private - */ - function setItemSelection(newpos, oldpos) { - var carousel = this, - cssClass = carousel.CLASSES, - el, - firstItem = carousel._firstItem, - isCircular = carousel.get("isCircular"), - numItems = carousel.get("numItems"), - numVisible = carousel.get("numVisible"), - position = oldpos, - sentinel = firstItem + numVisible - 1; - - if (position >= 0 && position < numItems) { - if (!JS.isUndefined(carousel._itemsTable.items[position])) { - el = Dom.get(carousel._itemsTable.items[position].id); - if (el) { - Dom.removeClass(el, cssClass.SELECTED_ITEM); - } - } - } - - if (JS.isNumber(newpos)) { - newpos = parseInt(newpos, 10); - newpos = JS.isNumber(newpos) ? newpos : 0; - } else { - newpos = firstItem; - } - - if (JS.isUndefined(carousel._itemsTable.items[newpos])) { - newpos = getFirstVisibleForPosition.call(carousel, newpos); - carousel.scrollTo(newpos); // still loading the item - } - - if (!JS.isUndefined(carousel._itemsTable.items[newpos])) { - el = Dom.get(carousel._itemsTable.items[newpos].id); - if (el) { - Dom.addClass(el, cssClass.SELECTED_ITEM); - } - } - - if (newpos < firstItem || newpos > sentinel) { // out of focus - newpos = getFirstVisibleForPosition.call(carousel, newpos); - carousel.scrollTo(newpos); - } - } - - /** - * Fire custom events for enabling/disabling navigation elements. - * - * @method syncNavigation - * @private - */ - function syncNavigation() { - var attach = false, - carousel = this, - cssClass = carousel.CLASSES, - i, - navigation, - sentinel; - - // Don't do anything if the Carousel is not rendered - if (!carousel._hasRendered) { - return; - } - - navigation = carousel.get("navigation"); - sentinel = carousel._firstItem + carousel.get("numVisible"); - - if (navigation.prev) { - if (carousel.get("numItems") === 0 || carousel._firstItem === 0) { - if (carousel.get("numItems") === 0 || - !carousel.get("isCircular")) { - Event.removeListener(navigation.prev, "click", - scrollPageBackward); - Dom.addClass(navigation.prev, cssClass.FIRST_NAV_DISABLED); - for (i = 0; i < carousel._navBtns.prev.length; i++) { - carousel._navBtns.prev[i].setAttribute("disabled", - "true"); - } - carousel._prevEnabled = false; - } else { - attach = !carousel._prevEnabled; - } - } else { - attach = !carousel._prevEnabled; - } - - if (attach) { - Event.on(navigation.prev, "click", scrollPageBackward, - carousel); - Dom.removeClass(navigation.prev, cssClass.FIRST_NAV_DISABLED); - for (i = 0; i < carousel._navBtns.prev.length; i++) { - carousel._navBtns.prev[i].removeAttribute("disabled"); - } - carousel._prevEnabled = true; - } - } - - attach = false; - if (navigation.next) { - if (sentinel >= carousel.get("numItems")) { - if (!carousel.get("isCircular")) { - Event.removeListener(navigation.next, "click", - scrollPageForward); - Dom.addClass(navigation.next, cssClass.DISABLED); - for (i = 0; i < carousel._navBtns.next.length; i++) { - carousel._navBtns.next[i].setAttribute("disabled", - "true"); - } - carousel._nextEnabled = false; - } else { - attach = !carousel._nextEnabled; - } - } else { - attach = !carousel._nextEnabled; - } - - if (attach) { - Event.on(navigation.next, "click", scrollPageForward, - carousel); - Dom.removeClass(navigation.next, cssClass.DISABLED); - for (i = 0; i < carousel._navBtns.next.length; i++) { - carousel._navBtns.next[i].removeAttribute("disabled"); - } - carousel._nextEnabled = true; - } - } - - carousel.fireEvent(navigationStateChangeEvent, - { next: carousel._nextEnabled, prev: carousel._prevEnabled }); - } - - /** - * Synchronize and redraw the Pager UI if necessary. - * - * @method syncPagerUi - * @private - */ - function syncPagerUi(page) { - var carousel = this, numPages, numVisible; - - // Don't do anything if the Carousel is not rendered - if (!carousel._hasRendered) { - return; - } - - numVisible = carousel.get("numVisible"); - - if (!JS.isNumber(page)) { - page = Math.ceil(carousel.get("selectedItem") / numVisible); - } - numPages = Math.ceil(carousel.get("numItems") / numVisible); - - carousel._pages.num = numPages; - carousel._pages.cur = page; - - if (numPages > carousel.CONFIG.MAX_PAGER_BUTTONS) { - carousel._updatePagerMenu(); - } else { - carousel._updatePagerButtons(); - } - } - - /** - * Handle UI update. - * Call the appropriate methods on events fired when an item is added, or - * removed for synchronizing the DOM. - * - * @method syncUi - * @param {Object} o The item that needs to be added or removed - * @private - */ - function syncUi(o) { - var carousel = this; - - if (!JS.isObject(o)) { - return; - } - - switch (o.ev) { - case itemAddedEvent: - carousel._syncUiForItemAdd(o); - break; - case itemRemovedEvent: - carousel._syncUiForItemRemove(o); - break; - case loadItemsEvent: - carousel._syncUiForLazyLoading(o); - break; - } - - carousel.fireEvent(uiUpdateEvent); - } - - /** - * Update the state variables after scrolling the Carousel view port. - * - * @method updateStateAfterScroll - * @param {Integer} item The index to which the Carousel has scrolled to. - * @param {Integer} sentinel The last element in the view port. - * @private - */ - function updateStateAfterScroll(item, sentinel) { - var carousel = this, - page = carousel.get("currentPage"), - newPage, - numPerPage = carousel.get("numVisible"); - - newPage = parseInt(carousel._firstItem / numPerPage, 10); - if (newPage != page) { - carousel.setAttributeConfig("currentPage", { value: newPage }); - carousel.fireEvent(pageChangeEvent, newPage); - } - - if (carousel.get("selectOnScroll")) { - if (carousel.get("selectedItem") != carousel._selectedItem) { - carousel.set("selectedItem", carousel._selectedItem); - } - } - - clearTimeout(carousel._autoPlayTimer); - delete carousel._autoPlayTimer; - if (carousel.isAutoPlayOn()) { - carousel.startAutoPlay(); - } - - carousel.fireEvent(afterScrollEvent, - { first: carousel._firstItem, - last: sentinel }, - carousel); - } - - /* - * Static members and methods of the Carousel component - */ - - /** - * Return the appropriate Carousel object based on the id associated with - * the Carousel element or false if none match. - * @method getById - * @public - * @static - */ - Carousel.getById = function (id) { - return instances[id] ? instances[id].object : false; - }; - - YAHOO.extend(Carousel, YAHOO.util.Element, { - - /* - * Internal variables used within the Carousel component - */ - - /** - * The Animation object. - * - * @property _animObj - * @private - */ - _animObj: null, - - /** - * The Carousel element. - * - * @property _carouselEl - * @private - */ - _carouselEl: null, - - /** - * The Carousel clipping container element. - * - * @property _clipEl - * @private - */ - _clipEl: null, - - /** - * The current first index of the Carousel. - * - * @property _firstItem - * @private - */ - _firstItem: 0, - - /** - * Does the Carousel element have focus? - * - * @property _hasFocus - * @private - */ - _hasFocus: false, - - /** - * Is the Carousel rendered already? - * - * @property _hasRendered - * @private - */ - _hasRendered: false, - - /** - * Is the animation still in progress? - * - * @property _isAnimationInProgress - * @private - */ - _isAnimationInProgress: false, - - /** - * Is the auto-scrolling of Carousel in progress? - * - * @property _isAutoPlayInProgress - * @private - */ - _isAutoPlayInProgress: false, - - /** - * The table of items in the Carousel. - * The numItems is the number of items in the Carousel, items being the - * array of items in the Carousel. The size is the size of a single - * item in the Carousel. It is cached here for efficiency (to avoid - * computing the size multiple times). - * - * @property _itemsTable - * @private - */ - _itemsTable: null, - - /** - * The Carousel navigation buttons. - * - * @property _navBtns - * @private - */ - _navBtns: null, - - /** - * The Carousel navigation. - * - * @property _navEl - * @private - */ - _navEl: null, - - /** - * Status of the next navigation item. - * - * @property _nextEnabled - * @private - */ - _nextEnabled: true, - - /** - * The Carousel pages structure. - * This is an object of the total number of pages and the current page. - * - * @property _pages - * @private - */ - _pages: null, - - /** - * Status of the previous navigation item. - * - * @property _prevEnabled - * @private - */ - _prevEnabled: true, - - /** - * Whether the Carousel size needs to be recomputed or not? - * - * @property _recomputeSize - * @private - */ - _recomputeSize: true, - - /* - * CSS classes used by the Carousel component - */ - - CLASSES: { - - /** - * The class name of the Carousel navigation buttons. - * - * @property BUTTON - * @default "yui-carousel-button" - */ - BUTTON: "yui-carousel-button", - - /** - * The class name of the Carousel element. - * - * @property CAROUSEL - * @default "yui-carousel" - */ - CAROUSEL: "yui-carousel", - - /** - * The class name of the container of the items in the Carousel. - * - * @property CAROUSEL_EL - * @default "yui-carousel-element" - */ - CAROUSEL_EL: "yui-carousel-element", - - /** - * The class name of the Carousel's container element. - * - * @property CONTAINER - * @default "yui-carousel-container" - */ - CONTAINER: "yui-carousel-container", - - /** - * The class name of the Carousel's container element. - * - * @property CONTENT - * @default "yui-carousel-content" - */ - CONTENT: "yui-carousel-content", - - /** - * The class name of a disabled navigation button. - * - * @property DISABLED - * @default "yui-carousel-button-disabled" - */ - DISABLED: "yui-carousel-button-disabled", - - /** - * The class name of the first Carousel navigation button. - * - * @property FIRST_NAV - * @default " yui-carousel-first-button" - */ - FIRST_NAV: " yui-carousel-first-button", - - /** - * The class name of a first disabled navigation button. - * - * @property FIRST_NAV_DISABLED - * @default "yui-carousel-first-button-disabled" - */ - FIRST_NAV_DISABLED: "yui-carousel-first-button-disabled", - - /** - * The class name of a first page element. - * - * @property FIRST_PAGE - * @default "yui-carousel-nav-first-page" - */ - FIRST_PAGE: "yui-carousel-nav-first-page", - - /** - * The class name of the Carousel navigation button that has focus. - * - * @property FOCUSSED_BUTTON - * @default "yui-carousel-button-focus" - */ - FOCUSSED_BUTTON: "yui-carousel-button-focus", - - /** - * The class name of a horizontally oriented Carousel. - * - * @property HORIZONTAL - * @default "yui-carousel-horizontal" - */ - HORIZONTAL: "yui-carousel-horizontal", - - /** - * The element to be used as the progress indicator when the item - * is still being loaded. - * - * @property ITEM_LOADING - * @default The progress indicator (spinner) image CSS class - */ - ITEM_LOADING: "yui-carousel-item-loading", - - /** - * The class name that will be set if the Carousel adjusts itself - * for a minimum width. - * - * @property MIN_WIDTH - * @default "yui-carousel-min-width" - */ - MIN_WIDTH: "yui-carousel-min-width", - - /** - * The navigation element container class name. - * - * @property NAVIGATION - * @default "yui-carousel-nav" - */ - NAVIGATION: "yui-carousel-nav", - - /** - * The class name of the next Carousel navigation button. - * - * @property NEXT_NAV - * @default " yui-carousel-next-button" - */ - NEXT_NAV: " yui-carousel-next-button", - - /** - * The class name of the next navigation link. This variable is - * not only used for styling, but also for identifying the link - * within the Carousel container. - * - * @property NEXT_PAGE - * @default "yui-carousel-next" - */ - NEXT_PAGE: "yui-carousel-next", - - /** - * The class name for the navigation container for prev/next. - * - * @property NAV_CONTAINER - * @default "yui-carousel-buttons" - */ - NAV_CONTAINER: "yui-carousel-buttons", - - /** - * The class name of the focussed page navigation. This class is - * specifically used for the ugly focus handling in Opera. - * - * @property PAGE_FOCUS - * @default "yui-carousel-nav-page-focus" - */ - PAGE_FOCUS: "yui-carousel-nav-page-focus", - - /** - * The class name of the previous navigation link. This variable - * is not only used for styling, but also for identifying the link - * within the Carousel container. - * - * @property PREV_PAGE - * @default "yui-carousel-prev" - */ - PREV_PAGE: "yui-carousel-prev", - - /** - * The class name of the selected item. - * - * @property SELECTED_ITEM - * @default "yui-carousel-item-selected" - */ - SELECTED_ITEM: "yui-carousel-item-selected", - - /** - * The class name of the selected paging navigation. - * - * @property SELECTED_NAV - * @default "yui-carousel-nav-page-selected" - */ - SELECTED_NAV: "yui-carousel-nav-page-selected", - - /** - * The class name of a vertically oriented Carousel. - * - * @property VERTICAL - * @default "yui-carousel-vertical" - */ - VERTICAL: "yui-carousel-vertical", - - /** - * The class name of the (vertical) Carousel's container element. - * - * @property VERTICAL_CONTAINER - * @default "yui-carousel-vertical-container" - */ - VERTICAL_CONTAINER: "yui-carousel-vertical-container", - - /** - * The class name of a visible Carousel. - * - * @property VISIBLE - * @default "yui-carousel-visible" - */ - VISIBLE: "yui-carousel-visible" - - }, - - /* - * Configuration attributes for configuring the Carousel component - */ - - CONFIG: { - - /** - * The offset of the first visible item in the Carousel. - * - * @property FIRST_VISIBLE - * @default 0 - */ - FIRST_VISIBLE: 0, - - /** - * The minimum width of the horizontal Carousel container to support - * the navigation buttons. - * - * @property HORZ_MIN_WIDTH - * @default 180 - */ - HORZ_MIN_WIDTH: 180, - - /** - * The maximum number of pager buttons allowed beyond which the UI - * of the pager would be a drop-down of pages instead of buttons. - * - * @property MAX_PAGER_BUTTONS - * @default 5 - */ - MAX_PAGER_BUTTONS: 5, - - /** - * The minimum width of the vertical Carousel container to support - * the navigation buttons. - * - * @property VERT_MIN_WIDTH - * @default 99 - */ - VERT_MIN_WIDTH: 99, - - /** - * The number of visible items in the Carousel. - * - * @property NUM_VISIBLE - * @default 3 - */ - NUM_VISIBLE: 3 - - }, - - /* - * Internationalizable strings in the Carousel component - */ - - STRINGS: { - - /** - * The content to be used as the progress indicator when the item - * is still being loaded. - * - * @property ITEM_LOADING_CONTENT - * @default "Loading" - */ - ITEM_LOADING_CONTENT: "Loading", - - /** - * The next navigation button name/text. - * - * @property NEXT_BUTTON_TEXT - * @default "Next Page" - */ - NEXT_BUTTON_TEXT: "Next Page", - - /** - * The prefix text for the pager in case the UI is a drop-down. - * - * @property PAGER_PREFIX_TEXT - * @default "Go to page " - */ - PAGER_PREFIX_TEXT: "Go to page ", - - /** - * The previous navigation button name/text. - * - * @property PREVIOUS_BUTTON_TEXT - * @default "Previous Page" - */ - PREVIOUS_BUTTON_TEXT: "Previous Page" - - }, - - /* - * Public methods of the Carousel component - */ - - /** - * Insert or append an item to the Carousel. - * - * @method addItem - * @public - * @param item {String | Object | HTMLElement} The item to be appended - * to the Carousel. If the parameter is a string, it is assumed to be - * the content of the newly created item. If the parameter is an - * object, it is assumed to supply the content and an optional class - * and an optional id of the newly created item. - * @param index {Number} optional The position to where in the list - * (starts from zero). - * @return {Boolean} Return true on success, false otherwise - */ - addItem: function (item, index) { - var carousel = this, - className, - content, - elId, - numItems = carousel.get("numItems"); - - if (!item) { - return false; - } - - if (JS.isString(item) || item.nodeName) { - content = item.nodeName ? item.innerHTML : item; - } else if (JS.isObject(item)) { - content = item.content; - } else { - return false; - } - - className = item.className || ""; - elId = item.id ? item.id : Dom.generateId(); - - if (JS.isUndefined(index)) { - carousel._itemsTable.items.push({ - item : content, - className : className, - id : elId - }); - } else { - if (index < 0 || index >= numItems) { - return false; - } - carousel._itemsTable.items.splice(index, 0, { - item : content, - className : className, - id : elId - }); - } - carousel._itemsTable.numItems++; - - if (numItems < carousel._itemsTable.items.length) { - carousel.set("numItems", carousel._itemsTable.items.length); - } - - carousel.fireEvent(itemAddedEvent, { pos: index, ev: itemAddedEvent }); - - return true; - }, - - /** - * Insert or append multiple items to the Carousel. - * - * @method addItems - * @public - * @param items {Array} An array of items to be added with each item - * representing an item, index pair [{item, index}, ...] - * @return {Boolean} Return true on success, false otherwise - */ - addItems: function (items) { - var i, n, rv = true; - - if (!JS.isArray(items)) { - return false; - } - - for (i = 0, n = items.length; i < n; i++) { - if (this.addItem(items[i][0], items[i][1]) === false) { - rv = false; - } - } - - return rv; - }, - - /** - * Remove focus from the Carousel. - * - * @method blur - * @public - */ - blur: function () { - this._carouselEl.blur(); - this.fireEvent(blurEvent); - }, - - /** - * Clears the items from Carousel. - * - * @method clearItems - * public - */ - clearItems: function () { - var carousel = this, n = carousel.get("numItems"); - - while (n > 0) { - if (!carousel.removeItem(0)) { - } - /* - For dynamic loading, the numItems may be much larger than - the actual number of items in the table. So, set the - numItems to zero, and break out of the loop if the table - is already empty. - */ - if (carousel._itemsTable.numItems === 0) { - carousel.set("numItems", 0); - break; - } - n--; - } - - carousel.fireEvent(allItemsRemovedEvent); - }, - - /** - * Set focus on the Carousel. - * - * @method focus - * @public - */ - focus: function () { - var carousel = this, - first, - focusEl, - isSelectionInvisible, - itemsTable, - last, - numVisible, - selectOnScroll, - selected, - selItem; - - // Don't do anything if the Carousel is not rendered - if (!carousel._hasRendered) { - return; - } - - if (carousel.isAnimating()) { - // this messes up real bad! - return; - } - - selItem = carousel.get("selectedItem"); - numVisible = carousel.get("numVisible"); - selectOnScroll = carousel.get("selectOnScroll"); - selected = (selItem >= 0) ? - carousel.getItem(selItem) : null; - first = carousel.get("firstVisible"); - last = first + numVisible - 1; - isSelectionInvisible = (selItem < first || selItem > last); - focusEl = (selected && selected.id) ? - Dom.get(selected.id) : null; - itemsTable = carousel._itemsTable; - - if (!selectOnScroll && isSelectionInvisible) { - focusEl = (itemsTable && itemsTable.items && - itemsTable.items[first]) ? - Dom.get(itemsTable.items[first].id) : null; - } - - if (focusEl) { - try { - focusEl.focus(); - } catch (ex) { - // ignore focus errors - } - } - - carousel.fireEvent(focusEvent); - }, - - /** - * Hide the Carousel. - * - * @method hide - * @public - */ - hide: function () { - var carousel = this; - - if (carousel.fireEvent(beforeHideEvent) !== false) { - carousel.removeClass(carousel.CLASSES.VISIBLE); - carousel.fireEvent(hideEvent); - } - }, - - /** - * Initialize the Carousel. - * - * @method init - * @public - * @param el {HTMLElement | String} The html element that represents - * the Carousel container. - * @param attrs {Object} The set of configuration attributes for - * creating the Carousel. - */ - init: function (el, attrs) { - var carousel = this, - elId = el, // save for a rainy day - parse = false; - - if (!el) { - return; - } - - carousel._hasRendered = false; - carousel._navBtns = { prev: [], next: [] }; - carousel._pages = { el: null, num: 0, cur: 0 }; - carousel._itemsTable = { loading: {}, numItems: 0, - items: [], size: 0 }; - - - if (JS.isString(el)) { - el = Dom.get(el); - } else if (!el.nodeName) { - return; - } - - Carousel.superclass.init.call(carousel, el, attrs); - - if (el) { - if (!el.id) { // in case the HTML element is passed - el.setAttribute("id", Dom.generateId()); - } - parse = carousel._parseCarousel(el); - if (!parse) { - carousel._createCarousel(elId); - } - } else { - el = carousel._createCarousel(elId); - } - elId = el.id; - - carousel.initEvents(); - - if (parse) { - carousel._parseCarouselItems(); - } - - if (!attrs || typeof attrs.isVertical == "undefined") { - carousel.set("isVertical", false); - } - - carousel._parseCarouselNavigation(el); - carousel._navEl = carousel._setupCarouselNavigation(); - - instances[elId] = { object: carousel }; - - carousel._loadItems(); - }, - - /** - * Initialize the configuration attributes used to create the Carousel. - * - * @method initAttributes - * @public - * @param attrs {Object} The set of configuration attributes for - * creating the Carousel. - */ - initAttributes: function (attrs) { - var carousel = this; - - attrs = attrs || {}; - Carousel.superclass.initAttributes.call(carousel, attrs); - - /** - * @attribute carouselEl - * @description The type of the Carousel element. - * @default OL - * @type Boolean - */ - carousel.setAttributeConfig("carouselEl", { - validator : JS.isString, - value : attrs.carouselEl || "OL" - }); - - /** - * @attribute carouselItemEl - * @description The type of the list of items within the Carousel. - * @default LI - * @type Boolean - */ - carousel.setAttributeConfig("carouselItemEl", { - validator : JS.isString, - value : attrs.carouselItemEl || "LI" - }); - - /** - * @attribute currentPage - * @description The current page number (read-only.) - * @type Number - */ - carousel.setAttributeConfig("currentPage", { - readOnly : true, - value : 0 - }); - - /** - * @attribute firstVisible - * @description The index to start the Carousel from (indexes begin - * from zero) - * @default 0 - * @type Number - */ - carousel.setAttributeConfig("firstVisible", { - method : carousel._setFirstVisible, - validator : carousel._validateFirstVisible, - value : - attrs.firstVisible || carousel.CONFIG.FIRST_VISIBLE - }); - - /** - * @attribute selectOnScroll - * @description Set this to true to automatically set focus to - * follow scrolling in the Carousel. - * @default true - * @type Boolean - */ - carousel.setAttributeConfig("selectOnScroll", { - validator : JS.isBoolean, - value : attrs.selectOnScroll || true - }); - - /** - * @attribute numVisible - * @description The number of visible items in the Carousel's - * viewport. - * @default 3 - * @type Number - */ - carousel.setAttributeConfig("numVisible", { - method : carousel._setNumVisible, - validator : carousel._validateNumVisible, - value : attrs.numVisible || carousel.CONFIG.NUM_VISIBLE - }); - - /** - * @attribute numItems - * @description The number of items in the Carousel. - * @type Number - */ - carousel.setAttributeConfig("numItems", { - method : carousel._setNumItems, - validator : carousel._validateNumItems, - value : carousel._itemsTable.numItems - }); - - /** - * @attribute scrollIncrement - * @description The number of items to scroll by for arrow keys. - * @default 1 - * @type Number - */ - carousel.setAttributeConfig("scrollIncrement", { - validator : carousel._validateScrollIncrement, - value : attrs.scrollIncrement || 1 - }); - - /** - * @attribute selectedItem - * @description The index of the selected item. - * @type Number - */ - carousel.setAttributeConfig("selectedItem", { - method : carousel._setSelectedItem, - validator : JS.isNumber, - value : -1 - }); - - /** - * @attribute revealAmount - * @description The percentage of the item to be revealed on each - * side of the Carousel (before and after the first and last item - * in the Carousel's viewport.) - * @default 0 - * @type Number - */ - carousel.setAttributeConfig("revealAmount", { - method : carousel._setRevealAmount, - validator : carousel._validateRevealAmount, - value : attrs.revealAmount || 0 - }); - - /** - * @attribute isCircular - * @description Set this to true to wrap scrolling of the contents - * in the Carousel. - * @default false - * @type Boolean - */ - carousel.setAttributeConfig("isCircular", { - validator : JS.isBoolean, - value : attrs.isCircular || false - }); - - /** - * @attribute isVertical - * @description True if the orientation of the Carousel is vertical - * @default false - * @type Boolean - */ - carousel.setAttributeConfig("isVertical", { - method : carousel._setOrientation, - validator : JS.isBoolean, - value : attrs.isVertical || false - }); - - /** - * @attribute navigation - * @description The set of navigation controls for Carousel - * @default
- * { prev: null, // the previous navigation element
- * next: null } // the next navigation element - * @type Object - */ - carousel.setAttributeConfig("navigation", { - method : carousel._setNavigation, - validator : carousel._validateNavigation, - value : - attrs.navigation || {prev: null,next: null,page: null} - }); - - /** - * @attribute animation - * @description The optional animation attributes for the Carousel. - * @default
- * { speed: 0, // the animation speed (in seconds)
- * effect: null } // the animation effect (like - * YAHOO.util.Easing.easeOut) - * @type Object - */ - carousel.setAttributeConfig("animation", { - validator : carousel._validateAnimation, - value : attrs.animation || { speed: 0, effect: null } - }); - - /** - * @attribute autoPlay - * @description Set this to time in milli-seconds to have the - * Carousel automatically scroll the contents. - * @type Number - * @deprecated Use autoPlayInterval instead. - */ - carousel.setAttributeConfig("autoPlay", { - validator : JS.isNumber, - value : attrs.autoPlay || 0 - }); - - /** - * @attribute autoPlayInterval - * @description The delay in milli-seconds for scrolling the - * Carousel during auto-play. - * Note: The startAutoPlay() method needs to be invoked to trigger - * automatic scrolling of Carousel. - * @type Number - */ - carousel.setAttributeConfig("autoPlayInterval", { - validator : JS.isNumber, - value : attrs.autoPlayInterval || 0 - }); - }, - - /** - * Initialize and bind the event handlers. - * - * @method initEvents - * @public - */ - initEvents: function () { - var carousel = this, - cssClass = carousel.CLASSES, - focussedLi; - - carousel.on("keydown", carousel._keyboardEventHandler); - - carousel.on(afterScrollEvent, syncNavigation); - - carousel.on(itemAddedEvent, syncUi); - - carousel.on(itemRemovedEvent, syncUi); - - carousel.on(itemSelectedEvent, function () { - if (carousel._hasFocus) { - carousel.focus(); - } - }); - - carousel.on(loadItemsEvent, syncUi); - - carousel.on(allItemsRemovedEvent, function (ev) { - carousel.scrollTo(0); - syncNavigation.call(carousel); - syncPagerUi.call(carousel); - }); - - carousel.on(pageChangeEvent, syncPagerUi, carousel); - - carousel.on(renderEvent, function (ev) { - carousel.set("selectedItem", carousel.get("firstVisible")); - syncNavigation.call(carousel, ev); - syncPagerUi.call(carousel, ev); - carousel._setClipContainerSize(); - }); - - carousel.on("selectedItemChange", function (ev) { - setItemSelection.call(carousel, ev.newValue, ev.prevValue); - if (ev.newValue >= 0) { - carousel._updateTabIndex( - carousel.getElementForItem(ev.newValue)); - } - carousel.fireEvent(itemSelectedEvent, ev.newValue); - }); - - carousel.on(uiUpdateEvent, function (ev) { - syncNavigation.call(carousel, ev); - syncPagerUi.call(carousel, ev); - }); - - carousel.on("firstVisibleChange", function (ev) { - if (!carousel.get("selectOnScroll")) { - if (ev.newValue >= 0) { - carousel._updateTabIndex( - carousel.getElementForItem(ev.newValue)); - } - } - }); - - // Handle item selection on mouse click - carousel.on("click", function (ev) { - if (carousel.isAutoPlayOn()) { - carousel.stopAutoPlay(); - } - carousel._itemClickHandler(ev); - carousel._pagerClickHandler(ev); - }); - - // Restore the focus on the navigation buttons - - Event.onFocus(carousel.get("element"), function (ev, obj) { - var target = Event.getTarget(ev); - - if (target && target.nodeName.toUpperCase() == "A" && - Dom.getAncestorByClassName(target, cssClass.NAVIGATION)) { - if (focussedLi) { - Dom.removeClass(focussedLi, cssClass.PAGE_FOCUS); - } - focussedLi = target.parentNode; - Dom.addClass(focussedLi, cssClass.PAGE_FOCUS); - } else { - if (focussedLi) { - Dom.removeClass(focussedLi, cssClass.PAGE_FOCUS); - } - } - - obj._hasFocus = true; - obj._updateNavButtons(Event.getTarget(ev), true); - }, carousel); - - Event.onBlur(carousel.get("element"), function (ev, obj) { - obj._hasFocus = false; - obj._updateNavButtons(Event.getTarget(ev), false); - }, carousel); - }, - - /** - * Return true if the Carousel is still animating, or false otherwise. - * - * @method isAnimating - * @return {Boolean} Return true if animation is still in progress, or - * false otherwise. - * @public - */ - isAnimating: function () { - return this._isAnimationInProgress; - }, - - /** - * Return true if the auto-scrolling of Carousel is "on", or false - * otherwise. - * - * @method isAutoPlayOn - * @return {Boolean} Return true if autoPlay is "on", or false - * otherwise. - * @public - */ - isAutoPlayOn: function () { - return this._isAutoPlayInProgress; - }, - - /** - * Return the carouselItemEl at index or null if the index is not - * found. - * - * @method getElementForItem - * @param index {Number} The index of the item to be returned - * @return {Element} Return the item at index or null if not found - * @public - */ - getElementForItem: function (index) { - var carousel = this; - - if (index < 0 || index >= carousel.get("numItems")) { - return null; - } - - // TODO: may be cache the item - if (carousel._itemsTable.numItems > index) { - if (!JS.isUndefined(carousel._itemsTable.items[index])) { - return Dom.get(carousel._itemsTable.items[index].id); - } - } - - return null; - }, - - /** - * Return the carouselItemEl for all items in the Carousel. - * - * @method getElementForItems - * @return {Array} Return all the items - * @public - */ - getElementForItems: function () { - var carousel = this, els = [], i; - - for (i = 0; i < carousel._itemsTable.numItems; i++) { - els.push(carousel.getElementForItem(i)); - } - - return els; - }, - - /** - * Return the item at index or null if the index is not found. - * - * @method getItem - * @param index {Number} The index of the item to be returned - * @return {Object} Return the item at index or null if not found - * @public - */ - getItem: function (index) { - var carousel = this; - - if (index < 0 || index >= carousel.get("numItems")) { - return null; - } - - if (carousel._itemsTable.numItems > index) { - if (!JS.isUndefined(carousel._itemsTable.items[index])) { - return carousel._itemsTable.items[index]; - } - } - - return null; - }, - - /** - * Return all items as an array. - * - * @method getItems - * @return {Array} Return all items in the Carousel - * @public - */ - getItems: function (index) { - return this._itemsTable.items; - }, - - /** - * Return the position of the Carousel item that has the id "id", or -1 - * if the id is not found. - * - * @method getItemPositionById - * @param index {Number} The index of the item to be returned - * @public - */ - getItemPositionById: function (id) { - var carousel = this, i = 0, n = carousel._itemsTable.numItems; - - while (i < n) { - if (!JS.isUndefined(carousel._itemsTable.items[i])) { - if (carousel._itemsTable.items[i].id == id) { - return i; - } - } - i++; - } - - return -1; - }, - - /** - * Return all visible items as an array. - * - * @method getVisibleItems - * @return {Array} The array of visible items - * @public - */ - getVisibleItems: function () { - var carousel = this, - i = carousel.get("firstVisible"), - n = i + carousel.get("numVisible"), - r = []; - - while (i < n) { - r.push(carousel.getElementForItem(i)); - i++; - } - - return r; - }, - - /** - * Remove an item at index from the Carousel. - * - * @method removeItem - * @public - * @param index {Number} The position to where in the list (starts from - * zero). - * @return {Boolean} Return true on success, false otherwise - */ - removeItem: function (index) { - var carousel = this, - item, - num = carousel.get("numItems"); - - if (index < 0 || index >= num) { - return false; - } - - item = carousel._itemsTable.items.splice(index, 1); - if (item && item.length == 1) { - carousel._itemsTable.numItems--; - carousel.set("numItems", num - 1); - - carousel.fireEvent(itemRemovedEvent, - { item: item[0], pos: index, ev: itemRemovedEvent }); - return true; - } - - return false; - }, - - /** - * Render the Carousel. - * - * @method render - * @public - * @param appendTo {HTMLElement | String} The element to which the - * Carousel should be appended prior to rendering. - * @return {Boolean} Status of the operation - */ - render: function (appendTo) { - var carousel = this, - cssClass = carousel.CLASSES; - - carousel.addClass(cssClass.CAROUSEL); - - if (!carousel._clipEl) { - carousel._clipEl = carousel._createCarouselClip(); - carousel._clipEl.appendChild(carousel._carouselEl); - } - - if (appendTo) { - carousel.appendChild(carousel._clipEl); - carousel.appendTo(appendTo); - } else { - if (!Dom.inDocument(carousel.get("element"))) { - return false; - } - carousel.appendChild(carousel._clipEl); - } - - if (carousel.get("isVertical")) { - carousel.addClass(cssClass.VERTICAL); - } else { - carousel.addClass(cssClass.HORIZONTAL); - } - - if (carousel.get("numItems") < 1) { - return false; - } - - carousel._refreshUi(); - - return true; - }, - - /** - * Scroll the Carousel by an item backward. - * - * @method scrollBackward - * @public - */ - scrollBackward: function () { - var carousel = this; - - carousel.scrollTo(carousel._firstItem - - carousel.get("scrollIncrement")); - }, - - /** - * Scroll the Carousel by an item forward. - * - * @method scrollForward - * @public - */ - scrollForward: function () { - var carousel = this; - - carousel.scrollTo(carousel._firstItem + - carousel.get("scrollIncrement")); - }, - - /** - * Scroll the Carousel by a page backward. - * - * @method scrollPageBackward - * @public - */ - scrollPageBackward: function () { - var carousel = this, - item = carousel._firstItem - carousel.get("numVisible"); - - if (carousel.get("selectOnScroll")) { - carousel._selectedItem = carousel._getSelectedItem(item); - } else { - item = carousel._getValidIndex(item); - } - carousel.scrollTo(item); - }, - - /** - * Scroll the Carousel by a page forward. - * - * @method scrollPageForward - * @public - */ - scrollPageForward: function () { - var carousel = this, - item = carousel._firstItem + carousel.get("numVisible"); - - if (carousel.get("selectOnScroll")) { - carousel._selectedItem = carousel._getSelectedItem(item); - } else { - item = carousel._getValidIndex(item); - } - carousel.scrollTo(item); - }, - - /** - * Scroll the Carousel to make the item the first visible item. - * - * @method scrollTo - * @public - * @param item Number The index of the element to position at. - * @param dontSelect Boolean True if select should be avoided - */ - scrollTo: function (item, dontSelect) { - var carousel = this, - animate, animCfg, isCircular, delta, direction, firstItem, - numItems, numPerPage, offset, page, rv, sentinel, - stopAutoScroll; - - if (JS.isUndefined(item) || item == carousel._firstItem || - carousel.isAnimating()) { - return; // nothing to do! - } - - animCfg = carousel.get("animation"); - isCircular = carousel.get("isCircular"); - firstItem = carousel._firstItem; - numItems = carousel.get("numItems"); - numPerPage = carousel.get("numVisible"); - page = carousel.get("currentPage"); - stopAutoScroll = function () { - if (carousel.isAutoPlayOn()) { - carousel.stopAutoPlay(); - } - }; - - if (item < 0) { - if (isCircular) { - item = numItems + item; - } else { - stopAutoScroll.call(carousel); - return; - } - } else if (numItems > 0 && item > numItems - 1) { - if (carousel.get("isCircular")) { - item = numItems - item; - } else { - stopAutoScroll.call(carousel); - return; - } - } - - direction = (carousel._firstItem > item) ? "backward" : "forward"; - - sentinel = firstItem + numPerPage; - sentinel = (sentinel > numItems - 1) ? numItems - 1 : sentinel; - rv = carousel.fireEvent(beforeScrollEvent, - { dir: direction, first: firstItem, last: sentinel }); - if (rv === false) { // scrolling is prevented - return; - } - - carousel.fireEvent(beforePageChangeEvent, { page: page }); - - delta = firstItem - item; // yes, the delta is reverse - carousel._firstItem = item; - carousel.set("firstVisible", item); - - - carousel._loadItems(); // do we have all the items to display? - - sentinel = item + numPerPage; - sentinel = (sentinel > numItems - 1) ? numItems - 1 : sentinel; - - offset = getScrollOffset.call(carousel, delta); - - animate = animCfg.speed > 0; - - if (animate) { - carousel._animateAndSetCarouselOffset(offset, item, sentinel, - dontSelect); - } else { - carousel._setCarouselOffset(offset); - updateStateAfterScroll.call(carousel, item, sentinel); - } - }, - - /** - * Select the previous item in the Carousel. - * - * @method selectPreviousItem - * @public - */ - selectPreviousItem: function () { - var carousel = this, - newpos = 0, - selected = carousel.get("selectedItem"); - - if (selected == this._firstItem) { - newpos = selected - carousel.get("numVisible"); - carousel._selectedItem = carousel._getSelectedItem(selected-1); - carousel.scrollTo(newpos); - } else { - newpos = carousel.get("selectedItem") - - carousel.get("scrollIncrement"); - carousel.set("selectedItem",carousel._getSelectedItem(newpos)); - } - }, - - /** - * Select the next item in the Carousel. - * - * @method selectNextItem - * @public - */ - selectNextItem: function () { - var carousel = this, newpos = 0; - - newpos = carousel.get("selectedItem") + - carousel.get("scrollIncrement"); - carousel.set("selectedItem", carousel._getSelectedItem(newpos)); - }, - - /** - * Display the Carousel. - * - * @method show - * @public - */ - show: function () { - var carousel = this, - cssClass = carousel.CLASSES; - - if (carousel.fireEvent(beforeShowEvent) !== false) { - carousel.addClass(cssClass.VISIBLE); - carousel.fireEvent(showEvent); - } - }, - - /** - * Start auto-playing the Carousel. - * - * @method startAutoPlay - * @public - */ - startAutoPlay: function () { - var carousel = this, timer; - - if (JS.isUndefined(carousel._autoPlayTimer)) { - timer = carousel.get("autoPlayInterval"); - if (timer <= 0) { - return; - } - carousel._isAutoPlayInProgress = true; - carousel.fireEvent(startAutoPlayEvent); - carousel._autoPlayTimer = setTimeout(function () { - carousel._autoScroll(); - }, timer); - } - }, - - /** - * Stop auto-playing the Carousel. - * - * @method stopAutoPlay - * @public - */ - stopAutoPlay: function () { - var carousel = this; - - if (!JS.isUndefined(carousel._autoPlayTimer)) { - clearTimeout(carousel._autoPlayTimer); - delete carousel._autoPlayTimer; - carousel._isAutoPlayInProgress = false; - carousel.fireEvent(stopAutoPlayEvent); - } - }, - - /** - * Return the string representation of the Carousel. - * - * @method toString - * @public - * @return {String} - */ - toString: function () { - return WidgetName + (this.get ? " (#" + this.get("id") + ")" : ""); - }, - - /* - * Protected methods of the Carousel component - */ - - /** - * Set the Carousel offset to the passed offset after animating. - * - * @method _animateAndSetCarouselOffset - * @param {Integer} offset The offset to which the Carousel has to be - * scrolled to. - * @param {Integer} item The index to which the Carousel will scroll. - * @param {Integer} sentinel The last element in the view port. - * @protected - */ - _animateAndSetCarouselOffset: function (offset, item, sentinel) { - var carousel = this, - animCfg = carousel.get("animation"), - animObj = null; - - if (carousel.get("isVertical")) { - animObj = new YAHOO.util.Motion(carousel._carouselEl, - { points: { by: [0, offset] } }, - animCfg.speed, animCfg.effect); - } else { - animObj = new YAHOO.util.Motion(carousel._carouselEl, - { points: { by: [offset, 0] } }, - animCfg.speed, animCfg.effect); - } - - carousel._isAnimationInProgress = true; - animObj.onComplete.subscribe(carousel._animationCompleteHandler, - { scope: carousel, item: item, - last: sentinel }); - animObj.animate(); - }, - - /** - * Handle the animation complete event. - * - * @method _animationCompleteHandler - * @param {Event} ev The event. - * @param {Array} p The event parameters. - * @param {Object} o The object that has the state of the Carousel - * @protected - */ - _animationCompleteHandler: function (ev, p, o) { - o.scope._isAnimationInProgress = false; - updateStateAfterScroll.call(o.scope, o.item, o.last); - }, - - /** - * Automatically scroll the contents of the Carousel. - * @method _autoScroll - * @protected - */ - _autoScroll: function() { - var carousel = this, - currIndex = carousel._firstItem, - index; - - if (currIndex >= carousel.get("numItems") - 1) { - if (carousel.get("isCircular")) { - index = 0; - } else { - carousel.stopAutoPlay(); - } - } else { - index = currIndex + carousel.get("numVisible"); - } - - carousel._selectedItem = carousel._getSelectedItem(index); - carousel.scrollTo.call(carousel, index); - }, - - /** - * Create the Carousel. - * - * @method createCarousel - * @param elId {String} The id of the element to be created - * @protected - */ - _createCarousel: function (elId) { - var carousel = this, - cssClass = carousel.CLASSES, - el = Dom.get(elId); - - if (!el) { - el = createElement("DIV", { - className : cssClass.CAROUSEL, - id : elId - }); - } - - if (!carousel._carouselEl) { - carousel._carouselEl=createElement(carousel.get("carouselEl"), - { className: cssClass.CAROUSEL_EL }); - } - - return el; - }, - - /** - * Create the Carousel clip container. - * - * @method createCarouselClip - * @protected - */ - _createCarouselClip: function () { - return createElement("DIV", { className: this.CLASSES.CONTENT }); - }, - - /** - * Create the Carousel item. - * - * @method createCarouselItem - * @param obj {Object} The attributes of the element to be created - * @protected - */ - _createCarouselItem: function (obj) { - return createElement(this.get("carouselItemEl"), { - className : obj.className, - content : obj.content, - id : obj.id - }); - }, - - /** - * Return a valid item for a possibly out of bounds index considering - * the isCircular property. - * - * @method _getValidIndex - * @param index {Number} The index of the item to be returned - * @return {Object} Return a valid item index - * @protected - */ - _getValidIndex: function (index) { - var carousel = this, - isCircular = carousel.get("isCircular"), - numItems = carousel.get("numItems"), - sentinel = numItems - 1; - - if (index < 0) { - index = isCircular ? numItems + index : 0; - } else if (index > sentinel) { - index = isCircular ? index - numItems : sentinel; - } - - return index; - }, - - /** - * Get the value for the selected item. - * - * @method _getSelectedItem - * @param val {Number} The new value for "selected" item - * @return {Number} The new value that would be set - * @protected - */ - _getSelectedItem: function (val) { - var carousel = this, - isCircular = carousel.get("isCircular"), - numItems = carousel.get("numItems"), - sentinel = numItems - 1; - - if (val < 0) { - if (isCircular) { - val = numItems + val; - } else { - val = carousel.get("selectedItem"); - } - } else if (val > sentinel) { - if (isCircular) { - val = val - numItems; - } else { - val = carousel.get("selectedItem"); - } - } - - return val; - }, - - /** - * The "click" handler for the item. - * - * @method _itemClickHandler - * @param {Event} ev The event object - * @protected - */ - _itemClickHandler: function (ev) { - var carousel = this, - container = carousel.get("element"), - el, - item, - target = YAHOO.util.Event.getTarget(ev); - - while (target && target != container && - target.id != carousel._carouselEl) { - el = target.nodeName; - if (el.toUpperCase() == carousel.get("carouselItemEl")) { - break; - } - target = target.parentNode; - } - - if ((item = carousel.getItemPositionById(target.id)) >= 0) { - carousel.set("selectedItem", carousel._getSelectedItem(item)); - carousel.focus(); - } - }, - - /** - * The keyboard event handler for Carousel. - * - * @method _keyboardEventHandler - * @param ev {Event} The event that is being handled. - * @protected - */ - _keyboardEventHandler: function (ev) { - var carousel = this, - key = Event.getCharCode(ev), - prevent = false; - - if (carousel.isAnimating()) { - return; // do not mess while animation is in progress - } - - switch (key) { - case 0x25: // left arrow - case 0x26: // up arrow - carousel.selectPreviousItem(); - prevent = true; - break; - case 0x27: // right arrow - case 0x28: // down arrow - carousel.selectNextItem(); - prevent = true; - break; - case 0x21: // page-up - carousel.scrollPageBackward(); - prevent = true; - break; - case 0x22: // page-down - carousel.scrollPageForward(); - prevent = true; - break; - } - - if (prevent) { - if (carousel.isAutoPlayOn()) { - carousel.stopAutoPlay(); - } - Event.preventDefault(ev); - } - }, - - /** - * The load the required set of items that are needed for display. - * - * @method _loadItems - * @protected - */ - _loadItems: function() { - var carousel = this, - first = carousel.get("firstVisible"), - last = 0, - numItems = carousel.get("numItems"), - numVisible = carousel.get("numVisible"), - reveal = carousel.get("revealAmount"); - - last = first + numVisible - 1 + (reveal ? 1 : 0); - last = last > numItems - 1 ? numItems - 1 : last; - - if (!carousel.getItem(first) || !carousel.getItem(last)) { - carousel.fireEvent(loadItemsEvent, { - ev: loadItemsEvent, first: first, last: last, - num: last - first - }); - } - }, - - /** - * The "click" handler for the pager navigation. - * - * @method _pagerClickHandler - * @param {Event} ev The event object - * @protected - */ - _pagerClickHandler: function (ev) { - var carousel = this, - pos, - target = Event.getTarget(ev), - val; - - function getPagerNode(el) { - var itemEl = carousel.get("carouselItemEl"); - - if (el.nodeName.toUpperCase() == itemEl.toUpperCase()) { - el = Dom.getChildrenBy(el, function (node) { - // either an anchor or select at least - return node.href || node.value; - }); - if (el && el[0]) { - return el[0]; - } - } else if (el.href || el.value) { - return el; - } - - return null; - } - - if (target) { - target = getPagerNode(target); - if (!target) { - return; - } - val = target.href || target.value; - if (JS.isString(val) && val) { - pos = val.lastIndexOf("#"); - if (pos != -1) { - val = carousel.getItemPositionById( - val.substring(pos + 1)); - carousel._selectedItem = val; - carousel.scrollTo(val); - if (!target.value) { // not a select element - carousel.focus(); - } - Event.preventDefault(ev); - } - } - } - }, - - /** - * Find the Carousel within a container. The Carousel is identified by - * the first element that matches the carousel element tag or the - * element that has the Carousel class. - * - * @method parseCarousel - * @param parent {HTMLElement} The parent element to look under - * @return {Boolean} True if Carousel is found, false otherwise - * @protected - */ - _parseCarousel: function (parent) { - var carousel = this, child, cssClass, domEl, found, node; - - cssClass = carousel.CLASSES; - domEl = carousel.get("carouselEl"); - found = false; - - for (child = parent.firstChild; child; child = child.nextSibling) { - if (child.nodeType == 1) { - node = child.nodeName; - if (node.toUpperCase() == domEl) { - carousel._carouselEl = child; - Dom.addClass(carousel._carouselEl, - carousel.CLASSES.CAROUSEL_EL); - found = true; - } - } - } - - return found; - }, - - /** - * Find the items within the Carousel and add them to the items table. - * A Carousel item is identified by elements that matches the carousel - * item element tag. - * - * @method parseCarouselItems - * @protected - */ - _parseCarouselItems: function () { - var carousel = this, - child, - domItemEl, - elId, - node, - parent = carousel._carouselEl; - - domItemEl = carousel.get("carouselItemEl"); - - for (child = parent.firstChild; child; child = child.nextSibling) { - if (child.nodeType == 1) { - node = child.nodeName; - if (node.toUpperCase() == domItemEl) { - if (child.id) { - elId = child.id; - } else { - elId = Dom.generateId(); - child.setAttribute("id", elId); - } - carousel.addItem(child); - } - } - } - }, - - /** - * Find the Carousel navigation within a container. The navigation - * elements need to match the carousel navigation class names. - * - * @method parseCarouselNavigation - * @param parent {HTMLElement} The parent element to look under - * @return {Boolean} True if at least one is found, false otherwise - * @protected - */ - _parseCarouselNavigation: function (parent) { - var carousel = this, - cfg, - cssClass = carousel.CLASSES, - el, - i, - j, - nav, - rv = false; - - nav = Dom.getElementsByClassName(cssClass.PREV_PAGE, "*", parent); - if (nav.length > 0) { - for (i in nav) { - if (nav.hasOwnProperty(i)) { - el = nav[i]; - if (el.nodeName == "INPUT" || - el.nodeName == "BUTTON") { - carousel._navBtns.prev.push(el); - } else { - j = el.getElementsByTagName("INPUT"); - if (JS.isArray(j) && j.length > 0) { - carousel._navBtns.prev.push(j[0]); - } else { - j = el.getElementsByTagName("BUTTON"); - if (JS.isArray(j) && j.length > 0) { - carousel._navBtns.prev.push(j[0]); - } - } - } - } - } - cfg = { prev: nav }; - } - - nav = Dom.getElementsByClassName(cssClass.NEXT_PAGE, "*", parent); - if (nav.length > 0) { - for (i in nav) { - if (nav.hasOwnProperty(i)) { - el = nav[i]; - if (el.nodeName == "INPUT" || - el.nodeName == "BUTTON") { - carousel._navBtns.next.push(el); - } else { - j = el.getElementsByTagName("INPUT"); - if (JS.isArray(j) && j.length > 0) { - carousel._navBtns.next.push(j[0]); - } else { - j = el.getElementsByTagName("BUTTON"); - if (JS.isArray(j) && j.length > 0) { - carousel._navBtns.next.push(j[0]); - } - } - } - } - } - if (cfg) { - cfg.next = nav; - } else { - cfg = { next: nav }; - } - } - - if (cfg) { - carousel.set("navigation", cfg); - rv = true; - } - - return rv; - }, - - /** - * Refresh the widget UI if it is not already rendered, on first item - * addition. - * - * @method _refreshUi - * @protected - */ - _refreshUi: function () { - var carousel = this; - - // Set the rendered state appropriately. - carousel._hasRendered = true; - carousel.fireEvent(renderEvent); - }, - - /** - * Set the Carousel offset to the passed offset. - * - * @method _setCarouselOffset - * @protected - */ - _setCarouselOffset: function (offset) { - var carousel = this, which; - - which = carousel.get("isVertical") ? "top" : "left"; - offset += offset !== 0 ? getStyle(carousel._carouselEl, which) : 0; - Dom.setStyle(carousel._carouselEl, which, offset + "px"); - }, - - /** - * Setup/Create the Carousel navigation element (if needed). - * - * @method _setupCarouselNavigation - * @protected - */ - _setupCarouselNavigation: function () { - var carousel = this, - btn, cfg, cssClass, nav, navContainer, nextButton, prevButton; - - cssClass = carousel.CLASSES; - - // TODO: can the _navBtns be tested against instead? - navContainer = Dom.getElementsByClassName(cssClass.NAVIGATION, - "DIV", carousel.get("element")); - - if (navContainer.length === 0) { - navContainer = createElement("DIV", - { className: cssClass.NAVIGATION }); - carousel.insertBefore(navContainer, - Dom.getFirstChild(carousel.get("element"))); - } else { - navContainer = navContainer[0]; - } - - carousel._pages.el = createElement("UL"); - navContainer.appendChild(carousel._pages.el); - - nav = carousel.get("navigation"); - if (JS.isString(nav.prev) || JS.isArray(nav.prev)) { - if (JS.isString(nav.prev)) { - nav.prev = [nav.prev]; - } - for (btn in nav.prev) { - if (nav.prev.hasOwnProperty(btn)) { - carousel._navBtns.prev.push(Dom.get(nav.prev[btn])); - } - } - } else { - // TODO: separate method for creating a navigation button - prevButton = createElement("SPAN", - { className: cssClass.BUTTON + cssClass.FIRST_NAV }); - // XXX: for IE 6.x - Dom.setStyle(prevButton, "visibility", "visible"); - btn = Dom.generateId(); - prevButton.innerHTML = ""; - navContainer.appendChild(prevButton); - btn = Dom.get(btn); - carousel._navBtns.prev = [btn]; - cfg = { prev: [prevButton] }; - } - - if (JS.isString(nav.next) || JS.isArray(nav.next)) { - if (JS.isString(nav.next)) { - nav.next = [nav.next]; - } - for (btn in nav.next) { - if (nav.next.hasOwnProperty(btn)) { - carousel._navBtns.next.push(Dom.get(nav.next[btn])); - } - } - } else { - // TODO: separate method for creating a navigation button - nextButton = createElement("SPAN", - { className: cssClass.BUTTON + cssClass.NEXT_NAV }); - // XXX: for IE 6.x - Dom.setStyle(nextButton, "visibility", "visible"); - btn = Dom.generateId(); - nextButton.innerHTML = ""; - navContainer.appendChild(nextButton); - btn = Dom.get(btn); - carousel._navBtns.next = [btn]; - if (cfg) { - cfg.next = [nextButton]; - } else { - cfg = { next: [nextButton] }; - } - } - - if (cfg) { - carousel.set("navigation", cfg); - } - - return navContainer; - }, - - /** - * Set the clip container size (based on the new numVisible value). - * - * @method _setClipContainerSize - * @param clip {HTMLElement} The clip container element. - * @param num {Number} optional The number of items per page. - * @protected - */ - _setClipContainerSize: function (clip, num) { - var carousel = this, - attr, currVal, isVertical, itemSize, reveal, size, which; - - isVertical = carousel.get("isVertical"); - reveal = carousel.get("revealAmount"); - which = isVertical ? "height" : "width"; - attr = isVertical ? "top" : "left"; - - clip = clip || carousel._clipEl; - if (!clip) { - return; - } - - num = num || carousel.get("numVisible"); - itemSize = getCarouselItemSize.call(carousel, which); - size = itemSize * num; - - // TODO: try to re-use the _hasRendered indicator - carousel._recomputeSize = (size === 0); // bleh! - if (carousel._recomputeSize) { - carousel._hasRendered = false; - return; // no use going further, bail out! - } - - if (reveal > 0) { - reveal = itemSize * (reveal / 100) * 2; - size += reveal; - // TODO: set the Carousel's initial offset somwehere - currVal = parseFloat(Dom.getStyle(carousel._carouselEl, attr)); - currVal = JS.isNumber(currVal) ? currVal : 0; - Dom.setStyle(carousel._carouselEl, - attr, currVal + (reveal / 2) + "px"); - } - - if (isVertical) { - size += getStyle(carousel._carouselEl, "marginTop") + - getStyle(carousel._carouselEl, "marginBottom") + - getStyle(carousel._carouselEl, "paddingTop") + - getStyle(carousel._carouselEl, "paddingBottom") + - getStyle(carousel._carouselEl, "borderTopWidth") + - getStyle(carousel._carouselEl, "borderBottomWidth"); - // XXX: for vertical Carousel - Dom.setStyle(clip, which, (size - (num - 1)) + "px"); - } else { - size += getStyle(carousel._carouselEl, "marginLeft") + - getStyle(carousel._carouselEl, "marginRight") + - getStyle(carousel._carouselEl, "paddingLeft") + - getStyle(carousel._carouselEl, "paddingRight") + - getStyle(carousel._carouselEl, "borderLeftWidth") + - getStyle(carousel._carouselEl, "borderRightWidth"); - Dom.setStyle(clip, which, size + "px"); - } - - carousel._setContainerSize(clip); // adjust the container size too - }, - - /** - * Set the container size. - * - * @method _setContainerSize - * @param clip {HTMLElement} The clip container element. - * @param attr {String} Either set the height or width. - * @protected - */ - _setContainerSize: function (clip, attr) { - var carousel = this, - config = carousel.CONFIG, - cssClass = carousel.CLASSES, - isVertical, - size; - - isVertical = carousel.get("isVertical"); - clip = clip || carousel._clipEl; - attr = attr || (isVertical ? "height" : "width"); - size = parseFloat(Dom.getStyle(clip, attr), 10); - - size = JS.isNumber(size) ? size : 0; - - if (isVertical) { - size += getStyle(carousel._carouselEl, "marginTop") + - getStyle(carousel._carouselEl, "marginBottom") + - getStyle(carousel._carouselEl, "paddingTop") + - getStyle(carousel._carouselEl, "paddingBottom") + - getStyle(carousel._carouselEl, "borderTopWidth") + - getStyle(carousel._carouselEl, "borderBottomWidth") + - getStyle(carousel._navEl, "height"); - } else { - size += getStyle(clip, "marginLeft") + - getStyle(clip, "marginRight") + - getStyle(clip, "paddingLeft") + - getStyle(clip, "paddingRight") + - getStyle(clip, "borderLeftWidth") + - getStyle(clip, "borderRightWidth"); - } - - if (!isVertical) { - if (size < config.HORZ_MIN_WIDTH) { - size = config.HORZ_MIN_WIDTH; - carousel.addClass(cssClass.MIN_WIDTH); - } - } - carousel.setStyle(attr, size + "px"); - - // Additionally the width of the container should be set for - // the vertical Carousel - if (isVertical) { - size = getCarouselItemSize.call(carousel, "width"); - if (size < config.VERT_MIN_WIDTH) { - size = config.VERT_MIN_WIDTH; - carousel.addClass(cssClass.MIN_WIDTH); - } - carousel.setStyle("width", size + "px"); - } - }, - - /** - * Set the value for the Carousel's first visible item. - * - * @method _setFirstVisible - * @param val {Number} The new value for firstVisible - * @return {Number} The new value that would be set - * @protected - */ - _setFirstVisible: function (val) { - var carousel = this; - - if (val >= 0 && val < carousel.get("numItems")) { - carousel.scrollTo(val); - } else { - val = carousel.get("firstVisible"); - } - return val; - }, - - /** - * Set the value for the Carousel's navigation. - * - * @method _setNavigation - * @param cfg {Object} The navigation configuration - * @return {Object} The new value that would be set - * @protected - */ - _setNavigation: function (cfg) { - var carousel = this; - - if (cfg.prev) { - Event.on(cfg.prev, "click", scrollPageBackward, carousel); - } - if (cfg.next) { - Event.on(cfg.next, "click", scrollPageForward, carousel); - } - }, - - /** - * Set the value for the number of visible items in the Carousel. - * - * @method _setNumVisible - * @param val {Number} The new value for numVisible - * @return {Number} The new value that would be set - * @protected - */ - _setNumVisible: function (val) { - var carousel = this; - - carousel._setClipContainerSize(carousel._clipEl, val); - }, - - /** - * Set the number of items in the Carousel. - * Warning: Setting this to a lower number than the current removes - * items from the end. - * - * @method _setNumItems - * @param val {Number} The new value for numItems - * @return {Number} The new value that would be set - * @protected - */ - _setNumItems: function (val) { - var carousel = this, - num = carousel._itemsTable.numItems; - - if (JS.isArray(carousel._itemsTable.items)) { - if (carousel._itemsTable.items.length != num) { // out of sync - num = carousel._itemsTable.items.length; - carousel._itemsTable.numItems = num; - } - } - - if (val < num) { - while (num > val) { - carousel.removeItem(num - 1); - num--; - } - } - - return val; - }, - - /** - * Set the orientation of the Carousel. - * - * @method _setOrientation - * @param val {Boolean} The new value for isVertical - * @return {Boolean} The new value that would be set - * @protected - */ - _setOrientation: function (val) { - var carousel = this, - cssClass = carousel.CLASSES; - - if (val) { - carousel.replaceClass(cssClass.HORIZONTAL, cssClass.VERTICAL); - } else { - carousel.replaceClass(cssClass.VERTICAL, cssClass.HORIZONTAL); - } - carousel._itemsTable.size = 0; // force recalculation next time - return val; - }, - - /** - * Set the value for the reveal amount percentage in the Carousel. - * - * @method _setRevealAmount - * @param val {Number} The new value for revealAmount - * @return {Number} The new value that would be set - * @protected - */ - _setRevealAmount: function (val) { - var carousel = this; - - if (val >= 0 && val <= 100) { - val = parseInt(val, 10); - val = JS.isNumber(val) ? val : 0; - carousel._setClipContainerSize(); - } else { - val = carousel.get("revealAmount"); - } - return val; - }, - - /** - * Set the value for the selected item. - * - * @method _setSelectedItem - * @param val {Number} The new value for "selected" item - * @protected - */ - _setSelectedItem: function (val) { - this._selectedItem = val; - }, - - /** - * Synchronize and redraw the UI after an item is added. - * - * @method _syncUiForItemAdd - * @protected - */ - _syncUiForItemAdd: function (obj) { - var carousel = this, - carouselEl = carousel._carouselEl, - el, - item, - itemsTable = carousel._itemsTable, - oel, - pos, - sibling; - - pos = JS.isUndefined(obj.pos) ? itemsTable.numItems - 1 : obj.pos; - if (!JS.isUndefined(itemsTable.items[pos])) { - item = itemsTable.items[pos]; - if (item && !JS.isUndefined(item.id)) { - oel = Dom.get(item.id); - } - } - if (!oel) { - el = carousel._createCarouselItem({ - className : item.className, - content : item.item, - id : item.id - }); - if (JS.isUndefined(obj.pos)) { - if (!JS.isUndefined(itemsTable.loading[pos])) { - oel = itemsTable.loading[pos]; - // if oel is null, it is a problem ... - } - if (oel) { - // replace the node - carouselEl.replaceChild(el, oel); - // ... and remove the item from the data structure - delete itemsTable.loading[pos]; - } else { - carouselEl.appendChild(el); - } - } else { - if (!JS.isUndefined(itemsTable.items[obj.pos + 1])) { - sibling = Dom.get(itemsTable.items[obj.pos + 1].id); - } - if (sibling) { - carouselEl.insertBefore(el, sibling); - } else { - } - } - } else { - if (JS.isUndefined(obj.pos)) { - if (!Dom.isAncestor(carousel._carouselEl, oel)) { - carouselEl.appendChild(oel); - } - } else { - if (!Dom.isAncestor(carouselEl, oel)) { - if (!JS.isUndefined(itemsTable.items[obj.pos + 1])) { - carouselEl.insertBefore(oel, - Dom.get(itemsTable.items[obj.pos + 1].id)); - } - } - } - } - - if (!carousel._hasRendered) { - carousel._refreshUi(); - } - - if (carousel.get("selectedItem") < 0) { - carousel.set("selectedItem", carousel.get("firstVisible")); - } - }, - - /** - * Synchronize and redraw the UI after an item is removed. - * - * @method _syncUiForItemAdd - * @protected - */ - _syncUiForItemRemove: function (obj) { - var carousel = this, - carouselEl = carousel._carouselEl, - el, item, num, pos; - - num = carousel.get("numItems"); - item = obj.item; - pos = obj.pos; - - if (item && (el = Dom.get(item.id))) { - if (el && Dom.isAncestor(carouselEl, el)) { - Event.purgeElement(el, true); - carouselEl.removeChild(el); - } - - if (carousel.get("selectedItem") == pos) { - pos = pos >= num ? num - 1 : pos; - carousel.set("selectedItem", pos); - } - } else { - } - }, - - /** - * Synchronize and redraw the UI for lazy loading. - * - * @method _syncUiForLazyLoading - * @protected - */ - _syncUiForLazyLoading: function (obj) { - var carousel = this, - carouselEl = carousel._carouselEl, - el, - i, - itemsTable = carousel._itemsTable, - sibling; - - for (i = obj.first; i <= obj.last; i++) { - el = carousel._createCarouselItem({ - className : carousel.CLASSES.ITEM_LOADING, - content : carousel.STRINGS.ITEM_LOADING_CONTENT, - id : Dom.generateId() - }); - if (el) { - if (!JS.isUndefined(itemsTable.items[obj.last + 1])) { - sibling = Dom.get(itemsTable.items[obj.last + 1].id); - if (sibling) { - carouselEl.insertBefore(el, sibling); - } else { - } - } else { - carouselEl.appendChild(el); - } - } - itemsTable.loading[i] = el; - } - }, - - /** - * Set the correct class for the navigation buttons. - * - * @method _updateNavButtons - * @param el {Object} The target button - * @param setFocus {Boolean} True to set focus ring, false otherwise. - * @protected - */ - _updateNavButtons: function (el, setFocus) { - var children, - cssClass = this.CLASSES, - grandParent, - parent = el.parentNode; - - if (!parent) { - return; - } - grandParent = parent.parentNode; - - if (el.nodeName.toUpperCase() == "BUTTON" && - Dom.hasClass(parent, cssClass.BUTTON)) { - if (setFocus) { - if (grandParent) { - children = Dom.getChildren(grandParent); - if (children) { - Dom.removeClass(children, cssClass.FOCUSSED_BUTTON); - } - } - Dom.addClass(parent, cssClass.FOCUSSED_BUTTON); - } else { - Dom.removeClass(parent, cssClass.FOCUSSED_BUTTON); - } - } - }, - - /** - * Update the UI for the pager buttons based on the current page and - * the number of pages. - * - * @method _updatePagerButtons - * @protected - */ - _updatePagerButtons: function () { - var carousel = this, - css = carousel.CLASSES, - cur = carousel._pages.cur, // current page - el, - html, - i, - item, - n = carousel.get("numVisible"), - num = carousel._pages.num, // total pages - pager = carousel._pages.el; // the pager container element - - if (num === 0 || !pager) { - return; // don't do anything if number of pages is 0 - } - - // Hide the pager before redrawing it - Dom.setStyle(pager, "visibility", "hidden"); - - // Remove all nodes from the pager - while (pager.firstChild) { - pager.removeChild(pager.firstChild); - } - - for (i = 0; i < num; i++) { - if (JS.isUndefined(carousel._itemsTable.items[i * n])) { - Dom.setStyle(pager, "visibility", "visible"); - break; - } - item = carousel._itemsTable.items[i * n].id; - - el = document.createElement("LI"); - if (!el) { - Dom.setStyle(pager, "visibility", "visible"); - break; - } - - if (i === 0) { - Dom.addClass(el, css.FIRST_PAGE); - } - if (i == cur) { - Dom.addClass(el, css.SELECTED_NAV); - } - - // TODO: use a template string for i18N compliance - html = "" + - carousel.STRINGS.PAGER_PREFIX_TEXT + " " + (i+1) + - ""; - el.innerHTML = html; - - pager.appendChild(el); - } - - // Show the pager now - Dom.setStyle(pager, "visibility", "visible"); - }, - - /** - * Update the UI for the pager menu based on the current page and - * the number of pages. If the number of pages is greater than - * MAX_PAGER_BUTTONS, then the selection of pages is provided by a drop - * down menu instead of a set of buttons. - * - * @method _updatePagerMenu - * @protected - */ - _updatePagerMenu: function () { - var carousel = this, - cur = carousel._pages.cur, // current page - el, - i, - item, - n = carousel.get("numVisible"), - num = carousel._pages.num, // total pages - pager = carousel._pages.el, // the pager container element - sel; - - if (num === 0) { - return; // don't do anything if number of pages is 0 - } - - sel = document.createElement("SELECT"); - if (!sel) { - return; - } - - // Hide the pager before redrawing it - Dom.setStyle(pager, "visibility", "hidden"); - - // Remove all nodes from the pager - while (pager.firstChild) { - pager.removeChild(pager.firstChild); - } - - for (i = 0; i < num; i++) { - if (JS.isUndefined(carousel._itemsTable.items[i * n])) { - Dom.setStyle(pager, "visibility", "visible"); - break; - } - item = carousel._itemsTable.items[i * n].id; - - el = document.createElement("OPTION"); - if (!el) { - Dom.setStyle(pager, "visibility", "visible"); - break; - } - el.value = "#" + item; - // TODO: use a template string for i18N compliance - el.innerHTML = carousel.STRINGS.PAGER_PREFIX_TEXT+" "+(i+1); - - if (i == cur) { - el.setAttribute("selected", "selected"); - } - - sel.appendChild(el); - } - - el = document.createElement("FORM"); - if (!el) { - } else { - el.appendChild(sel); - pager.appendChild(el); - } - - // Show the pager now - Dom.setStyle(pager, "visibility", "visible"); - }, - - /** - * Set the correct tab index for the Carousel items. - * - * @method _updateTabIndex - * @param el {Object} The element to be focussed - * @protected - */ - _updateTabIndex: function (el) { - var carousel = this; - - if (el) { - if (carousel._focusableItemEl) { - carousel._focusableItemEl.tabIndex = -1; - } - carousel._focusableItemEl = el; - el.tabIndex = 0; - } - }, - - /** - * Validate animation parameters. - * - * @method _validateAnimation - * @param cfg {Object} The animation configuration - * @return {Boolean} The status of the validation - * @protected - */ - _validateAnimation: function (cfg) { - var rv = true; - - if (JS.isObject(cfg)) { - if (cfg.speed) { - rv = rv && JS.isNumber(cfg.speed); - } - if (cfg.effect) { - rv = rv && JS.isFunction(cfg.effect); - } else if (!JS.isUndefined(YAHOO.util.Easing)) { - cfg.effect = YAHOO.util.Easing.easeOut; - } - } else { - rv = false; - } - - return rv; - }, - - /** - * Validate the firstVisible value. - * - * @method _validateFirstVisible - * @param val {Number} The first visible value - * @return {Boolean} The status of the validation - * @protected - */ - _validateFirstVisible: function (val) { - var carousel = this, numItems = carousel.get("numItems"); - - if (JS.isNumber(val)) { - if (numItems === 0 && val == numItems) { - return true; - } else { - return (val >= 0 && val < numItems); - } - } - - return false; - }, - - /** - * Validate and navigation parameters. - * - * @method _validateNavigation - * @param cfg {Object} The navigation configuration - * @return {Boolean} The status of the validation - * @protected - */ - _validateNavigation : function (cfg) { - var i; - - if (!JS.isObject(cfg)) { - return false; - } - - if (cfg.prev) { - if (!JS.isArray(cfg.prev)) { - return false; - } - for (i in cfg.prev) { - if (cfg.prev.hasOwnProperty(i)) { - if (!JS.isString(cfg.prev[i].nodeName)) { - return false; - } - } - } - } - - if (cfg.next) { - if (!JS.isArray(cfg.next)) { - return false; - } - for (i in cfg.next) { - if (cfg.next.hasOwnProperty(i)) { - if (!JS.isString(cfg.next[i].nodeName)) { - return false; - } - } - } - } - - return true; - }, - - /** - * Validate the numItems value. - * - * @method _validateNumItems - * @param val {Number} The numItems value - * @return {Boolean} The status of the validation - * @protected - */ - _validateNumItems: function (val) { - return JS.isNumber(val) && (val >= 0); - }, - - /** - * Validate the numVisible value. - * - * @method _validateNumVisible - * @param val {Number} The numVisible value - * @return {Boolean} The status of the validation - * @protected - */ - _validateNumVisible: function (val) { - var rv = false; - - if (JS.isNumber(val)) { - rv = val > 0 && val <= this.get("numItems"); - } - - return rv; - }, - - /** - * Validate the revealAmount value. - * - * @method _validateRevealAmount - * @param val {Number} The revealAmount value - * @return {Boolean} The status of the validation - * @protected - */ - _validateRevealAmount: function (val) { - var rv = false; - - if (JS.isNumber(val)) { - rv = val >= 0 && val < 100; - } - - return rv; - }, - - /** - * Validate the scrollIncrement value. - * - * @method _validateScrollIncrement - * @param val {Number} The scrollIncrement value - * @return {Boolean} The status of the validation - * @protected - */ - _validateScrollIncrement: function (val) { - var rv = false; - - if (JS.isNumber(val)) { - rv = (val > 0 && val < this.get("numItems")); - } - - return rv; - } - - }); - -})(); -/* -;; Local variables: ** -;; mode: js2 ** -;; indent-tabs-mode: nil ** -;; End: ** -*/ -YAHOO.register("carousel", YAHOO.widget.Carousel, {version: "2.7.0", build: "1799"});