/*! * UI development toolkit for HTML5 (OpenUI5) * (c) Copyright 2009-2018 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides control sap.m.IconTabHeader. sap.ui.define([ './library', 'sap/ui/core/Control', 'sap/ui/core/EnabledPropagator', 'sap/ui/core/delegate/ItemNavigation', 'sap/ui/core/IconPool', 'sap/ui/core/delegate/ScrollEnablement', './IconTabBarSelectList', './Button', './ResponsivePopover', './IconTabFilter', 'sap/ui/Device', 'sap/ui/core/ResizeHandler', 'sap/ui/core/Icon', './IconTabBarDragAndDropUtil', './IconTabHeaderRenderer', "sap/ui/thirdparty/jquery", "sap/base/Log" ], function( library, Control, EnabledPropagator, ItemNavigation, IconPool, ScrollEnablement, IconTabBarSelectList, Button, ResponsivePopover, IconTabFilter, Device, ResizeHandler, Icon, IconTabBarDragAndDropUtil, IconTabHeaderRenderer, jQuery, Log ) { "use strict"; // shortcut for sap.m.touch var touch = library.touch; // shortcut for sap.m.ImageHelper var ImageHelper = library.ImageHelper; // shortcut for sap.m.PlacementType var PlacementType = library.PlacementType; // shortcut for sap.m.ButtonType var ButtonType = library.ButtonType; // shortcut for sap.m.BackgroundDesign var BackgroundDesign = library.BackgroundDesign; // shortcut for sap.m.IconTabHeaderMode var IconTabHeaderMode = library.IconTabHeaderMode; // shortcut for sap.m.IconTabDensityMode var IconTabDensityMode = library.IconTabDensityMode; /** * Constructor for a new IconTabHeader. * * @param {string} [sId] ID for the new control, generated automatically if no ID is given * @param {object} [mSettings] Initial settings for the new control * * @class * This control displays a number of IconTabFilters and IconTabSeparators. If the available horizontal * space is exceeded, a horizontal scrolling appears. * @extends sap.ui.core.Control * * @author SAP SE * @version 1.60.23 * * @constructor * @public * @alias sap.m.IconTabHeader * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel */ var IconTabHeader = Control.extend("sap.m.IconTabHeader", /** @lends sap.m.IconTabHeader.prototype */ { metadata : { library : "sap.m", properties : { /** * Defines whether the current selection is visualized. * @deprecated As of 1.15.0. * Regarding to changes of this control this property is not needed anymore. */ showSelection : {type : "boolean", group : "Misc", defaultValue : true, deprecated: true}, /** * Key of the selected item. * * If the key has no corresponding aggregated item, no changes will apply. * If duplicate keys exists the first item matching, the key is used. * @since 1.15.0 */ selectedKey : {type : "string", group : "Data", defaultValue : null}, /** * Specifies whether the control is rendered. * @since 1.15.0 */ visible : {type : "boolean", group : "Behavior", defaultValue : true}, /** * Specifies the header mode. * Note: The Inline mode works only if no icons are set. * * @since 1.40 */ mode : {type : "sap.m.IconTabHeaderMode", group : "Appearance", defaultValue : IconTabHeaderMode.Standard}, /** * Specifies if the overflow select list is displayed. * * The overflow select list represents a list, where all tab filters are displayed, * so the user can select specific tab filter easier. * @since 1.42 */ showOverflowSelectList : {type : "boolean", group : "Appearance", defaultValue : false}, /** * Specifies the background color of the header. * * Depending on the theme, you can change the state of * the background color to "Solid", "Translucent", or "Transparent". * Default is "Solid". * @since 1.44 */ backgroundDesign : {type : "sap.m.BackgroundDesign", group : "Appearance", defaultValue : BackgroundDesign.Solid}, /** * Specifies whether tab reordering is enabled. Relevant only for desktop devices. * The {@link sap.m.IconTabSeparator sap.m.IconTabSeparator} cannot be dragged and dropped * Items can be moved around {@link sap.m.IconTabSeparator sap.m.IconTabSeparator} * @since 1.46 */ enableTabReordering : {type : "boolean", group : "Behavior", defaultValue : false}, /** * Specifies the visual density mode of the tabs. * * The values that can be applied are Cozy, Compact and Inherit. * Cozy and Compact render the control in one of these modes independent of the global density settings. * The Inherit value follows the global density settings which are applied. * For compatibility reasons, the default value is Cozy. * @since 1.56 */ tabDensityMode :{type : "sap.m.IconTabDensityMode", group : "Appearance", defaultValue : IconTabDensityMode.Cozy} }, aggregations : { /** * The items displayed in the IconTabHeader. */ items : {type : "sap.m.IconTab", multiple : true, singularName : "item", dnd : {draggable: true, droppable: true, layout: "Horizontal"} }, /** * Internal aggregation for managing the overflow button. */ _overflowButton : {type : "sap.m.Button", multiple : false, visibility : "hidden"} }, events : { /** * Fires when an item is selected. */ select : { parameters : { /** * The selected item * @since 1.15.0 */ item : {type : "sap.m.IconTabFilter"}, /** * The key of the selected item * @since 1.15.0 */ key : {type : "string"} } } } }}); EnabledPropagator.apply(IconTabHeader.prototype, [true]); IconTabHeader.SCROLL_STEP = 264; // how many pixels to scroll with every overflow arrow click IconTabHeader.prototype.init = function() { this._bPreviousScrollForward = false; // remember the item overflow state this._bPreviousScrollBack = false; this._iCurrentScrollLeft = 0; this.startScrollX = 0; this.startTouchX = 0; this._scrollable = null; this._aTabKeys = []; // Initialize the ItemNavigation this._oItemNavigation = new ItemNavigation().setCycling(false); this._oItemNavigation.attachEvent(ItemNavigation.Events.FocusLeave, this._onItemNavigationFocusLeave, this); this._oItemNavigation.attachEvent(ItemNavigation.Events.AfterFocus, this._onItemNavigationAfterFocus, this); this._oItemNavigation.setDisabledModifiers({ sapnext : ["alt", "meta"], sapprevious : ["alt", "meta"] }); this.addDelegate(this._oItemNavigation); this._oScroller = new ScrollEnablement(this, this.getId() + "-head", { horizontal: true, vertical: false, nonTouchScrolling: true }); }; /** * Returns if the touch scrolling is disabled * @private */ IconTabHeader.prototype.isTouchScrollingDisabled = function () { return this.getShowOverflowSelectList() && this.getParent().getMetadata().getName() == 'sap.tnt.ToolHeader'; }; /** * Returns overflow select list * @private */ IconTabHeader.prototype._getSelectList = function () { var that = this; if (!this._oSelectList) { this._oSelectList = new IconTabBarSelectList({ selectionChange: function (oEvent) { var oTarget = oEvent.getParameter('selectedItem'); that.setSelectedItem(oTarget._tabFilter); } }); this._oSelectList._iconTabHeader = this; } return this._oSelectList; }; /** * Returns overflow button * @private */ IconTabHeader.prototype._getOverflowButton = function () { var oOverflowButton = this.getAggregation("_overflowButton"); if (!oOverflowButton) { oOverflowButton = new Button({ id: this.getId() + '-overflow', icon: "sap-icon://slim-arrow-down", type: ButtonType.Transparent, press: this._overflowButtonPress.bind(this) }); oOverflowButton.addEventDelegate(this._onOverflowButtonEventDelegate); this.setAggregation("_overflowButton", oOverflowButton); } return oOverflowButton; }; /** * Handles overflow button "press" event * @private */ IconTabHeader.prototype._overflowButtonPress = function (event) { if (!this._oPopover) { this._oPopover = new ResponsivePopover({ showArrow: false, showHeader: false, placement: PlacementType.Vertical, offsetX: 0, offsetY: 0 } ).addStyleClass('sapMITBPopover'); if (Device.system.phone) { this._oPopover._oControl.addButton(this._createPopoverCloseButton()); } this.addDependent(this._oPopover); //This overrides the popover _adaptPositionParams function for placing the popover //over the right bottom corner of the button. This change is required by the visual spec. this._oPopover._oControl._adaptPositionParams = function () { var bIsCompact = jQuery("body").hasClass("sapUiSizeCompact"); this._arrowOffset = 0; if (bIsCompact) { this._offsets = ["0 0", "0 0", "0 2", "0 0"]; } else { this._offsets = ["0 0", "0 0", "0 3", "0 0"]; } this._myPositions = ["end bottom", "begin top", "end top", "end top"]; this._atPositions = ["end top", "end top", "end bottom", "begin top"]; }; } var oSelectList = this._getSelectList(); this._setSelectListItems(); this._oPopover.removeAllContent(); this._oPopover.addContent(oSelectList); this._oPopover.setInitialFocus(oSelectList.getSelectedItem()); this._oPopover.openBy(this._getOverflowButton()); }; /** * Creates popover close button * @private */ IconTabHeader.prototype._createPopoverCloseButton = function() { var that = this; var oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m"); return new Button({ text: oResourceBundle.getText("SELECT_CANCEL_BUTTON"), press: function() { that._closeOverflow(); } }); }; /** * Closes the overflow popover and focuses the correct tab filter * @private */ IconTabHeader.prototype._closeOverflow = function () { if (!Device.system.desktop) { this._oPopover.close(); } if (this.oSelectedItem) { this.oSelectedItem.$().focus(); } }; /** * Sets overflow items * * @returns {sap.ui.core.Element} * @private */ IconTabHeader.prototype._setSelectListItems = function () { if (!this.getShowOverflowSelectList()) { return; } var oSelectItem, oTabFilter, oSelectList = this._getSelectList(), aTabFilters = this.getTabFilters(); oSelectList.destroyItems(); for (var i = 0; i < aTabFilters.length; i++) { oTabFilter = aTabFilters[i]; oSelectItem = oTabFilter.clone(); oSelectItem._tabFilter = oTabFilter; oSelectList.addItem(oSelectItem); if (oTabFilter == this.oSelectedItem) { oSelectList.setSelectedItem(oSelectItem); } } }; /** * Returns SelectList item, that corresponds ot specific TabFilter. * @private */ IconTabHeader.prototype._findSelectItem = function (oTabFilter) { var oSelectList = this._getSelectList(), aSelectListItems = oSelectList.getItems(), oSelectItem; for (var i = 0; i < aSelectListItems.length; i++){ oSelectItem = aSelectListItems[i]; if (oSelectItem._tabFilter == oTabFilter) { return oSelectItem; } } }; IconTabHeader.prototype._onItemNavigationFocusLeave = function() { // BCP: 1570034646 if (!this.oSelectedItem) { return; } var aItems = this.getItems(); var iIndex = -1; var oItem; for (var i = 0; i < aItems.length; i++) { oItem = aItems[i]; if (oItem instanceof IconTabFilter == false) { continue; } iIndex++; if (this.oSelectedItem == oItem) { break; } } this._oItemNavigation.setFocusedIndex(iIndex); }; /** * Adjusts arrows when keyboard is used for navigation and the beginning/end of the toolbar is reached. * @private */ IconTabHeader.prototype._onItemNavigationAfterFocus = function(oEvent) { var oHead = this.getDomRef("head"), oIndex = oEvent.getParameter("index"), $event = oEvent.getParameter('event'); // handle only keyboard navigation here if ($event.keyCode === undefined) { return; } this._iCurrentScrollLeft = oHead.scrollLeft; this._checkOverflow(); if (oIndex !== null && oIndex !== undefined) { this._scrollIntoView(this.getTabFilters()[oIndex], 0); } }; /** * Returns all tab filters, without the tab separators. * @private */ IconTabHeader.prototype.getTabFilters = function() { var aItems = this.getItems(); var aTabFilters = []; aItems.forEach(function(oItem) { if (oItem instanceof IconTabFilter) { aTabFilters.push(oItem); } }); return aTabFilters; }; IconTabHeader.prototype.exit = function() { if (this._oArrowLeft) { this._oArrowLeft.destroy(); } if (this._oArrowRight) { this._oArrowRight.destroy(); } if (this._oItemNavigation) { this.removeDelegate(this._oItemNavigation); this._oItemNavigation.destroy(); delete this._oItemNavigation; } if (this._oScroller) { this._oScroller.destroy(); this._oScroller = null; } if (this._sResizeListenerId) { ResizeHandler.deregister(this._sResizeListenerId); this._sResizeListenerId = null; } if (this._aTabKeys) { this._aTabKeys = null; } if (this._oPopover) { this._oPopover.destroy(); this._oPopover = null; } }; /** * Handles onLongDragOver of overflow button. * @private */ IconTabHeader.prototype._handleOnLongDragOver = function() { if (!this._oPopover || !this._oPopover.isOpen()) { this._overflowButtonPress(); } }; /** * Handles onDragOver of the overflow button. * @private * @param {jQuery.Event} oEvent The jQuery drag over event */ IconTabHeader.prototype._handleOnDragOver = function(oEvent) { this._getOverflowButton().addStyleClass("sapMBtnDragOver"); oEvent.preventDefault(); // allow drop, so that the cursor is correct }; /** * Handles onDrop of the overflow button. * @private */ IconTabHeader.prototype._handleOnDrop = function() { this._getOverflowButton().removeStyleClass("sapMBtnDragOver"); }; /** * Handles onDragLeave of the overflow button. * @private */ IconTabHeader.prototype._handleOnDragLeave = function() { this._getOverflowButton().removeStyleClass("sapMBtnDragOver"); }; /** * Sets or remove Drag and Drop configurations. * @private */ IconTabHeader.prototype._setsDragAndDropConfigurations = function() { if (!this.getEnableTabReordering() && this.getDragDropConfig().length) { //Destroying Drag&Drop aggregation this.destroyDragDropConfig(); } else if (this.getEnableTabReordering() && !this.getDragDropConfig().length) { //Adding Drag&Drop configuration to the dragDropConfig aggregation if needed IconTabBarDragAndDropUtil.setDragDropAggregations(this, "Horizontal"); } }; IconTabHeader.prototype.onBeforeRendering = function() { var aItems = this.getItems(), sSelectedKey = this.getSelectedKey(), i = 0, oParent = this.getParent(), bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar, bIsParentToolHeader = oParent && oParent.getMetadata().getName() == 'sap.tnt.ToolHeader'; this._bRtl = sap.ui.getCore().getConfiguration().getRTL(); this._onOverflowButtonEventDelegate = { onlongdragover: this._handleOnLongDragOver.bind(this), ondragover: this._handleOnDragOver.bind(this), ondragleave: this._handleOnDragLeave.bind(this), ondrop: this._handleOnDrop.bind(this) }; if (this._sResizeListenerId) { ResizeHandler.deregister(this._sResizeListenerId); this._sResizeListenerId = null; } if (aItems.length > 0) { if (!this.oSelectedItem || sSelectedKey && sSelectedKey !== this.oSelectedItem._getNonEmptyKey()) { if (sSelectedKey) { // selected key was specified by API: set oSelectedItem to the item specified by key for (; i < aItems.length; i++) { if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i]._getNonEmptyKey() === sSelectedKey) { this.oSelectedItem = aItems[i]; break; } } } // no key and no item, we set the first visible item as selected if (!this.oSelectedItem && (bIsParentIconTabBar || !sSelectedKey)) { for (i = 0; i < aItems.length; i++) { // tab item if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i].getVisible()) { this.oSelectedItem = aItems[i]; break; } } } } //in case the selected tab is not visible anymore, the selected tab will change to the first visible tab if (!bIsParentToolHeader && this.oSelectedItem && !this.oSelectedItem.getVisible()) { for (i = 0; i < aItems.length; i++) { // tab item if (!(aItems[i] instanceof sap.m.IconTabSeparator) && aItems[i].getVisible()) { this.oSelectedItem = aItems[i]; break; } } } if (this.oSelectedItem) { this.setProperty("selectedKey", this.oSelectedItem._getNonEmptyKey(), true); } } this._isTouchScrollingDisabled = this.isTouchScrollingDisabled(); this._oScroller.setHorizontal(!this._isTouchScrollingDisabled && (!this.getEnableTabReordering() || !Device.system.desktop)); this._setsDragAndDropConfigurations(); }; /** * Sets the selected item based on key. * @overwrite * @public * @param {string} sKey The key of the item to be selected * @return {sap.m.IconTabHeader} this pointer for chaining */ IconTabHeader.prototype.setSelectedKey = function (sKey) { var aItems = this.getTabFilters(), i = 0, oParent = this.getParent(), bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar, bSelectedItemFound; if (aItems.length > 0) { sKey = sKey || aItems[0]._getNonEmptyKey(); } // adjust UI and internal variables if already rendered (otherwise taken care by onBeforeRendering) if (this.$().length) { for (; i < aItems.length; i++) { if (aItems[i]._getNonEmptyKey() === sKey) { this.setSelectedItem(aItems[i], true); bSelectedItemFound = true; break; } } if (!bSelectedItemFound && !bIsParentIconTabBar && sKey) { this.setSelectedItem(null); } } // set internal property this.setProperty("selectedKey", sKey, true); return this; }; /* * Sets the selected item, updates the UI, and fires the select event. * @private * @param {sap.m.IconTabFilter} oItem The item to be selected * @param {Boolean} bAPIChange whether this function is called through the API * @return {sap.m.IconTabHeader} this pointer for chaining */ IconTabHeader.prototype.setSelectedItem = function(oItem, bAPIchange) { if (!oItem) { if (this.oSelectedItem) { this.oSelectedItem.$().removeClass("sapMITBSelected"); this.oSelectedItem = null; } return this; } if (!oItem.getEnabled()) { return this; } if (this.getShowOverflowSelectList()) { var oSelectItem = this._findSelectItem(oItem); if (oSelectItem) { this._getSelectList().setSelectedItem(oSelectItem); } } var oParent = this.getParent(); var bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar; //if the old selected tab and the new selected tab both have no own content, which means they both use the same content from the icontabbar //there is no need to rerender the content //fix for xml views css: 0120061532 0001427250 2014 var bIsContentTheSame = false; if (oItem.getContent().length === 0 && this.oSelectedItem && this.oSelectedItem.getContent().length === 0) { bIsContentTheSame = true; } if (this.oSelectedItem && this.oSelectedItem.getVisible() && (!bAPIchange && bIsParentIconTabBar && oParent.getExpandable() || this.oSelectedItem !== oItem)) { this.oSelectedItem.$() .removeClass("sapMITBSelected") .attr('aria-selected', false) .removeAttr('aria-expanded'); } if (oItem.getVisible()) { //click on already selected item leads to expanding/collapsing of the content (if expandable enabled) if (this.oSelectedItem === oItem) { //if content is not expandable nothing should happen otherwise content will be expanded/collapsed if (!bAPIchange && bIsParentIconTabBar && oParent.getExpandable()) { oParent._toggleExpandCollapse(); } //click on other item leads to showing the right content of this item } else { //change the content aria-labaled by the newly selected tab; if (bIsParentIconTabBar) { oParent.$("content").attr('aria-labelledby', oItem.sId); } // set new item this.oSelectedItem = oItem; this.setProperty("selectedKey", this.oSelectedItem._getNonEmptyKey(), true); if (!bIsParentIconTabBar) { this.oSelectedItem.$() .addClass("sapMITBSelected") .attr({ 'aria-selected': true }); } //if the IconTabBar is not expandable and the content not expanded (which means content can never be expanded), we do not need //to visualize the selection and we do not need to render the content if (bIsParentIconTabBar && (oParent.getExpandable() || oParent.getExpanded())) { // add selected styles this.oSelectedItem.$() .addClass("sapMITBSelected") .attr({ 'aria-selected': true }); //if item has own content, this content is shown var oSelectedItemContent = this.oSelectedItem.getContent(); if (oSelectedItemContent.length > 0) { oParent._rerenderContent(oSelectedItemContent); //if item has not own content, general content of the icontabbar is shown } else { //if the general content was already shown there is no need to rerender if (!bIsContentTheSame) { oParent._rerenderContent(oParent.getContent()); } } //if content is not expanded, content will be expanded (first click on item always leads to expanding the right content) if (!bAPIchange && oParent.getExpandable() && !oParent.getExpanded()) { oParent._toggleExpandCollapse(true); } } } // scroll to item if out of viewport if (this.oSelectedItem.$().length > 0) { this._scrollIntoView(oItem, 500); } else { this._scrollAfterRendering = true; } } this.oSelectedItem = oItem; var sSelectedKey = this.oSelectedItem._getNonEmptyKey(); this.setProperty("selectedKey", sSelectedKey, true); if (bIsParentIconTabBar) { oParent.setProperty("selectedKey", sSelectedKey, true); } if (!bAPIchange) { // fire event on iconTabBar if (bIsParentIconTabBar) { oParent.fireSelect({ selectedItem: this.oSelectedItem, selectedKey: sSelectedKey, item: this.oSelectedItem, key: sSelectedKey }); } else { // fire event on header this.fireSelect({ selectedItem: this.oSelectedItem, selectedKey: sSelectedKey, item: this.oSelectedItem, key: sSelectedKey }); } } return this; }; /** * Returns all the visible tab filters. * * @private */ IconTabHeader.prototype.getVisibleTabFilters = function() { var aItems = this.getTabFilters(), aVisibleItems = [], oItem; for (var i = 0; i < aItems.length; i++) { oItem = aItems[i]; if (oItem.getVisible()) { aVisibleItems.push(oItem); } } return aVisibleItems; }; /** * Returns the first visible item, which is needed for correct arrow calculation. */ IconTabHeader.prototype._getFirstVisibleItem = function(aItems) { for (var i = 0; i < aItems.length; i++) { if (aItems[i].getVisible()) { return aItems[i]; } } return null; }; IconTabHeader.prototype._initItemNavigation = function() { //use ItemNavigation for keyboardHandling var that = this, oHeadDomRef = this.getDomRef("head"), aItems = this.getItems(), aTabDomRefs = [], iSelectedDomIndex = -1; // find a collection of all tabs aItems.forEach(function(oItem) { if (oItem instanceof IconTabFilter) { var oItemDomRef = that.getFocusDomRef(oItem); jQuery(oItemDomRef).attr("tabindex", "-1"); aTabDomRefs.push(oItemDomRef); if (oItem === that.oSelectedItem) { iSelectedDomIndex = aTabDomRefs.indexOf(oItemDomRef); } } }); //Initialize the ItemNavigation if (!this._oItemNavigation) { this._oItemNavigation = new ItemNavigation(); this._oItemNavigation.attachEvent(ItemNavigation.Events.FocusLeave, this._onItemNavigationFocusLeave, this); this._oItemNavigation.attachEvent(ItemNavigation.Events.AfterFocus, this._onItemNavigationAfterFocus, this); this.addDelegate(this._oItemNavigation); } //Reinitialize the ItemNavigation after rendering this._oItemNavigation.setRootDomRef(oHeadDomRef); this._oItemNavigation.setItemDomRefs(aTabDomRefs); this._oItemNavigation.setPageSize(aTabDomRefs.length); // set the page size equal to the tab number so when we press pageUp/pageDown to focus first/last tab this._oItemNavigation.setSelectedIndex(iSelectedDomIndex); }; IconTabHeader.prototype.onThemeChanged = function() { this._applyTabDensityMode(); }; IconTabHeader.prototype._applyTabDensityMode = function() { var sTabDensityMode = this.getTabDensityMode(); this.$().removeClass("sapUiSizeCompact"); switch (sTabDensityMode) { case IconTabDensityMode.Compact: this.$().addClass("sapUiSizeCompact"); break; case IconTabDensityMode.Inherit: if (this.$().closest(".sapUiSizeCompact").length) { this.$().addClass("sapUiSizeCompact"); } break; } }; IconTabHeader.prototype.onAfterRendering = function() { this._applyTabDensityMode(); // initialize scrolling if (this._oScroller) { this._oScroller.setIconTabBar(this, jQuery.proxy(this._afterIscroll, this), jQuery.proxy(this._scrollPreparation, this)); } var oParent = this.getParent(); var bIsParentIconTabBar = oParent instanceof sap.m.IconTabBar; if (this.oSelectedItem && (!bIsParentIconTabBar || bIsParentIconTabBar && oParent.getExpanded())) { this.oSelectedItem.$() .addClass("sapMITBSelected") .attr({ 'aria-selected': true }); } setTimeout(this["_checkOverflow"].bind(this), 350); // scroll to selected item if it is out of screen and we render the control the first time if (this.oSelectedItem) { this._scrollIntoView(this.oSelectedItem, 500); } this._initItemNavigation(); // overflow button doesn't have tab stop if (this.getShowOverflowSelectList()) { this.$('overflow').attr('tabindex', -1); } //listen to resize this._sResizeListenerId = ResizeHandler.register(this.getDomRef(), jQuery.proxy(this._fnResize, this)); this._bCheckIfIntoView = true; }; /* * Destroys the item aggregation. */ IconTabHeader.prototype.destroyItems = function() { this.oSelectedItem = null; this._aTabKeys = []; this.destroyAggregation("items"); }; IconTabHeader.prototype.addItem = function(oItem) { if (!(oItem instanceof sap.m.IconTabSeparator)) { var sKey = oItem.getKey(); // check if key is a duplicate if (this._aTabKeys.indexOf(sKey) !== -1) { Log.warning("sap.m.IconTabHeader: duplicate key '" + sKey + "' inside the IconTabFilter. Please use unique keys."); } this._aTabKeys.push(sKey); } this.addAggregation("items", oItem); }; IconTabHeader.prototype.insertItem = function(oItem, iIndex) { if (!(oItem instanceof sap.m.IconTabSeparator)) { var sKey = oItem.getKey(); //check if key is a duplicate if (this._aTabKeys.indexOf(sKey) !== -1) { Log.warning("sap.m.IconTabHeader: duplicate key '" + sKey + "' inside the IconTabFilter. Please use unique keys."); } this._aTabKeys.push(sKey); } this.insertAggregation("items", oItem, iIndex); }; IconTabHeader.prototype.removeAllItems = function() { this._aTabKeys = []; return this.removeAllAggregation("items"); }; IconTabHeader.prototype.removeItem = function(oItem) { // Make sure we have the actual Item and not just an ID oItem = this.removeAggregation("items", oItem); if (oItem && !(oItem instanceof sap.m.IconTabSeparator)) { var sKey = oItem.getKey(); this._aTabKeys.splice(this._aTabKeys.indexOf(sKey) , 1); } // Return the original value from removeAggregation return oItem; }; IconTabHeader.prototype.updateAggregation = function() { this.oSelectedItem = null; return Control.prototype.updateAggregation.apply(this, arguments); }; IconTabHeader.prototype.removeAggregation = function (sAggregationName, oObject, bSuppressInvalidate) { var aItems = this.getTabFilters(); var oItem = Control.prototype.removeAggregation.apply(this, arguments); if (bSuppressInvalidate) { return oItem; } if (oItem && oItem == this.oSelectedItem && sAggregationName == 'items') { var iIndexOf = (aItems ? Array.prototype.indexOf.call(aItems, oItem) : -1); aItems = this.getTabFilters(); iIndexOf = Math.max(0, Math.min(iIndexOf, aItems.length - 1)); var oSelectedItem = aItems[iIndexOf]; if (oSelectedItem) { this.setSelectedItem(oSelectedItem, true); } else { var oIconTabBar = this.getParent(); if (oIconTabBar instanceof sap.m.IconTabBar && oIconTabBar.getExpanded()) { oIconTabBar.$("content").children().remove(); } } } return oItem; }; IconTabHeader.prototype.removeAllAggregation = function (sAggregationName, bSuppressInvalidate) { if (sAggregationName == 'items') { var oIconTabBar = this.getParent(); if (oIconTabBar instanceof sap.m.IconTabBar && oIconTabBar.getExpanded()) { oIconTabBar.$("content").children().remove(); } } return Control.prototype.removeAllAggregation.apply(this, arguments); }; /** * Returns the displayed text - text or text + (count) * @private */ IconTabHeader.prototype._getDisplayText = function (oItem) { var sText = oItem.getText(); if (this.isInlineMode()) { var sCount = oItem.getCount(); if (sCount) { if (this._bRtl) { sText = '(' + sCount + ') ' + sText; } else { sText += ' (' + sCount + ')'; } } } return sText; }; /** * Returns if the header is in inline mode. * @private */ IconTabHeader.prototype.isInlineMode = function () { return this._bTextOnly && this.getMode() == IconTabHeaderMode.Inline; }; /** * Checks if all tabs are textOnly version. * @private * @returns True if all tabs are textOnly version, otherwise false */ IconTabHeader.prototype._checkTextOnly = function(aItems) { if (aItems.length > 0) { for (var i = 0; i < aItems.length; i++) { if (!(aItems[i] instanceof sap.m.IconTabSeparator)) { if (aItems[i].getIcon()) { this._bTextOnly = false; return false; } } } } this._bTextOnly = true; return true; }; /** * Checks if all tabs are noText version. * @private * @returns True if all tabs are noText version, otherwise false */ IconTabHeader.prototype._checkNoText = function(aItems) { if (aItems.length > 0) { for (var i = 0; i < aItems.length; i++) { if (!(aItems[i] instanceof sap.m.IconTabSeparator)) { if (aItems[i].getText().length > 0) { return false; } } } } return true; }; /** * Checks if all tabs are in line version. * @private * @returns True if all tabs are in line version, otherwise false */ IconTabHeader.prototype._checkInLine = function(aItems) { var oItem; if (aItems.length > 0) { for (var i = 0; i < aItems.length; i++) { oItem = aItems[i]; if (!(oItem instanceof sap.m.IconTabSeparator)) { if (oItem.getIcon() || oItem.getCount()) { this._bInLine = false; return false; } } } } this._bInLine = true; return true; }; /** * Checks if scrolling is needed. * @private * @returns True if scrolling is needed, otherwise false */ IconTabHeader.prototype._checkScrolling = function(oHead) { var $bar = this.$(); var bScrolling = false; var domScrollCont = this.getDomRef("scrollContainer"); var domHead = this.getDomRef("head"); if (domHead && domScrollCont) { if (domHead.offsetWidth > domScrollCont.offsetWidth) { bScrolling = true; } } if (this._scrollable !== bScrolling) { $bar.toggleClass("sapMITBScrollable", bScrolling); $bar.toggleClass("sapMITBNotScrollable", !bScrolling); this._scrollable = bScrolling; } this._setTabsVisibility(); return bScrolling; }; /** * Gets the icon of the requested arrow (left/right). * @private * @param {string} sName Left or right * @returns Icon of the requested arrow */ IconTabHeader.prototype._getScrollingArrow = function(sName) { var src = IconPool.getIconURI("slim-arrow-" + sName); var mProperties = { src : src, useIconTooltip : false }; var sSuffix = this._bTextOnly ? "TextOnly" : ""; var sLeftArrowClass = "sapMITBArrowScrollLeft" + sSuffix; var sRightArrowClass = "sapMITBArrowScrollRight" + sSuffix; var aCssClassesToAddLeft = ["sapMITBArrowScroll", sLeftArrowClass]; var aCssClassesToAddRight = ["sapMITBArrowScroll", sRightArrowClass]; if (this._bInLine) { aCssClassesToAddLeft.push('sapMITBArrowScrollLeftInLine'); aCssClassesToAddRight.push('sapMITBArrowScrollRightInLine'); } if (sName === "left") { if (!this._oArrowLeft) { this._oArrowLeft = ImageHelper.getImageControl(this.getId() + "-arrowScrollLeft", this._oArrowLeft, this, mProperties, aCssClassesToAddLeft); } return this._oArrowLeft; } if (sName === "right") { if (!this._oArrowRight) { this._oArrowRight = ImageHelper.getImageControl(this.getId() + "-arrowScrollRight", this._oArrowRight, this, mProperties, aCssClassesToAddRight); } return this._oArrowRight; } }; /** * Changes the state of the scroll arrows depending on whether they are required due to overflow. * @private */ IconTabHeader.prototype._checkOverflow = function() { var oBarHead = this.getDomRef("head"); var $bar = this.$(); if (this._checkScrolling(oBarHead) && oBarHead) { // check whether scrolling to the left is possible var bScrollBack = false; var bScrollForward = false; var domScrollCont = this.getDomRef("scrollContainer"); var domHead = this.getDomRef("head"); if (this._oScroller.getScrollLeft() > 0) { bScrollBack = true; } if ((this._oScroller.getScrollLeft() + domScrollCont.offsetWidth) < domHead.offsetWidth) { bScrollForward = true; } // only do DOM changes if the state changed to avoid periodic application of identical values if ((bScrollForward != this._bPreviousScrollForward) || (bScrollBack != this._bPreviousScrollBack)) { this._bPreviousScrollForward = bScrollForward; this._bPreviousScrollBack = bScrollBack; $bar.toggleClass("sapMITBScrollBack", bScrollBack); $bar.toggleClass("sapMITBNoScrollBack", !bScrollBack); $bar.toggleClass("sapMITBScrollForward", bScrollForward); $bar.toggleClass("sapMITBNoScrollForward", !bScrollForward); } } else { this._bPreviousScrollForward = false; this._bPreviousScrollBack = false; } }; /** * Handles the activation of the tabs and arrows. * @private */ IconTabHeader.prototype._handleActivation = function(oEvent) { var sTargetId = oEvent.target.id, oControl = oEvent.srcControl, sControlId, $target = jQuery(oEvent.target); if (oControl instanceof Button) { return; } var $sTargetId = jQuery(document.getElementById(sTargetId)); /*eslint-disable no-empty */ // TODO check better implementation if ($sTargetId.parents() && Array.prototype.indexOf.call($sTargetId.parents(), this.$("content")[0]) > -1) { /*eslint-enable no-empty */ //do nothing because element is inside content } else { if (sTargetId) { var sId = this.getId(); // For items: do not navigate away! Stay on the page and handle the click in-place. Right-click + "Open in new Tab" still works. // For scroll buttons: Prevent IE from firing beforeunload event -> see CSN 4378288 2012// TODO remove after 1.62 version oEvent.preventDefault(); //on mobile devices click on arrows has no effect if (sTargetId == sId + "-arrowScrollLeft" && Device.system.desktop) { var iScrollLeft = this._oScroller.getScrollLeft() - IconTabHeader.SCROLL_STEP; if (iScrollLeft < 0) { iScrollLeft = 0; } // execute manual scrolling with iScroll's scrollTo method (delayedCall 0 is needed for positioning glitch) this._scrollPreparation(); setTimeout(this._oScroller["scrollTo"].bind(this._oScroller, iScrollLeft, 0, 500), 0); setTimeout(this["_afterIscroll"].bind(this), 500); } else if (sTargetId == sId + "-arrowScrollRight" && Device.system.desktop) { var iScrollLeft = this._oScroller.getScrollLeft() + IconTabHeader.SCROLL_STEP; var iContainerWidth = this.$("scrollContainer").width(); var iHeadWidth = this.$("head").width(); if (iScrollLeft > (iHeadWidth - iContainerWidth)) { iScrollLeft = iHeadWidth - iContainerWidth; } // execute manual scrolling with iScroll's scrollTo method (delayedCall 0 is needed for positioning glitch) this._scrollPreparation(); setTimeout(this._oScroller["scrollTo"].bind(this._oScroller, iScrollLeft, 0, 500), 0); setTimeout(this["_afterIscroll"].bind(this), 500); } else { // should be one of the items - select it if ($target.hasClass('sapMITBFilterIcon') || $target.hasClass('sapMITBCount') || $target.hasClass('sapMITBText') || $target.hasClass('sapMITBTab') || $target.hasClass('sapMITBContentArrow') || $target.hasClass('sapMITBSep') || $target.hasClass('sapMITBSepIcon')) { // click on icon: fetch filter instead sControlId = oEvent.srcControl.getId().replace(/-icon$/, ""); oControl = sap.ui.getCore().byId(sControlId); if (oControl.getMetadata().isInstanceOf("sap.m.IconTab") && !(oControl instanceof sap.m.IconTabSeparator)) { this.setSelectedItem(oControl); } } else if (oControl.getMetadata().isInstanceOf("sap.m.IconTab") && !(oControl instanceof sap.m.IconTabSeparator)) { // select item if it is an iconTab but not a separator this.setSelectedItem(oControl); } } } else { //no target id, so we have to check if showAll is set or it's a text only item, because clicking on the number then also leads to selecting the item if (oControl.getMetadata().isInstanceOf("sap.m.IconTab") && !(oControl instanceof sap.m.IconTabSeparator)) { this.setSelectedItem(oControl); } } } }; /* * Scrolls to the item passed as parameter if it is not (fully) visible. * If the item is to the left of the viewport it will be put leftmost. * If the item is to the right of the viewport it will be put rightmost. * @param {sap.m.IconTabFilter} oItem The item to be scrolled into view * @param {int} iDuration The duration of the animation effect * @private * @return {sap.m.IconTabHeader} this pointer for chaining */ IconTabHeader.prototype._scrollIntoView = function(oItem, iDuration) { var $item = oItem.$(), iScrollLeft, iNewScrollLeft, iContainerWidth; if ($item.length > 0) { var $head = this.$('head'); var iHeadPaddingWidth = $head.innerWidth() - $head.width(); var iItemWidth = $item.outerWidth(true); var iItemPosLeft = $item.position().left - iHeadPaddingWidth / 2; iScrollLeft = this._oScroller.getScrollLeft(); iContainerWidth = this.$("scrollContainer").width(); iNewScrollLeft = 0; // check if item is outside of viewport if (iItemPosLeft - iScrollLeft < 0 || iItemPosLeft - iScrollLeft > iContainerWidth - iItemWidth) { if (iItemPosLeft - iScrollLeft < 0) { // left side: make this the first item iNewScrollLeft += iItemPosLeft; } else { // right side: make this the last item iNewScrollLeft += Math.min(iItemPosLeft, iItemPosLeft + iItemWidth - iContainerWidth); iNewScrollLeft = Math.round(iNewScrollLeft); } // execute manual scrolling with scrollTo method (delayedCall 0 is needed for positioning glitch) this._scrollPreparation(); // store current scroll state to set it after rerendering this._iCurrentScrollLeft = iNewScrollLeft; setTimeout(this._oScroller["scrollTo"].bind(this._oScroller, iNewScrollLeft, 0, iDuration), 0); setTimeout(this["_afterIscroll"].bind(this), iDuration); } } return this; }; /* * Scrolls the items if possible, using an animation. * * @param {int} iDelta How far to scroll * @param {int} iDuration How long to scroll (ms) * @private */ IconTabHeader.prototype._scroll = function(iDelta, iDuration) { this._scrollPreparation(); var oDomRef = this.getDomRef("head"); var iScrollLeft = oDomRef.scrollLeft; var bIsIE = Device.browser.msie || Device.browser.edge;// TODO remove after 1.62 version if (!bIsIE && this._bRtl) {// TODO remove after 1.62 version iDelta = -iDelta; } // RTL lives in the negative space var iScrollTarget = iScrollLeft + iDelta; jQuery(oDomRef).stop(true, true).animate({scrollLeft: iScrollTarget}, iDuration, jQuery.proxy(this._adjustAndShowArrow, this)); this._iCurrentScrollLeft = iScrollTarget; }; /** * Adjusts the arrow position and displays the arrow. * @private */ IconTabHeader.prototype._adjustAndShowArrow = function() { this._$bar && this._$bar.toggleClass("sapMITBScrolling", false); this._$bar = null; //update the arrows on desktop if (Device.system.desktop) { this._checkOverflow(); } }; /** * Scroll preparation. * @private */ IconTabHeader.prototype._scrollPreparation = function() { if (!this._$bar) { this._$bar = this.$().toggleClass("sapMITBScrolling", true); } }; /** * After iscroll. * @private */ IconTabHeader.prototype._afterIscroll = function() { this._checkOverflow(); this._adjustAndShowArrow(); this._setTabsVisibility(); }; /** * Resize handling. * @private */ IconTabHeader.prototype._fnResize = function() { this._checkOverflow(); if (this.oSelectedItem && this._bCheckIfIntoView) { this._scrollIntoView(this.oSelectedItem, 0); if (!this._isTouchScrollingDisabled) { this._bCheckIfIntoView = false; } } this._setTabsVisibility(); }; /** * Sets tabs visibility when touch scrolling is disabled * @private */ IconTabHeader.prototype._setTabsVisibility = function() { if (!this._isTouchScrollingDisabled) { return; } var aTabs = this.getItems(), oTab, $tab, bHasVisibleItem, i; for (i = 0; i < aTabs.length; i++) { oTab = aTabs[i]; $tab = oTab.$(); if (!$tab.hasClass('sapMITBSelected') && !this._isTabIntoView($tab)) { $tab.addClass('sapMITBFilterHidden'); } else { bHasVisibleItem = true; $tab.removeClass('sapMITBFilterHidden'); } } if (!bHasVisibleItem) { for (i = 0; i < aTabs.length; i++) { oTab = aTabs[i]; $tab = oTab.$(); if (this._isTabIntoView($tab, true)) { $tab.removeClass('sapMITBFilterHidden'); break; } } } this._moveVisibleTabs(); }; /** * Returns if the tab is into the view area * @private */ IconTabHeader.prototype._isTabIntoView = function($tab, skipRightSide) { if (!$tab.length) { return false; } var iScrollLeft = this._oScroller.getScrollLeft(), iContainerWidth = this.$("scrollContainer").width(), $head = this.$('head'), iHeadPaddingWidth = $head.innerWidth() - $head.width(), leftMargin = $tab.css('padding-left'), iItemWidth = $tab.width() + parseFloat(leftMargin), iItemPosLeft = Math.ceil($tab.position().left - iHeadPaddingWidth / 2); if (iItemPosLeft - iScrollLeft < 0 || (!skipRightSide && (iItemPosLeft + iItemWidth - iScrollLeft > iContainerWidth))) { return false; } return true; }; /** * Moves visible tabs * @private */ IconTabHeader.prototype._moveVisibleTabs = function() { if (!this._oScroller) { return; } var iScrollLeft = this._oScroller.getScrollLeft(), $head = this.$('head'), iHeadPaddingWidth = $head.innerWidth() - $head.width(), $tab = this.$().find('.sapMITBFilter:not(.sapMITBFilterHidden)').first(), idx, iItemPosLeft; if (!$tab.length) { return; } iItemPosLeft = $tab.position().left - iHeadPaddingWidth / 2; if (!this._bRtl && iItemPosLeft - iScrollLeft > 2) { idx = iScrollLeft - iItemPosLeft; $head.css('transform', 'translate(' + idx + 'px)'); } else { $head.css('transform', ''); } return true; }; /** * @overwrite */ //overwritten method, returns for most cases the iconDomRef, if the given tab has no icon, the textDomRef is returned. IconTabHeader.prototype.getFocusDomRef = function (oFocusTab) { var oTab = oFocusTab || this.oSelectedItem; if (!oTab) { return null; } return oTab.getDomRef(); }; IconTabHeader.prototype.applyFocusInfo = function (oFocusInfo) { //sets the focus depending on the used IconTabFilter if (oFocusInfo.focusDomRef) { jQuery(oFocusInfo.focusDomRef).focus(); } }; /* =========================================================== */ /* begin: event handlers */ /* =========================================================== */ /** * Initializes scrolling on the IconTabHeader. * * @param {jQuery.Event} oEvent * @private */ IconTabHeader.prototype.ontouchstart = function(oEvent) { var oTargetTouch = oEvent.targetTouches[0]; // store & init touch state this._iActiveTouch = oTargetTouch.identifier; this._iTouchStartPageX = oTargetTouch.pageX; this._iTouchStartPageY = oTargetTouch.pageY; this._iTouchDragX = 0; this._iTouchDragY = 0; var $target = jQuery(oEvent.target); // prevent text selecting when click on the scrolling arrows if ($target.hasClass('sapMITBArrowScroll')) { oEvent.preventDefault(); } }; /** * Sets an internal flag if horizontal drag was executed. * * @param {jQuery.Event} oEvent * @private */ IconTabHeader.prototype.ontouchmove = function(oEvent) { if (this._iActiveTouch === undefined) { return; } var oTouch = touch.find(oEvent.changedTouches, this._iActiveTouch); // check for valid changes if (!oTouch || oTouch.pageX === this._iTouchStartPageX) { return; } // sum up movement to determine in touchend event if selection should be executed this._iTouchDragX += Math.abs(this._iTouchStartPageX - oTouch.pageX); this._iTouchDragY += Math.abs(this._iTouchStartPageY - oTouch.pageY); this._iTouchStartPageX = oTouch.pageX; this._iTouchStartPageY = oTouch.pageY; }; /** * Handles touch end and events and triggers selection if bar was not dragged. * * @param {jQuery.Event} oEvent * @private */ IconTabHeader.prototype.ontouchend = function(oEvent) { if (this._iActiveTouch === undefined) { return; } // suppress selection if there ware a drag (moved more than 5px on desktop or 20px on others) var iMaxMove = Device.system.desktop ? 5 : 15; if ((this._scrollable && this._iTouchDragX > iMaxMove) || this._iTouchDragY > iMaxMove) { return; } var MOBILE_TAP = 0; var LEFT_MOUSE_CLICK = 1; var LUMIA_TOUCH; // undefined on Lumia phone if (oEvent.which === LUMIA_TOUCH || oEvent.which === MOBILE_TAP || oEvent.which === LEFT_MOUSE_CLICK) { this._handleActivation(oEvent); } this._iActiveTouch = undefined; }; /** * Handles the touch cancel event. * * @param {jQuery.Event} oEvent The event object * @private */ IconTabHeader.prototype.ontouchcancel = IconTabHeader.prototype.ontouchend; /** * Fires keyboard navigation event when the user presses Enter or Space. * * @param {jQuery.Event} oEvent * @private */ IconTabHeader.prototype.onsapselect = function(oEvent) { this._handleActivation(oEvent); }; /* =========================================================== */ /* end: event handlers */ /* =========================================================== */ /* =========================================================== */ /* start: tab drag-drop */ /* =========================================================== */ /** * Handles drop event for drag & drop functionality in sap.m.IconTabHeader * @param {jQuery.Event} oEvent * @private */ IconTabHeader.prototype._handleDragAndDrop = function (oEvent) { var sDropPosition = oEvent.getParameter("dropPosition"), oDraggedControl = oEvent.getParameter("draggedControl"), oDroppedControl = oEvent.getParameter("droppedControl"), isParentSelectList = oDraggedControl.getParent().getMetadata().getName() === "sap.m.IconTabBarSelectList"; //drag and drop is between overflow list and header if (isParentSelectList) { this._handleDragAndDropBetweenHeaderAndList(sDropPosition, oDroppedControl, oDraggedControl); } else { IconTabBarDragAndDropUtil.handleDrop(this, sDropPosition, oDraggedControl, oDroppedControl, false); } this._initItemNavigation(); oDraggedControl.$().focus(); }; /** * Handles drop event for drag & drop between sap.m.IconTabHeader and sap.m.IconTabBarSelectList. * @param {string} sDropPosition position where the control will be dropped (e.g. Before/After) * @param {object} oDraggedControl item that is dragged * @param {object} oDroppedControl item that the dragged control will be dropped on * @private */ IconTabHeader.prototype._handleDragAndDropBetweenHeaderAndList = function (sDropPosition, oDroppedControl, oDraggedControl) { var oSelectList = this._getSelectList(), oDraggedAndDroppedItemFromSelectList = IconTabBarDragAndDropUtil.getDraggedDroppedItemsFromList(oSelectList.getAggregation("items"), oDraggedControl, oDroppedControl); if (!oDraggedAndDroppedItemFromSelectList) { return; } IconTabBarDragAndDropUtil.handleDrop(this, sDropPosition, oDraggedControl._tabFilter, oDroppedControl, false); IconTabBarDragAndDropUtil.handleDrop(oSelectList, sDropPosition, oDraggedControl, oDraggedAndDroppedItemFromSelectList.oDroppedControlFromList, false); oSelectList._initItemNavigation(); }; /* =========================================================== */ /* end: tab drag-drop */ /* =========================================================== */ /* =========================================================== */ /* start: tab keyboard handling - drag-drop */ /* =========================================================== */ /** * Moves a tab by a specific key code * * @param {object} oTab The event object * @param {number} iKeyCode Key code * @private */ IconTabHeader.prototype._moveTab = function (oTab, iKeyCode) { var bResult = IconTabBarDragAndDropUtil.moveItem.call(this, oTab, iKeyCode); this._initItemNavigation(); if (bResult) { this._scrollIntoView(oTab, 0); } }; /** * Handle keyboard drag&drop * @param {jQuery.Event} oEvent * @private */ IconTabHeader.prototype.ondragrearranging = function (oEvent) { if (!this.getEnableTabReordering()) { return; } var oTab = oEvent.srcControl; this._moveTab(oTab, oEvent.keyCode); oTab.$().focus(); }; /** * Moves tab on first position * Ctrl + Home * @param {jQuery.Event} oEvent */ IconTabHeader.prototype.onsaphomemodifiers = IconTabHeader.prototype.ondragrearranging; /** * Move focused tab of IconTabHeader to last position * Ctrl + End * @param {jQuery.Event} oEvent */ IconTabHeader.prototype.onsapendmodifiers = IconTabHeader.prototype.ondragrearranging; /** * Moves tab for Drag&Drop keyboard handling * Ctrl + Left Right || Ctrl + Arrow Up * @param {jQuery.Event} oEvent */ IconTabHeader.prototype.onsapincreasemodifiers = IconTabHeader.prototype.ondragrearranging; /** * Moves tab for Drag&Drop keyboard handling * Ctrl + Left Arrow || Ctrl + Arrow Down * @param {jQuery.Event} oEvent */ IconTabHeader.prototype.onsapdecreasemodifiers = IconTabHeader.prototype.ondragrearranging; /* =========================================================== */ /* end: tab keyboard handling - drag-drop */ /* =========================================================== */ return IconTabHeader; });