UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,222 lines (982 loc) • 38.6 kB
"use strict"; var $ = require("../core/renderer"), eventsEngine = require("../events/core/events_engine"), registerComponent = require("../core/component_registrator"), commonUtils = require("../core/utils/common"), typeUtils = require("../core/utils/type"), windowUtils = require("../core/utils/window"), extend = require("../core/utils/extend").extend, getPublicElement = require("../core/utils/dom").getPublicElement, fx = require("../animation/fx"), clickEvent = require("../events/click"), translator = require("../animation/translator"), devices = require("../core/devices"), Widget = require("./widget/ui.widget"), eventUtils = require("../events/utils"), CollectionWidget = require("./collection/ui.collection_widget.edit"), Swipeable = require("../events/gesture/swipeable"), BindableTemplate = require("./widget/bindable_template"), Deferred = require("../core/utils/deferred").Deferred; var GALLERY_CLASS = "dx-gallery", GALLERY_WRAPPER_CLASS = GALLERY_CLASS + "-wrapper", GALLERY_LOOP_CLASS = "dx-gallery-loop", GALLERY_ITEM_CONTAINER_CLASS = GALLERY_CLASS + "-container", GALLERY_ACTIVE_CLASS = GALLERY_CLASS + "-active", GALLERY_ITEM_CLASS = GALLERY_CLASS + "-item", GALLERY_INVISIBLE_ITEM_CLASS = GALLERY_CLASS + "-item-invisible", GALLERY_LOOP_ITEM_CLASS = GALLERY_ITEM_CLASS + "-loop", GALLERY_ITEM_SELECTOR = "." + GALLERY_ITEM_CLASS, GALLERY_ITEM_SELECTED_CLASS = GALLERY_ITEM_CLASS + "-selected", GALLERY_INDICATOR_CLASS = GALLERY_CLASS + "-indicator", GALLERY_INDICATOR_ITEM_CLASS = GALLERY_INDICATOR_CLASS + "-item", GALLERY_INDICATOR_ITEM_SELECTOR = "." + GALLERY_INDICATOR_ITEM_CLASS, GALLERY_INDICATOR_ITEM_SELECTED_CLASS = GALLERY_INDICATOR_ITEM_CLASS + "-selected", GALLERY_IMAGE_CLASS = "dx-gallery-item-image", GALLERY_ITEM_DATA_KEY = "dxGalleryItemData", MAX_CALC_ERROR = 1; var GalleryNavButton = Widget.inherit({ _supportedKeys: function _supportedKeys() { return extend(this.callBase(), { pageUp: commonUtils.noop, pageDown: commonUtils.noop }); }, _getDefaultOptions: function _getDefaultOptions() { return extend(this.callBase(), { direction: "next", onClick: null, hoverStateEnabled: true, activeStateEnabled: true }); }, _render: function _render() { this.callBase(); var that = this, $element = this.$element(), eventName = eventUtils.addNamespace(clickEvent.name, this.NAME); $element.addClass(GALLERY_CLASS + "-nav-button-" + this.option("direction")); eventsEngine.off($element, eventName); eventsEngine.on($element, eventName, function (e) { that._createActionByOption("onClick")({ event: e }); }); }, _optionChanged: function _optionChanged(args) { switch (args.name) { case "onClick": case "direction": this._invalidate(); break; default: this.callBase(args); } } }); /** * @name dxgallery * @publicName dxGallery * @inherits CollectionWidget * @module ui/gallery * @export default */ var Gallery = CollectionWidget.inherit({ _activeStateUnit: GALLERY_ITEM_SELECTOR, _getDefaultOptions: function _getDefaultOptions() { return extend(this.callBase(), { /** * @name dxGalleryOptions.activeStateEnabled * @publicName activeStateEnabled * @type boolean * @default false */ activeStateEnabled: false, /** * @name dxGalleryOptions.animationDuration * @publicName animationDuration * @type number * @default 400 */ animationDuration: 400, /** * @name dxGalleryOptions.animationEnabled * @publicName animationEnabled * @type boolean * @default true */ animationEnabled: true, /** * @name dxGalleryOptions.loop * @publicName loop * @type boolean * @default false */ loop: false, /** * @name dxGalleryOptions.swipeEnabled * @publicName swipeEnabled * @type boolean * @default true */ swipeEnabled: true, /** * @name dxGalleryOptions.indicatorEnabled * @publicName indicatorEnabled * @type boolean * @default true */ indicatorEnabled: true, /** * @name dxGalleryOptions.showIndicator * @publicName showIndicator * @type boolean * @default true */ showIndicator: true, /** * @name dxGalleryOptions.selectedindex * @publicName selectedIndex * @type number * @default 0 */ selectedIndex: 0, /** * @name dxGalleryOptions.slideshowdelay * @publicName slideshowDelay * @type number * @default 0 */ slideshowDelay: 0, /** * @name dxGalleryOptions.showNavButtons * @publicName showNavButtons * @type boolean * @default false */ showNavButtons: false, /** * @name dxGalleryOptions.wrapAround * @publicName wrapAround * @type boolean * @default false */ wrapAround: false, /** * @name dxGalleryOptions.initialItemWidth * @publicName initialItemWidth * @type number * @default undefined */ initialItemWidth: undefined, /** * @name dxGalleryOptions.stretchImages * @publicName stretchImages * @type boolean * @default false */ stretchImages: false, /** * @name dxGalleryOptions.activeStateEnabled * @publicName activeStateEnabled * @hidden */ /** * @name dxGalleryOptions.noDataText * @publicName noDataText * @hidden * @inheritdoc */ /** * @name dxGalleryOptions.selectedItems * @publicName selectedItems * @hidden * @inheritdoc */ /** * @name dxGalleryOptions.selectedItemKeys * @publicName selectedItemKeys * @hidden * @inheritdoc */ /** * @name dxGalleryOptions.keyExpr * @publicName keyExpr * @hidden * @inheritdoc */ _itemAttributes: { role: "option" }, loopItemFocus: false, selectOnFocus: true, selectionMode: "single", selectionRequired: true, selectionByClick: false }); }, _defaultOptionsRules: function _defaultOptionsRules() { return this.callBase().concat([{ device: function device() { return devices.real().deviceType === "desktop" && !devices.isSimulator(); }, options: { /** * @name dxGalleryOptions.focusStateEnabled * @publicName focusStateEnabled * @type boolean * @default true @for desktop * @inheritdoc */ focusStateEnabled: true } }]); }, _init: function _init() { this.callBase(); this.option("loopItemFocus", this.option("loop")); }, _initTemplates: function _initTemplates() { this.callBase(); /** * @name dxGalleryItemTemplate * @publicName dxGalleryItemTemplate * @inherits CollectionWidgetItemTemplate * @type object */ /** * @name dxGalleryItemTemplate.imageSrc * @publicName imageSrc * @type String */ /** * @name dxGalleryItemTemplate.imageAlt * @publicName imageAlt * @type String */ /** * @name dxGalleryItemTemplate.visible * @publicName visible * @hidden * @inheritdoc */ this._defaultTemplates["item"] = new BindableTemplate(function ($container, data) { var $img = $('<img>').addClass(GALLERY_IMAGE_CLASS); if (typeUtils.isPlainObject(data)) { this._prepareDefaultItemTemplate(data, $container); $img.attr({ 'src': data.imageSrc, 'alt': data.imageAlt }).appendTo($container); } else { $img.attr('src', String(data)).appendTo($container); } }.bind(this), ["imageSrc", "imageAlt", "text", "html"], this.option("integrationOptions.watchMethod")); }, _dataSourceOptions: function _dataSourceOptions() { return { paginate: false }; }, _itemContainer: function _itemContainer() { return this._$container; }, _itemClass: function _itemClass() { return GALLERY_ITEM_CLASS; }, _itemDataKey: function _itemDataKey() { return GALLERY_ITEM_DATA_KEY; }, _actualItemWidth: function _actualItemWidth() { var itemPerPage = this.option("wrapAround") ? this._itemsPerPage() + 1 : this._itemsPerPage(); if (this.option("stretchImages")) { return 1 / itemPerPage; } if (this.option("wrapAround")) { return this._itemPercentWidth() * this._itemsPerPage() / (this._itemsPerPage() + 1); } return this._itemPercentWidth(); }, _itemPercentWidth: function _itemPercentWidth() { var percentWidth, elementWidth = this.$element().outerWidth(), initialItemWidth = this.option("initialItemWidth"); if (initialItemWidth && initialItemWidth <= elementWidth) { percentWidth = this.option("initialItemWidth") / elementWidth; } else { percentWidth = 1; } return percentWidth; }, _itemsPerPage: function _itemsPerPage() { var itemsPerPage = windowUtils.hasWindow() ? Math.floor(1 / this._itemPercentWidth()) : 1; return Math.min(itemsPerPage, this._itemsCount()); }, _pagesCount: function _pagesCount() { return Math.ceil(this._itemsCount() / this._itemsPerPage()); }, _itemsCount: function _itemsCount() { return (this.option("items") || []).length; }, _offsetDirection: function _offsetDirection() { return this.option("rtlEnabled") ? -1 : 1; }, _initMarkup: function _initMarkup() { this._renderWrapper(); this._renderItemsContainer(); this.$element().addClass(GALLERY_CLASS); this.$element().toggleClass(GALLERY_LOOP_CLASS, this.option("loop")); this.callBase(); this.setAria({ "role": "listbox", "label": "gallery" }); }, _render: function _render() { this._renderDragHandler(); this._renderContainerPosition(); this._renderItemSizes(); this._renderItemPositions(); this._renderNavButtons(); this._renderIndicator(); this._renderSelectedItem(); this._renderItemVisibility(); this._renderUserInteraction(); this._setupSlideShow(); this._reviseDimensions(); this.callBase(); }, _dimensionChanged: function _dimensionChanged() { var selectedIndex = this.option("selectedIndex") || 0; this._stopItemAnimations(); this._clearCacheWidth(); this._renderDuplicateItems(); this._renderItemSizes(); this._renderItemPositions(); this._renderIndicator(); this._renderContainerPosition(this._calculateIndexOffset(selectedIndex), true); this._renderItemVisibility(); }, _renderDragHandler: function _renderDragHandler() { var eventName = eventUtils.addNamespace("dragstart", this.NAME); eventsEngine.off(this.$element(), eventName); eventsEngine.on(this.$element(), eventName, "img", function () { return false; }); }, _renderWrapper: function _renderWrapper() { if (this._$wrapper) { return; } this._$wrapper = $("<div>").addClass(GALLERY_WRAPPER_CLASS).appendTo(this.$element()); }, _renderItems: function _renderItems(items) { if (!windowUtils.hasWindow()) { var selectedIndex = this.option("selectedIndex"); items = items.length > selectedIndex ? items.slice(selectedIndex, selectedIndex + 1) : items.slice(0, 1); } this.callBase(items); this._loadNextPageIfNeeded(); }, _renderItemsContainer: function _renderItemsContainer() { if (this._$container) { return; } this._$container = $("<div>").addClass(GALLERY_ITEM_CONTAINER_CLASS).appendTo(this._$wrapper); }, _renderDuplicateItems: function _renderDuplicateItems() { if (!this.option("loop")) { return; } var items = this.option("items") || [], itemsCount = items.length, lastItemIndex = itemsCount - 1, i; if (!itemsCount) return; this._getLoopedItems().remove(); var duplicateCount = Math.min(this._itemsPerPage(), itemsCount); for (i = 0; i < duplicateCount; i++) { this._renderItem(0, items[i]).addClass(GALLERY_LOOP_ITEM_CLASS); } for (i = 0; i < duplicateCount; i++) { this._renderItem(0, items[lastItemIndex - i]).addClass(GALLERY_LOOP_ITEM_CLASS); } }, _getLoopedItems: function _getLoopedItems() { return this.$element().find("." + GALLERY_LOOP_ITEM_CLASS); }, _emptyMessageContainer: function _emptyMessageContainer() { return this._$wrapper; }, _renderItemSizes: function _renderItemSizes(startIndex) { var $items = this._itemElements(), itemWidth = this._actualItemWidth(); if (startIndex !== undefined) { $items = $items.slice(startIndex); } $items.each(function (index) { $($items[index]).outerWidth(itemWidth * 100 + "%"); }); }, _renderItemPositions: function _renderItemPositions() { var itemWidth = this._actualItemWidth(), itemsCount = this._itemsCount(), itemsPerPage = this._itemsPerPage(), loopItemsCount = this.$element().find("." + GALLERY_LOOP_ITEM_CLASS).length, lastItemDuplicateIndex = itemsCount + loopItemsCount - 1, offsetRatio = this.option("wrapAround") ? 0.5 : 0, freeSpace = this._itemFreeSpace(), rtlEnabled = this.option("rtlEnabled"); this._itemElements().each(function (index) { var realIndex = index; if (index > itemsCount + itemsPerPage - 1) { realIndex = lastItemDuplicateIndex - realIndex - itemsPerPage; } var itemPosition = itemWidth * (realIndex + offsetRatio) + freeSpace * (realIndex + 1 - offsetRatio); $(this).css(rtlEnabled ? "right" : "left", itemPosition * 100 + "%"); }); this._relocateItems(this.option("selectedIndex"), this.option("selectedIndex"), true); }, _itemFreeSpace: function _itemFreeSpace() { var itemsPerPage = this._itemsPerPage(); if (this.option("wrapAround")) { itemsPerPage = itemsPerPage + 1; } return (1 - this._actualItemWidth() * itemsPerPage) / (itemsPerPage + 1); }, _renderContainerPosition: function _renderContainerPosition(offset, hideItems, animate) { this._releaseInvisibleItems(); offset = offset || 0; var that = this, itemWidth = this._actualItemWidth(), targetIndex = offset, targetPosition = this._offsetDirection() * targetIndex * (itemWidth + this._itemFreeSpace()), positionReady; if (typeUtils.isDefined(this._animationOverride)) { animate = this._animationOverride; delete this._animationOverride; } if (animate) { that._startSwipe(); positionReady = that._animate(targetPosition).done(that._endSwipe.bind(that)); } else { translator.move(this._$container, { left: targetPosition * this._elementWidth(), top: 0 }); positionReady = new Deferred().resolveWith(that); } positionReady.done(function () { this._deferredAnimate && that._deferredAnimate.resolveWith(that); hideItems && this._renderItemVisibility(); }); return positionReady.promise(); }, _startSwipe: function _startSwipe() { this.$element().addClass(GALLERY_ACTIVE_CLASS); }, _endSwipe: function _endSwipe() { this.$element().removeClass(GALLERY_ACTIVE_CLASS); }, _animate: function _animate(targetPosition, extraConfig) { var that = this, $container = this._$container, animationComplete = new Deferred(); fx.animate(this._$container, extend({ type: "slide", to: { left: targetPosition * this._elementWidth() }, duration: that.option("animationDuration"), complete: function complete() { if (that._needMoveContainerForward()) { translator.move($container, { left: 0, top: 0 }); } if (that._needMoveContainerBack()) { translator.move($container, { left: that._maxContainerOffset() * that._elementWidth(), top: 0 }); } animationComplete.resolveWith(that); } }, extraConfig || {})); return animationComplete; }, _needMoveContainerForward: function _needMoveContainerForward() { var expectedPosition = this._$container.position().left * this._offsetDirection(), actualPosition = -this._maxItemWidth() * this._elementWidth() * this._itemsCount(); return expectedPosition <= actualPosition + MAX_CALC_ERROR; }, _needMoveContainerBack: function _needMoveContainerBack() { var expectedPosition = this._$container.position().left * this._offsetDirection(), actualPosition = this._actualItemWidth() * this._elementWidth(); return expectedPosition >= actualPosition - MAX_CALC_ERROR; }, _maxContainerOffset: function _maxContainerOffset() { return -this._maxItemWidth() * (this._itemsCount() - this._itemsPerPage()) * this._offsetDirection(); }, _maxItemWidth: function _maxItemWidth() { return this._actualItemWidth() + this._itemFreeSpace(); }, _reviseDimensions: function _reviseDimensions() { var that = this, $firstItem = that._itemElements().first().find(".dx-item-content"); if (!$firstItem || $firstItem.is(":hidden")) { return; } if (!that.option("height")) { that.option("height", $firstItem.outerHeight()); } if (!that.option("width")) { that.option("width", $firstItem.outerWidth()); } this._dimensionChanged(); }, _renderIndicator: function _renderIndicator() { this._cleanIndicators(); if (!this.option("showIndicator")) { return; } var indicator = this._$indicator = $("<div>").addClass(GALLERY_INDICATOR_CLASS).appendTo(this._$wrapper); for (var i = 0; i < this._pagesCount(); i++) { $("<div>").addClass(GALLERY_INDICATOR_ITEM_CLASS).appendTo(indicator); } this._renderSelectedPageIndicator(); }, _cleanIndicators: function _cleanIndicators() { if (this._$indicator) { this._$indicator.remove(); } }, _renderSelectedItem: function _renderSelectedItem() { var selectedIndex = this.option("selectedIndex"); this._itemElements().removeClass(GALLERY_ITEM_SELECTED_CLASS).eq(selectedIndex).addClass(GALLERY_ITEM_SELECTED_CLASS); }, _renderItemVisibility: function _renderItemVisibility() { if (this.option("initialItemWidth") || this.option("wrapAround")) { this._releaseInvisibleItems(); return; } this._itemElements().each(function (index, item) { if (this.option("selectedIndex") === index) { $(item).removeClass(GALLERY_INVISIBLE_ITEM_CLASS); } else { $(item).addClass(GALLERY_INVISIBLE_ITEM_CLASS); } }.bind(this)); this._getLoopedItems().addClass(GALLERY_INVISIBLE_ITEM_CLASS); }, _releaseInvisibleItems: function _releaseInvisibleItems() { this._itemElements().removeClass(GALLERY_INVISIBLE_ITEM_CLASS); this._getLoopedItems().removeClass(GALLERY_INVISIBLE_ITEM_CLASS); }, _renderSelectedPageIndicator: function _renderSelectedPageIndicator() { if (!this._$indicator) { return; } var itemIndex = this.option("selectedIndex"), lastIndex = this._pagesCount() - 1, pageIndex = Math.ceil(itemIndex / this._itemsPerPage()); pageIndex = Math.min(lastIndex, pageIndex); this._$indicator.find(GALLERY_INDICATOR_ITEM_SELECTOR).removeClass(GALLERY_INDICATOR_ITEM_SELECTED_CLASS).eq(pageIndex).addClass(GALLERY_INDICATOR_ITEM_SELECTED_CLASS); }, _renderUserInteraction: function _renderUserInteraction() { var rootElement = this.$element(), swipeEnabled = this.option("swipeEnabled") && this._itemsCount() > 1; this._createComponent(rootElement, Swipeable, { disabled: this.option("disabled") || !swipeEnabled, onStart: this._swipeStartHandler.bind(this), onUpdated: this._swipeUpdateHandler.bind(this), onEnd: this._swipeEndHandler.bind(this), itemSizeFunc: this._elementWidth.bind(this) }); var indicatorSelectAction = this._createAction(this._indicatorSelectHandler); eventsEngine.off(rootElement, eventUtils.addNamespace(clickEvent.name, this.NAME), GALLERY_INDICATOR_ITEM_SELECTOR); eventsEngine.on(rootElement, eventUtils.addNamespace(clickEvent.name, this.NAME), GALLERY_INDICATOR_ITEM_SELECTOR, function (e) { indicatorSelectAction({ event: e }); }); }, _indicatorSelectHandler: function _indicatorSelectHandler(args) { var e = args.event, instance = args.component; if (!instance.option("indicatorEnabled")) { return; } var indicatorIndex = $(e.target).index(), itemIndex = instance._fitPaginatedIndex(indicatorIndex * instance._itemsPerPage()); instance._needLongMove = true; instance.option("selectedIndex", itemIndex); instance._loadNextPageIfNeeded(itemIndex); }, _renderNavButtons: function _renderNavButtons() { var that = this; if (!that.option("showNavButtons")) { that._cleanNavButtons(); return; } that._prevNavButton = $("<div>").appendTo(this._$wrapper); that._createComponent(that._prevNavButton, GalleryNavButton, { direction: "prev", onClick: function onClick() { that._prevPage(); } }); that._nextNavButton = $("<div>").appendTo(this._$wrapper); that._createComponent(that._nextNavButton, GalleryNavButton, { direction: "next", onClick: function onClick() { that._nextPage(); } }); this._renderNavButtonsVisibility(); }, _prevPage: function _prevPage() { var visiblePageSize = this._itemsPerPage(), newSelectedIndex = this.option("selectedIndex") - visiblePageSize; if (newSelectedIndex === -visiblePageSize && visiblePageSize === this._itemsCount()) { return this._relocateItems(newSelectedIndex, 0); } else { return this.goToItem(this._fitPaginatedIndex(newSelectedIndex)); } }, _nextPage: function _nextPage() { var visiblePageSize = this._itemsPerPage(), newSelectedIndex = this.option("selectedIndex") + visiblePageSize; if (newSelectedIndex === visiblePageSize && visiblePageSize === this._itemsCount()) { return this._relocateItems(newSelectedIndex, 0); } else { return this.goToItem(this._fitPaginatedIndex(newSelectedIndex)).done(this._loadNextPageIfNeeded); } }, _loadNextPageIfNeeded: function _loadNextPageIfNeeded(selectedIndex) { selectedIndex = selectedIndex === undefined ? this.option("selectedIndex") : selectedIndex; if (this._dataSource && this._dataSource.paginate() && this._shouldLoadNextPage(selectedIndex) && !this._isDataSourceLoading() && !this._isLastPage()) { this._loadNextPage().done(function () { this._renderIndicator(); this._renderItemPositions(); this._renderNavButtonsVisibility(); this._renderItemSizes(selectedIndex); }.bind(this)); } }, _shouldLoadNextPage: function _shouldLoadNextPage(selectedIndex) { var visiblePageSize = this._itemsPerPage(); return selectedIndex + 2 * visiblePageSize > this.option("items").length; }, _allowDynamicItemsAppend: function _allowDynamicItemsAppend() { return true; }, _fitPaginatedIndex: function _fitPaginatedIndex(itemIndex) { var itemsPerPage = this._itemsPerPage(); var restItemsCount = itemIndex < 0 ? itemsPerPage + itemIndex : this._itemsCount() - itemIndex; if (itemIndex > this._itemsCount() - 1) { itemIndex = 0; this._goToGhostItem = true; } else if (restItemsCount < itemsPerPage && restItemsCount > 0) { if (itemIndex > 0) { itemIndex = itemIndex - (itemsPerPage - restItemsCount); } else { itemIndex = itemIndex + (itemsPerPage - restItemsCount); } } return itemIndex; }, _cleanNavButtons: function _cleanNavButtons() { if (this._prevNavButton) { this._prevNavButton.remove(); delete this._prevNavButton; } if (this._nextNavButton) { this._nextNavButton.remove(); delete this._nextNavButton; } }, _renderNavButtonsVisibility: function _renderNavButtonsVisibility() { if (!this.option("showNavButtons") || !this._prevNavButton || !this._nextNavButton) { return; } var selectedIndex = this.option("selectedIndex"), loop = this.option("loop"), itemsCount = this._itemsCount(); this._prevNavButton.show(); this._nextNavButton.show(); if (itemsCount === 0) { this._prevNavButton.hide(); this._nextNavButton.hide(); } if (loop) { return; } var nextHidden = selectedIndex === itemsCount - this._itemsPerPage(), prevHidden = itemsCount < 2 || selectedIndex === 0; if (this._dataSource && this._dataSource.paginate()) { nextHidden = nextHidden && this._isLastPage(); } else { nextHidden = nextHidden || itemsCount < 2; } if (prevHidden) { this._prevNavButton.hide(); } if (nextHidden) { this._nextNavButton.hide(); } }, _setupSlideShow: function _setupSlideShow() { var that = this, slideshowDelay = that.option("slideshowDelay"); clearTimeout(that._slideshowTimer); if (!slideshowDelay) { return; } that._slideshowTimer = setTimeout(function () { if (that._userInteraction) { that._setupSlideShow(); return; } that.nextItem(true).done(that._setupSlideShow); }, slideshowDelay); }, _elementWidth: function _elementWidth() { if (!this._cacheElementWidth) { this._cacheElementWidth = this.$element().width(); } return this._cacheElementWidth; }, _clearCacheWidth: function _clearCacheWidth() { delete this._cacheElementWidth; }, _swipeStartHandler: function _swipeStartHandler(e) { this._releaseInvisibleItems(); this._clearCacheWidth(); this._elementWidth(); var itemsCount = this._itemsCount(); if (!itemsCount) { e.event.cancel = true; return; } this._stopItemAnimations(); this._startSwipe(); this._userInteraction = true; if (!this.option("loop")) { var selectedIndex = this.option("selectedIndex"), startOffset = itemsCount - selectedIndex - this._itemsPerPage(), endOffset = selectedIndex, rtlEnabled = this.option("rtlEnabled"); e.event.maxLeftOffset = rtlEnabled ? endOffset : startOffset; e.event.maxRightOffset = rtlEnabled ? startOffset : endOffset; } }, _stopItemAnimations: function _stopItemAnimations() { fx.stop(this._$container, true); }, _swipeUpdateHandler: function _swipeUpdateHandler(e) { var wrapAroundRatio = this.option("wrapAround") ? 1 : 0; var offset = this._offsetDirection() * e.event.offset * (this._itemsPerPage() + wrapAroundRatio) - this.option("selectedIndex"); if (offset < 0) { this._loadNextPageIfNeeded(Math.ceil(Math.abs(offset))); } this._renderContainerPosition(offset); }, _swipeEndHandler: function _swipeEndHandler(e) { var targetOffset = e.event.targetOffset * this._offsetDirection() * this._itemsPerPage(), selectedIndex = this.option("selectedIndex"), newIndex = this._fitIndex(selectedIndex - targetOffset), paginatedIndex = this._fitPaginatedIndex(newIndex); if (Math.abs(targetOffset) < this._itemsPerPage()) { this._relocateItems(selectedIndex); return; } if (this._itemsPerPage() === this._itemsCount()) { if (targetOffset > 0) { this._relocateItems(-targetOffset); } else { this._relocateItems(0); } return; } this.option("selectedIndex", paginatedIndex); }, _setFocusOnSelect: function _setFocusOnSelect() { this._userInteraction = true; var selectedItem = this.itemElements().filter("." + GALLERY_ITEM_SELECTED_CLASS); this.option("focusedElement", getPublicElement(selectedItem)); this._userInteraction = false; }, _flipIndex: function _flipIndex(index) { var itemsCount = this._itemsCount(); index = index % itemsCount; if (index > (itemsCount + 1) / 2) { index -= itemsCount; } if (index < -(itemsCount - 1) / 2) { index += itemsCount; } return index; }, _fitIndex: function _fitIndex(index) { if (!this.option("loop")) { return index; } var itemsCount = this._itemsCount(); if (index >= itemsCount || index < 0) { this._goToGhostItem = true; } if (index >= itemsCount) { index = itemsCount - index; } index = index % itemsCount; if (index < 0) { index += itemsCount; } return index; }, _clean: function _clean() { this.callBase(); this._cleanIndicators(); this._cleanNavButtons(); }, _dispose: function _dispose() { clearTimeout(this._slideshowTimer); this.callBase(); }, _updateSelection: function _updateSelection(addedSelection, removedSelection) { this._stopItemAnimations(); this._renderNavButtonsVisibility(); this._renderSelectedItem(); this._relocateItems(addedSelection[0], removedSelection[0]); this._renderSelectedPageIndicator(); }, _relocateItems: function _relocateItems(newIndex, prevIndex, withoutAnimation) { if (prevIndex === undefined) { prevIndex = newIndex; } var indexOffset = this._calculateIndexOffset(newIndex, prevIndex); this._renderContainerPosition(indexOffset, true, this.option("animationEnabled") && !withoutAnimation).done(function () { this._setFocusOnSelect(); this._userInteraction = false; this._setupSlideShow(); }); }, _focusInHandler: function _focusInHandler() { if (fx.isAnimating(this._$container) || this._userInteraction) { return; } this.callBase.apply(this, arguments); }, _focusOutHandler: function _focusOutHandler() { if (fx.isAnimating(this._$container) || this._userInteraction) { return; } this.callBase.apply(this, arguments); }, _selectFocusedItem: commonUtils.noop, _moveFocus: function _moveFocus() { this._stopItemAnimations(); this.callBase.apply(this, arguments); var index = this.itemElements().index($(this.option("focusedElement"))); this.goToItem(index, this.option("animationEnabled")); }, _visibilityChanged: function _visibilityChanged(visible) { if (visible) { this._reviseDimensions(); } }, _calculateIndexOffset: function _calculateIndexOffset(newIndex, lastIndex) { if (lastIndex === undefined) { lastIndex = newIndex; } var indexOffset = lastIndex - newIndex; if (this.option("loop") && !this._needLongMove && this._goToGhostItem) { if (this._isItemOnFirstPage(newIndex) && this._isItemOnLastPage(lastIndex)) { indexOffset = -this._itemsPerPage(); } else if (this._isItemOnLastPage(newIndex) && this._isItemOnFirstPage(lastIndex)) { indexOffset = this._itemsPerPage(); } this._goToGhostItem = false; } this._needLongMove = false; indexOffset = indexOffset - lastIndex; return indexOffset; }, _isItemOnLastPage: function _isItemOnLastPage(itemIndex) { return itemIndex >= this._itemsCount() - this._itemsPerPage(); }, _isItemOnFirstPage: function _isItemOnFirstPage(itemIndex) { return itemIndex <= this._itemsPerPage(); }, _optionChanged: function _optionChanged(args) { switch (args.name) { case "width": case "initialItemWidth": this.callBase.apply(this, arguments); this._dimensionChanged(); break; case "animationDuration": this._renderNavButtonsVisibility(); break; case "animationEnabled": break; case "loop": this.$element().toggleClass(GALLERY_LOOP_CLASS, args.value); this.option("loopItemFocus", args.value); if (windowUtils.hasWindow()) { this._renderDuplicateItems(); this._renderItemPositions(); this._renderNavButtonsVisibility(); } break; case "showIndicator": this._renderIndicator(); break; case "showNavButtons": this._renderNavButtons(); break; case "slideshowDelay": this._setupSlideShow(); break; case "wrapAround": case "stretchImages": if (windowUtils.hasWindow()) { this._renderItemSizes(); this._renderItemPositions(); this._renderItemVisibility(); } break; case "swipeEnabled": case "indicatorEnabled": this._renderUserInteraction(); break; default: this.callBase(args); } }, /** * @name dxgallerymethods.goToItem * @publicName goToItem(itemIndex, animation) * @param1 itemIndex:numeric * @param2 animation:boolean * @return Promise<void> */ goToItem: function goToItem(itemIndex, animation) { var selectedIndex = this.option("selectedIndex"), itemsCount = this._itemsCount(); if (animation !== undefined) { this._animationOverride = animation; } itemIndex = this._fitIndex(itemIndex); this._deferredAnimate = new Deferred(); if (itemIndex > itemsCount - 1 || itemIndex < 0 || selectedIndex === itemIndex) { return this._deferredAnimate.resolveWith(this).promise(); } this.option("selectedIndex", itemIndex); return this._deferredAnimate.promise(); }, /** * @name dxgallerymethods.prevItem * @publicName prevItem(animation) * @param1 animation:boolean * @return Promise<void> */ prevItem: function prevItem(animation) { return this.goToItem(this.option("selectedIndex") - 1, animation); }, /** * @name dxgallerymethods.nextItem * @publicName nextItem(animation) * @param1 animation:boolean * @return Promise<void> */ nextItem: function nextItem(animation) { return this.goToItem(this.option("selectedIndex") + 1, animation); } }); registerComponent("dxGallery", Gallery); module.exports = Gallery;