%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/components/bitrix/main.interface.buttons/templates/.default/ |
Current File : /home/bitrix/www/bitrix/components/bitrix/main.interface.buttons/templates/.default/script.js |
BX.namespace('BX.Main'); if (typeof(BX.Main.interfaceButtons) === 'undefined') { /** * @param {object} params parameters * @property {string} containerId @required * @property {object} classes * @property {string} classes.item Class for list item * @property {string} classes.itemSublink Class for sublink (ex. Add link) * @property {string} classes.itemText Class for item text and submenu item text * @property {string} classes.itemCounter Class for list item counter and submenu item counter * @property {string} classes.itemIcon Class for list item icon and submenu item icon * @property {string} classes.itemMore Class for more button * @property {string} classes.itemOver Class for hovered item * @property {string} classes.itemActive Class for active item * @property {string} classes.itemDisabled Class for disabled elements * @property {string} classes.itemLocked Class for locked item. Added for list and submenu item * @property {string} classes.onDrag Class added for container on dragstart event and removed on drag end event * @property {string} classes.dropzone Class for dropzone in submenu * @property {string} classes.separator Class for submenu separator before disabled items * @property {string} classes.submenuItem Class for submenu item * @property {string} classes.submenu Class for submenu container * @property {string} classes.secret Class for hidden alias items (set display: none; for items) * @property {object} messages Messages object. Contains localization strings * @property {string} messages.MIB_DROPZONE_TEXT Dropzone text * @property {string} messages.MIB_LICENSE_BUY_BUTTON License window Buy button text * @property {string} messages.MIB_LICENSE_TRIAL_BUTTON License window Trial button text * @property {string} messages.MIB_LICENSE_WINDOW_HEADER_TEXT License window header text * @property {string} messages.MIB_LICENSE_WINDOW_TEXT License window content text * @property {string} messages.MIB_LICENSE_WINDOW_TRIAL_SUCCESS_TEXT Trial success text * @property {object} licenseWindow Settings for license window * @property {string} licenseWindow.isFullDemoExists Y|N * @property {string} licenseWindow.hostname Hostname for license window ajax calls * @property {string} licenseWindow.ajaxUrl Ajax handler url * @property {string} licenseWindow.licenseAllPath * @property {string} licenseWindow.licenseDemoPath * @property {string} licenseWindow.featureGroupName * @property {string} licenseWindow.ajaxActionsUrl * @param {HTMLElement} container */ BX.Main.interfaceButtons = function(container, params) { /** * Sets default values */ this.classItem = 'main-buttons-item'; this.classItemSublink = 'main-buttons-item-sublink'; this.classItemText = 'main-buttons-item-text'; this.classItemCounter = 'main-buttons-item-counter'; this.classItemIcon = 'main-buttons-item-icon'; this.classItemMore = 'main-buttons-item-more'; this.classOnDrag = 'main-buttons-drag'; this.classDropzone = 'main-buttons-submenu-dropzone'; this.classSeporator = 'main-buttons-submenu-separator'; this.classHiddenLabel = 'main-buttons-hidden-label'; this.classSubmenuItem = 'main-buttons-submenu-item'; this.classItemDisabled = 'main-buttons-disabled'; this.classItemOver = 'over'; this.classItemActive = 'main-buttons-item-active'; this.classSubmenu = 'main-buttons-submenu'; this.classSecret = 'secret'; this.classItemLocked = 'locked'; this.submenuIdPrefix = 'main_buttons_popup_'; this.childMenuIdPrefix = 'main_buttons_popup_child_'; this.submenuWindowIdPrefix = 'menu-popup-'; this.classSettingMenuItem = 'main-buttons-submenu-setting'; this.classEditState = 'main-buttons-edit'; this.classEditItemButton = 'main-buttons-item-edit-button'; this.classDragItemButton = 'main-buttons-item-drag-button'; this.classSettingsApplyButton = 'main-buttons-submenu-settings-apply'; this.classSettingsResetButton = 'main-buttons-submenu-settings-reset'; this.classSetHome = 'main-buttons-set-home'; this.classSetHide = 'main-buttons-set-hide'; this.classManage = 'main-buttons-manage'; this.classContainer = 'main-buttons'; this.classSubmenuNoHiddenItem = 'main-buttons-submenu-item-no-hidden'; this.classDefaultSubmenuItem = 'menu-popup-item'; this.classInner = 'main-buttons-inner-container'; this.listContainer = null; this.pinContainer = null; this.dragItem = null; this.overItem = null; this.moreButton = null; this.messages = null; this.licenseParams = null; this.isSubmenuShown = false; this.isSubmenuShownOnDragStart = false; this.isSettingsEnabled = true; this.containerId = params.containerId; this.tmp = {}; this.init(container, params); /** * Public methods and properties */ return { getItemById: BX.delegate(this.getItemById, this), getAllItems: BX.delegate(this.getAllItems, this), getHiddenItems: BX.delegate(this.getHiddenItems, this), getVisibleItems: BX.delegate(this.getVisibleItems, this), getDisabledItems: BX.delegate(this.getDisabledItems, this), getMoreButton: BX.delegate(this.getMoreButton, this), adjustMoreButtonPosition: BX.delegate(this.adjustMoreButtonPosition, this), showSubmenu: BX.delegate(this.showSubmenu, this), closeSubmenu: BX.delegate(this.closeSubmenu, this), refreshSubmenu: BX.delegate(this.refreshSubmenu, this), getCurrentSettings: BX.delegate(this.getCurrentSettings, this), saveSettings: BX.delegate(this.saveSettings, this), setCounterValueByItemId: BX.delegate(this.setCounterValueByItemId, this), getCounterValueByItemId: BX.delegate(this.getCounterValueByItemId, this), updateCounter: BX.delegate(this.updateCounter, this), getActive: BX.delegate(this.getActive, this), isEditEnabled: BX.delegate(this.isEditEnabled, this), isActiveInMoreMenu: BX.delegate(this.isActiveInMoreMenu, this), isSettingsEnabled: this.isSettingsEnabled, classes: { item: this.classItem, itemText: this.classItemText, itemCounter: this.classItemCounter, itemIcon: this.classItemIcon, itemDisabled: this.classItemDisabled, itemOver: this.classItemOver, itemActive: this.classItemActive, itemLocked: this.classItemLocked, submenu: this.classSubmenu, submenuItem: this.classSubmenuItem, containerOnDrag: this.classOnDrag, classSettingMenuItem: this.classSettingMenuItem }, itemsContainer: this.listContainer, itemsContainerId: this.listContainer.id }; }; //noinspection JSUnusedGlobalSymbols,JSUnusedGlobalSymbols BX.Main.interfaceButtons.prototype = { init: function(container, params) { this.listContainer = BX(this.getId()); if (!BX.type.isPlainObject(params)) { throw 'BX.MainButtons: params is not Object'; } if (!('containerId' in params) || !BX.type.isNotEmptyString(params.containerId)) { throw 'BX.MainButtons: containerId not set in params'; } if (!BX.type.isDomNode(this.listContainer)) { throw 'BX.MainButtons: #' + params.containerId + ' is not dom node'; } if (('classes' in params) && BX.type.isPlainObject(params.classes)) { this.setCustomClasses(params.classes); } if (('messages' in params) && BX.type.isPlainObject(params.messages)) { this.setMessages(params.messages); } if (('licenseWindow' in params) && BX.type.isPlainObject(params.licenseWindow)) { this.setLicenseWindowParams(params.licenseWindow); } if ('disableSettings' in params && params.disableSettings === "true") { this.isSettingsEnabled = false; this.visibleControlMoreButton(); } this.moreButton = this.getMoreButton(); this.listChildItems = {}; if (this.isSettingsEnabled) { this.dragAndDropInit(); } this.adjustMoreButtonPosition(); this.bindOnClickOnMoreButton(); this.bindOnScrollWindow(); this.setContainerHeight(); BX.bind(this.getContainer(), 'click', BX.delegate(this._onDocumentClick, this)); BX.addCustomEvent("onPullEvent-main", BX.delegate(this._onPush, this)); this.updateMoreButtonCounter(); if (this.isActiveInMoreMenu()) { this.activateItem(this.moreButton); } var visibleItems = this.getVisibleItems(); var firstVisibleItem = BX.type.isArray(visibleItems) && visibleItems.length > 0 ? visibleItems[0] : null; var firstItemNode = BX.Buttons.Utils.getByTag(firstVisibleItem, 'a'); if (!BX.type.isDomNode(firstItemNode)) { return; } var firstPageLink = firstItemNode.getAttribute("href"); if (firstPageLink.charAt(0) === "?") { firstPageLink = firstItemNode.pathname + firstItemNode.search; } if (!this.lastHomeLink) { this.lastHomeLink = firstPageLink; } this.bindOnResizeFrame(); }, _onDocumentClick: function(event) { var item = this.getItem(event); var dataOnClick, currentItem, currentAlias, id, visibleItems, visibleItemsLength; if (this.isDragButton(event.target)) { event.preventDefault(); event.stopPropagation(); } if (BX.type.isDomNode(item)) { if (this.isSettings(item)) { this.enableEdit(); BX.hide(this.getSettingsButton()); BX.show(this.getSettingsApplyButton()); return false; } if (this.isApplySettingsButton(item)) { event.preventDefault(); event.stopPropagation(); this.disableEdit(); BX.show(this.getSettingsButton()); BX.hide(this.getSettingsApplyButton()); return false; } if (this.isResetSettingsButton(item)) { this.resetSettings(); return false; } if (this.isLocked(item)) { event.preventDefault(); this.showLicenseWindow(); return false; } if (this.isEditButton(event.target)) { var dataItem, menu; event.preventDefault(); event.stopPropagation(); if (this.isSubmenuItem(item)) { item = this.getItemAlias(item); } try { dataItem = JSON.parse(BX.data(item, 'item')); } catch (err) {} menu = this.getItemEditMenu(); if (menu && menu.popupWindow.isShown() && this.lastEditNode === item) { menu.popupWindow.close(); } else { this.showItemEditMenu(dataItem, event.target); } this.lastEditNode = item; return false; } if (this.isSetHide(item)) { visibleItems = this.getVisibleItems(); visibleItemsLength = BX.type.isArray(visibleItems) ? visibleItems.length : null; id = this.editItemData.ID.replace(this.listContainer.id + '_', ''); currentItem = this.getItemById(id); currentAlias = this.getItemAlias(currentItem); currentItem = this.isVisibleItem(currentItem) ? currentItem : currentAlias; if (this.isDisabled(currentAlias)) { this.enableItem(currentAlias); } else if (!this.isDisabled(currentAlias) && visibleItemsLength > 2) { this.disableItem(currentAlias); } if (visibleItemsLength === 2) { BX.onCustomEvent(window, 'BX.Main.InterfaceButtons:onHideLastVisibleItem', [currentItem, this]); } this.refreshSubmenu(); this.saveSettings(); this.adjustMoreButtonPosition(); if (this.isEditEnabled()) { this.enableEdit(); BX.hide(this.getSettingsButton()); BX.show(this.getSettingsApplyButton()); } this.editMenu.popupWindow.close(); return false; } if (this.isSetHome(item)) { id = this.editItemData.ID.replace(this.listContainer.id + '_', ''); currentItem = this.getItemById(id); currentAlias = this.getItemAlias(currentItem); if (this.isDisabled(currentAlias)) { this.enableItem(currentAlias); } this.listContainer.insertBefore(currentItem, BX.firstChild(this.listContainer)); this.adjustMoreButtonPosition(); this.refreshSubmenu(); this.saveSettings(); if (this.isEditEnabled()) { this.enableEdit(); BX.hide(this.getSettingsButton()); BX.show(this.getSettingsApplyButton()); } this.editMenu.popupWindow.close(); return false; } if (!this.isSublink(event.target)) { dataOnClick = this.dataValue(item, 'onclick'); if (BX.type.isNotEmptyString(dataOnClick)) { event.preventDefault(); this.execScript(dataOnClick); } } } if (this.isEditEnabled()) { //noinspection JSCheckFunctionSignatures this.getSubmenu().popupWindow.setAutoHide(false); } }, /** * @return {boolean} */ isActiveInMoreMenu: function() { var hiddenItems = this.getHiddenItems(); var disabledItems = this.getDisabledItems(); var items = hiddenItems.concat(disabledItems); return items.some(function(current) { var data; try { /** * @property data.IS_ACTIVE */ data = JSON.parse(BX.data(current, 'item')); } catch (err) {} return BX.type.isPlainObject(data) && ('IS_ACTIVE' in data && data.IS_ACTIVE === true || data.IS_ACTIVE === 'true' || data.IS_ACTIVE === 'Y'); }, this); }, _onPush: function (command, params) { if (command === "user_counter" && params && BX.message("SITE_ID") in params) { var counters = params[BX.message("SITE_ID")]; for (var counterId in counters) { if (counters.hasOwnProperty(counterId)) { this.updateCounter(counterId, counters[counterId]); } } } }, bindOnScrollWindow: function() { BX.bind(window, 'scroll', BX.delegate(this._onScroll, this)); }, /** * Gets active element * @return {?HTMLElement} */ getActive: function() { var items = this.getAllItems(); var tmpData, node; var result = null; if (BX.type.isArray(items)) { items.forEach(function(current) { try { tmpData = JSON.parse(BX.data(current, 'item')); } catch(err) { tmpData = null; } if (BX.type.isPlainObject(tmpData) && 'IS_ACTIVE' in tmpData && (tmpData.IS_ACTIVE === true || tmpData.IS_ACTIVE === 'true' || tmpData.IS_ACTIVE === 'Y')) { result = tmpData; } }, this); } if (BX.type.isPlainObject(result)) { node = BX(result.ID); if (BX.type.isDomNode(node)) { result.NODE = node; } else { result.NODE = null; } } return result; }, /** * @param {HTMLElement} item * @return {boolean} */ isSetHome: function(item) { return BX.hasClass(item, this.classSetHome); }, /** * @param {HTMLElement} item * @return {boolean} */ isSetHide: function(item) { return BX.hasClass(item, this.classSetHide); }, /** * @return {?HTMLElement} */ getSettingsButton: function() { return BX.Buttons.Utils.getByClass(this.getSubmenuContainer(), this.classSettingMenuItem); }, /** * @return {?HTMLElement} */ getSettingsApplyButton: function() { return BX.Buttons.Utils.getByClass(this.getSubmenuContainer(), this.classSettingsApplyButton); }, /** * @param {HTMLElement} item * @return {boolean} */ isApplySettingsButton: function(item) { return BX.hasClass(item, this.classSettingsApplyButton); }, enableEdit: function() { var submenu = this.getSubmenu(); if (submenu && 'popupWindow' in submenu) { //noinspection JSCheckFunctionSignatures submenu.popupWindow.setAutoHide(false); } BX.addClass(this.listContainer, this.classEditState); BX.addClass(this.getSubmenuContainer(), this.classEditState); this.isEditEnabledState = true; }, disableEdit: function() { var menu = this.getSubmenu(); if (menu && 'popupWindow' in menu) { //noinspection JSCheckFunctionSignatures menu.popupWindow.setAutoHide(true); } BX.removeClass(this.listContainer, this.classEditState); BX.removeClass(this.getSubmenuContainer(), this.classEditState); this.isEditEnabledState = false; }, /** * @return {boolean} */ isEditEnabled: function() { return this.isEditEnabledState; }, /** * @param {object} dataItem * @param {HTMLElement} node */ showItemEditMenu: function(dataItem, node) { if (BX.type.isPlainObject(dataItem) && 'ID' in dataItem) { var menuId = [this.listContainer.id, '_edit_item'].join(''); var menu = BX.PopupMenu.getMenuById(menuId); if (menu) { BX.PopupMenu.destroy(menuId); } menu = this.createItemEditMenu(dataItem, menuId, node); menu.popupWindow.show(); } }, /** * @return {?HTMLElement} */ getContainer: function() { if (!BX.type.isDomNode(this.container)) { this.container = BX(this.containerId).parentNode; } return this.container; }, /** * @return {?BX.PopupMenu} */ getItemEditMenu: function() { return BX.PopupMenu.getMenuById([this.listContainer.id, '_edit_item'].join('')); }, /** * @param {object} dataItem * @param {string} menuId * @param {HTMLElement} node BX.PopupMenu bindElement * @return {?BX.PopupMenu} */ createItemEditMenu: function(dataItem, menuId, node) { var menu; var menuItems = [ { text: this.message('MIB_SET_HOME'), className: 'main-buttons-set-home menu-popup-no-icon' } ]; var id = dataItem.ID.replace(this.listContainer.id + '_', ''); var currentItem = this.getItemById(id); if (this.isDisabled(currentItem)) { menuItems.push({ text: this.message('MIB_SET_SHOW'), className: 'main-buttons-set-hide menu-popup-no-icon' }); } else { menuItems.push({ text: this.message('MIB_SET_HIDE'), className: 'main-buttons-set-hide menu-popup-no-icon' }); } var nodeRect = BX.pos(node); var menuParams = { menuId: menuId, anchor: node, menuItems: menuItems, settings: { 'autoHide': true, 'offsetTop': 0, 'offsetLeft': (nodeRect.width / 2), 'zIndex': 20, 'angle': { 'position': 'top', 'offset': (nodeRect.width / 2) } } }; menu = BX.PopupMenu.create( menuParams.menuId, menuParams.anchor, menuParams.menuItems, menuParams.settings ); if (this.isVisibleItem(currentItem)) { dataItem.NODE = currentItem; } else { dataItem.NODE = this.getItemAlias(currentItem); } this.editItemData = dataItem; if ('menuItems' in menu && BX.type.isArray(menu.menuItems)) { menu.menuItems.forEach(function(current) { BX.bind(current.layout.item, 'click', BX.delegate(this._onDocumentClick, this)); }, this); } BX.onCustomEvent(window, 'BX.Main.InterfaceButtons:onBeforeCreateEditMenu', [menu, dataItem, this]); this.editMenu = menu; return menu; }, setHome: function() { var visibleItems = this.getVisibleItems(); var firstVisibleItem = BX.type.isArray(visibleItems) && visibleItems.length > 0 ? visibleItems[0] : null; var firstItemNode = BX.Buttons.Utils.getByTag(firstVisibleItem, 'a'); if (!BX.type.isDomNode(firstItemNode)) { return; } var firstPageLink = firstItemNode.getAttribute('href'); if (firstPageLink.charAt(0) === '?') { firstPageLink = firstItemNode.pathname + firstItemNode.search; } if (!this.lastHomeLink) { this.lastHomeLink = firstPageLink; } if (this.lastHomeLink !== firstPageLink) { BX.userOptions.save('ui', this.listContainer.id, 'firstPageLink', firstPageLink); BX.onCustomEvent('BX.Main.InterfaceButtons:onFirstItemChange', [firstPageLink, firstVisibleItem]); } this.lastHomeLink = firstPageLink; }, /** * @param {HTMLElement} item * @return {boolean} */ isEditButton: function(item) { return BX.hasClass(item, this.classEditItemButton); }, /** * @param {HTMLElement} item * @return {boolean} */ isDragButton: function(item) { return BX.hasClass(item, this.classDragItemButton); }, /** * @param {HTMLElement} item * @return {boolean} */ isResetSettingsButton: function(item) { return BX.hasClass(item, this.classSettingsResetButton); }, /** * Calculate container height * @return {number} Container height in pixels */ getContainerHeight: function() { var heights = this.getAllItems().map(function(current) { var currentStyle = getComputedStyle(current); return ( BX.height(current) + parseInt(currentStyle.marginTop) + parseInt(currentStyle.marginBottom) ); }); return Math.max.apply(Math, heights); }, /** * Sets container height */ setContainerHeight: function() { var containerHeight = this.getContainerHeight(); var itemMarginBottom = 8; BX.height(this.listContainer, containerHeight-itemMarginBottom); }, /** * Sets license window params in this.licenseParams * @param {object} params Params object */ setLicenseWindowParams: function(params) { this.licenseParams = params || {}; }, /** * Gets message by id * @method message * @private * @param {string} messageId * @return {string} */ message: function(messageId) { var result; try { result = this.messages[messageId]; } catch (error) { result = ''; } return result; }, /** * Sets custom classes * @param {object} classes * @return {undefined} */ setCustomClasses: function(classes) { if (!BX.type.isPlainObject(classes)) { return; } this.classItem = (classes.item || this.classItem); this.classItemSublink = (classes.itemSublink || this.classItemSublink); this.classItemText = (classes.itemText || this.classItemText); this.classItemCounter = (classes.itemCounter || this.classItemCounter); this.classItemIcon = (classes.itemIcon || this.classItemIcon); this.classItemMore = (classes.itemMore || this.classItemMore); this.classItemOver = (classes.itemOver || this.classItemOver); this.classItemActive = (classes.itemActive || this.classItemActive); this.classItemDisabled = (classes.itemDisabled || this.classItemDisabled); this.classOnDrag = (classes.onDrag || this.classOnDrag); this.classDropzone = (classes.dropzone || this.classDropzone); this.classSeporator = (classes.separator || this.classSeporator); this.classSubmenuItem = (classes.submenuItem || this.classSubmenuItem); this.classSubmenu = (classes.submenu || this.classSubmenu); this.classSecret = (classes.secret || this.classSecret); this.classItemLocked = (classes.itemLocked || this.classItemLocked); }, /** * Sets messages * @param {object} messages Messages object */ setMessages: function(messages) { if (!BX.type.isPlainObject(messages)) { return; } this.messages = messages; }, /** * Makes full item id * @private * @method makeFullItemId * @param {string} itemId * @return {*} */ makeFullItemId: function(itemId) { if (!BX.type.isNotEmptyString(itemId)) { return; } return [this.listContainer.id, itemId.replace('-', '_')].join('_'); }, /** * Gets listContainer child by id * @public * @method getItemById * @param {string} itemId * @return {object} dom node */ getItemById: function(itemId) { var resultItem = null; var realId; if (BX.type.isNotEmptyString(itemId)) { realId = this.makeFullItemId(itemId); resultItem = BX.Buttons.Utils.getBySelector(this.listContainer, '#'+realId); } return resultItem; }, /** * Finds counter object * @private * @method getItemCounterObject * @param {HTMLElement} item * @return {?HTMLElement} Counter dom node */ getItemCounterObject: function(item) { var result = null; if (BX.type.isDomNode(item)) { result = BX.Buttons.Utils.getByClass(item, this.classItemCounter); } return result; }, /** * Sets item counter value * @private * @param {HTMLElement} item * @param {Number|null} value */ setCounterValue: function(item, value) { var counter = this.getItemCounterObject(item); if (BX.type.isDomNode(counter)) { counter.innerText = value > 99 ? '99+' : (value > 0 ? value : ''); item.dataset.counter = value; } this.updateMoreButtonCounter(); }, /** * Updates menu item counter * @param {string} id - menu item id * @param {*} value - counter value */ updateCounter: function(id, value) { if(id.indexOf("crm") === 0 && value < 0) { //HACK: Skip of CRM counter reset return; } var counter, data, alias; var item = null; var items = this.getAllItems(); if (BX.type.isArray(items)) { items.forEach(function(current) { try { /** * @property data.COUNTER_ID */ data = JSON.parse(BX.data(current, 'item')); } catch (err) { data = {}; } if (BX.type.isPlainObject(data) && 'COUNTER_ID' in data && data.COUNTER_ID === id) { item = current; } }, this); } counter = this.getItemCounterObject(item); if (BX.type.isDomNode(counter)) { item = this.getItem(counter); counter.innerText = value > 99 ? '99+' : (value > 0 ? value : ''); item.dataset.counter = value; } alias = this.getItemAlias(item); if (BX.type.isDomNode(alias)) { counter = this.getItemCounterObject(alias); if (BX.type.isDomNode(counter)) { counter.innerText = value > 99 ? '99+' : (value > 0 ? value : ''); alias.dataset.counter = value; } } this.updateMoreButtonCounter(); }, /** * Sets counter value by item id * @public * @method setCounterValueByItemId * @param {string} itemId * @param {Number} counterValue */ setCounterValueByItemId: function(itemId, counterValue) { var currentValue = counterValue !== null ? parseFloat(counterValue) : null; var currentItem, aliasItem; if (!BX.type.isNotEmptyString(itemId)) { throw 'Bad first arg. Need string as item id'; } if (currentValue !== null && !BX.type.isNumber(currentValue)) { throw 'Bad two arg. Need number counter value - Integer, Float or string with number'; } currentItem = this.getItemById(itemId); if (!BX.type.isDomNode(currentItem)) { console.info('Not found node with id #' + itemId); return; } aliasItem = this.getItemAlias(currentItem); this.setCounterValue(currentItem, currentValue); this.setCounterValue(aliasItem, currentValue); }, /** * Gets counter value by item id * @param {string} itemId * @return {number} */ getCounterValueByItemId: function(itemId) { var item, counter; var counterValue = NaN; if (!BX.type.isNotEmptyString(itemId)) { throw 'Bad first arg. Need string item id'; } else { item = this.getItemById(itemId); counterValue = this.dataValue(item, 'counter'); counterValue = parseFloat(counterValue); if (!BX.type.isNumber(counterValue)) { counter = this.getItemCounterObject(item); counterValue = parseFloat(counter.innerText); } } return counterValue; }, /** * Sets counter of more button * @param {*} value */ setMoreButtonCounter: function(value) { var counter = this.getItemCounterObject(this.moreButton); var counterValue = value > 99 ? '99+' : (value > 0 ? value : ''); counterValue = parseInt(counterValue); counterValue = BX.type.isNumber(counterValue) ? counterValue : ''; counter.innerText = counterValue; }, /** * Binds on click on more button * @method bindOnClickOnMoreButton * @private * @return {undefined} */ bindOnClickOnMoreButton: function() { BX.bind( this.moreButton, 'click', BX.delegate(this._onClickMoreButton, this) ); }, /** * Binds on tmp frame resize * @method bindOnResizeFrame * @private */ bindOnResizeFrame: function() { window.frames["maininterfacebuttonstmpframe-"+this.getId()].onresize = BX.throttle(this._onResizeHandler, 20, this); }, /** * Gets buttons list container id * @return {string} */ getId: function() { return BX.Buttons.Utils.getByClass(this.getContainer(), this.classInner).id; }, /** * Gets all items * @public * @return {HTMLElement[]} */ getAllItems: function() { return BX.Buttons.Utils.getByClass(this.listContainer, this.classItem, true); }, /** * Gets only visible items * @public * @return {HTMLElement[]} */ getVisibleItems: function() { var allItems = this.getAllItems(); var self = this; var visibleItems = []; if (allItems && allItems.length) { visibleItems = allItems.filter(function(current) { return self.isVisibleItem(current) && !self.isDisabled(current); }); } return visibleItems; }, /** * Gets only hidden items * @public * @method getHiddenItems * @return {HTMLElement[]} */ getHiddenItems: function() { var allItems = this.getAllItems(); var hiddenItems = []; var self = this; if (allItems && allItems.length) { hiddenItems = allItems.filter(function(current) { return !self.isVisibleItem(current) && !self.isDisabled(current); }); } return hiddenItems; }, /** * Gets only disabled items, * as showed after separator in popup menu * @public * @method getDisabledItems * @return {HTMLElement[]} */ getDisabledItems: function() { return this.getAllItems().filter(function(current) { return this.isDisabled(current); }, this); }, /** * Gets more button * @public * @returns {?HTMLElement} More button element */ getMoreButton: function() { var moreButton = null; this.getAllItems().forEach(function(current) { !moreButton && BX.hasClass(current, this.classItemMore) && (moreButton = current); }, this); return moreButton; }, /** * Gets last visible item * @private * @method getLastVisibleItem * @return {object} last visible item object */ getLastVisibleItem: function() { var visibleItems = this.getVisibleItems(); var lastVisibleItem = null; if (BX.type.isArray(visibleItems) && visibleItems.length) { lastVisibleItem = visibleItems[visibleItems.length - 1]; } if (!BX.type.isDomNode(lastVisibleItem)) { lastVisibleItem = null; } return lastVisibleItem; }, /** * Moves "more button" in the end of the list * @public * @method adjustMoreButtonPosition * @return {undefined} */ adjustMoreButtonPosition: function() { var lastItem = this.getLastVisibleItem(); var lastItemIsMoreButton = this.isMoreButton(lastItem); if (!lastItemIsMoreButton) { this.listContainer.insertBefore(this.moreButton, lastItem); } this.updateMoreButtonCounter(); }, /** * Gets submenu id * @private * @method getSubmenuId * @param {boolean} [isFull] Set true if your need to get id for popup window * @return {string} id */ getSubmenuId: function(isFull) { var id = ''; if (BX.type.isDomNode(this.listContainer) && BX.type.isNotEmptyString(this.listContainer.id)) { id = this.submenuIdPrefix + this.listContainer.id; } if (isFull) { id = this.submenuWindowIdPrefix + id; } return id; }, getChildMenuId: function() { var id = ''; if (BX.type.isDomNode(this.listContainer) && BX.type.isNotEmptyString(this.listContainer.id)) { id = this.childMenuIdPrefix + this.listContainer.id; } return id; }, /** * Gets submenu item content * @private * @method getSubmenuItemText * @param {HTMLElement} item * @return {?string} */ getSubmenuItemText: function(item) { var text, counter, result; if (!BX.type.isDomNode(item)) { return null; } text = this.findChildrenByClassName(item, this.classItemText); counter = this.findChildrenByClassName(item, this.classItemCounter); if (BX.type.isDomNode(counter) && BX.type.isDomNode(text)) { counter.dataset.counter = this.dataValue(item, 'counter'); result = text.outerHTML + counter.outerHTML; } else { text = this.dataValue(item, 'text'); counter = this.dataValue(item, 'counter'); result = text; } return result; }, getChildMenuItemText: function(item) { var text, counter, result; if (!BX.type.isDomNode(item)) { return null; } text = this.findChildrenByClassName(item, this.classItemText); counter = this.findChildrenByClassName(item, this.classItemCounter); if (BX.type.isDomNode(counter) && BX.type.isDomNode(text)) { counter.dataset.counter = this.dataValue(item, 'counter'); result = text.outerHTML + counter.outerHTML; } else { text = this.dataValue(item, 'text'); result = text; } return result; }, /** * @param {HTMLElement} item * @return {string} */ getLockedClass: function(item) { var result = ''; if (BX.type.isDomNode(item) && this.isLocked(item)) { result = this.classItemLocked; } return result; }, /** * Gets submenu items * @private * @method getSubmenuItems * @return {HTMLElement[]} */ getSubmenuItems: function() { var allItems = this.getAllItems(); var hiddenItems = this.getHiddenItems(); var disabledItems = this.getDisabledItems(); var result = []; var data, className; if (allItems.length) { allItems.forEach(function(current) { if (hiddenItems.indexOf(current) === -1 && disabledItems.indexOf(current) === -1) { result.push({ text: this.getSubmenuItemText(current), href: this.dataValue(current, 'url'), onclick: this.dataValue(current, 'onclick'), title: current.getAttribute('title'), className: [ this.classSubmenuItem, this.getIconClass(current), this.classSecret, this.getAliasLink(current), this.getLockedClass(current) ].join(' ') }); } }, this); } if (hiddenItems.length) { hiddenItems.forEach(function(current) { try { data = JSON.parse(this.dataValue(current, 'item')); } catch (err) { data = null; } className = [ this.classSubmenuItem, this.getIconClass(current), this.getAliasLink(current), this.getLockedClass(current) ]; if (BX.type.isPlainObject(data) && ('IS_ACTIVE' in data && data.IS_ACTIVE === true || data.IS_ACTIVE === 'true' || data.IS_ACTIVE === 'Y')) { className.push(this.classItemActive); } result.push({ text: this.getSubmenuItemText(current), href: this.dataValue(current, 'url'), onclick: this.dataValue(current, 'onclick'), title: current.getAttribute('title'), className: className.join(' '), items: this.getChildMenuItems(current) }); }, this); } if (this.isSettingsEnabled) { result.push({ text: '<span>'+this.message('MIB_HIDDEN')+'</span>', className: [ this.classSeporator, this.classSubmenuItem, this.classHiddenLabel ].join(' ') }); if (!disabledItems.length) { result.push({ text: '<span>'+this.message('MIB_NO_HIDDEN')+'</span>', className: [ this.classSubmenuItem, this.classSubmenuNoHiddenItem ].join(' ') }); } if (disabledItems.length) { disabledItems.forEach(function(current) { try { data = JSON.parse(this.dataValue(current, 'item')); } catch (err) { data = null; } className = [ this.classSubmenuItem, this.classItemDisabled, this.getIconClass(current), this.getAliasLink(current), this.getLockedClass(current) ]; if (BX.type.isPlainObject(data) && ('IS_ACTIVE' in data && data.IS_ACTIVE === true || data.IS_ACTIVE === 'true' || data.IS_ACTIVE === 'Y')) { className.push(this.classItemActive); } result.push({ text: this.getSubmenuItemText(current), href: this.dataValue(current, 'url'), onclick: this.dataValue(current, 'onclick'), title: current.getAttribute('title'), className: className.join(' '), items: this.getChildMenuItems(current) }); }, this); } result.push({ text: '<span>'+this.message('MIB_MANAGE')+'</span>', className: [ this.classSeporator, this.classSubmenuItem, this.classHiddenLabel, this.classManage ].join(' ') }); result.push({ text: this.message('MIB_SETTING_MENU_ITEM'), className: [ this.classSettingMenuItem, this.classSubmenuItem ].join(' ') }); result.push({ text: this.message('MIB_APPLY_SETTING_MENU_ITEM'), className: [ this.classSettingsApplyButton, this.classSubmenuItem ].join(' ') }); result.push({ text: this.message('MIB_RESET_SETTINGS'), className: [this.classSettingsResetButton, this.classSubmenuItem].join(' ') }); } return result; }, getChildMenuItems: function(item) { var data; try { data = JSON.parse(this.dataValue(item, 'item')); } catch (err) { data = null; } if (!BX.type.isPlainObject(data)) { return []; } if (!BX.type.isArray(this.listChildItems[item.id])) { var listAllItems = {}; this.setListAllItems(listAllItems, data); var items = this.getListItems(listAllItems, ""); if (items.length) { this.listChildItems[item.id] = (BX.type.isArray(items[0].items) ? items[0].items : []); } } return this.listChildItems[item.id]; }, setListAllItems: function(listAllItems, data) { var items = []; if (BX.type.isPlainObject(data)) { items.push(data); } else { items = data; } items.forEach(function(item) { listAllItems[item["ID"].replace(this.containerId + "_", "")] = item; if (BX.type.isArray(item["ITEMS"])) { this.setListAllItems(listAllItems, item["ITEMS"]); } }, this); }, getListItems: function(listAllItems, parentId) { var listItems = []; for (var itemId in listAllItems) { if (!listAllItems.hasOwnProperty(itemId)) { continue; } var item = listAllItems[itemId]; if (item["PARENT_ID"] === parentId) { var listChildItems, itemData = { text: item["TEXT"], href: item["URL"], onclick: item["ON_CLICK"], title: item["TITLE"] }; listChildItems = this.getListItems(listAllItems, itemId); if (listChildItems.length) { itemData.items = listChildItems; } listItems.push(itemData); delete listAllItems[itemId]; } } return listItems; }, /** * Gets BX.PopupMenu.show arguments * @private * @method getSubmenuArgs * @return {*[]} Arguments */ getSubmenuArgs: function() { var menuId = this.getSubmenuId(); var anchor = this.moreButton; var anchorPosition = BX.pos(anchor); var menuItems = this.getSubmenuItems(); var params = { 'autoHide': true, 'offsetLeft': (anchorPosition.width / 2) - 80, 'angle': { 'position': 'top', 'offset': 100 }, zIndex: 0, 'events': { 'onPopupClose': BX.delegate(this._onSubmenuClose, this) } }; return [menuId, anchor, menuItems, params]; }, getChildMenuArgs: function(item) { var menuId = this.getChildMenuId(); var menuItems = this.getChildMenuItems(item); if (!menuItems || (BX.type.isArray(menuItems) && !menuItems.length)) { return []; } var params = { autoHide: true, angle: true, offsetLeft: item.getBoundingClientRect().width/2 }; return [menuId, item, menuItems, params]; }, /** * Controls the visibility of more button */ visibleControlMoreButton: function() { var hiddenItems = this.getHiddenItems(); if (!hiddenItems.length || (hiddenItems.length === 1 && this.isMoreButton(hiddenItems[0]))) { this.getMoreButton().style.display = 'none'; } else { this.getMoreButton().style.display = ''; } }, /** * Creates submenu * @return {BX.PopupMenu} */ createSubmenu: function() { var menu = BX.PopupMenu.create.apply(BX.PopupMenu, this.getSubmenuArgs()); if (this.isSettingsEnabled) { this.dragAndDropInitInSubmenu(); } menu.menuItems.forEach(function(current) { BX.bind(current.layout.item, 'click', BX.delegate(this._onDocumentClick, this)); }, this); return menu; }, createChildMenu: function(item) { return BX.PopupMenu.create.apply(BX.PopupMenu, this.getChildMenuArgs(item)); }, /** * Shows submenu * @public * @method showSubmenu * @return {undefined} */ showSubmenu: function() { var submenu = this.getSubmenu(); if (submenu !== null) { submenu.popupWindow.show(); } else { this.destroySubmenu(); submenu = this.createSubmenu(); submenu.popupWindow.show(); } this.setSubmenuShown(true); this.activateItem(this.moreButton); if (this.isEditEnabled()) { //noinspection JSCheckFunctionSignatures submenu.popupWindow.setAutoHide(false); } }, showChildMenu: function(item) { var currentMenu = BX.PopupMenu.getMenuById(this.getChildMenuId()), childMenu = null; if (currentMenu && currentMenu.bindElement) { if (currentMenu.bindElement.id !== item.id) { this.destroyChildMenu(item); childMenu = this.createChildMenu(item); childMenu.popupWindow.show(); } else { currentMenu.popupWindow.show(); } } else { this.destroyChildMenu(item); childMenu = this.createChildMenu(item); childMenu.popupWindow.show(); } }, /** * Closes submenu * @public * @method closeSubmenu * @return {undefined} */ closeSubmenu: function() { var submenu = this.getSubmenu(); if (submenu === null) { return; } submenu.popupWindow.close(); if (!this.isActiveInMoreMenu()) { this.deactivateItem(this.moreButton); } this.setSubmenuShown(false); }, closeChildMenu: function(item) { var childMenu = this.getChildMenu(item); if (childMenu === null) { return; } childMenu.popupWindow.close(); }, /** * Gets current submenu * @public * @method getSubmenu * @return {BX.PopupMenu} */ getSubmenu: function() { return BX.PopupMenu.getMenuById(this.getSubmenuId()); }, getChildMenu: function() { return BX.PopupMenu.getMenuById(this.getChildMenuId()); }, /** * Destroys submenu * @private * @method destroySubmenu * @return {undefined} */ destroySubmenu: function() { BX.PopupMenu.destroy(this.getSubmenuId()); }, destroyChildMenu: function() { BX.PopupMenu.destroy(this.getChildMenuId()); }, /** * Refreshes submenu * @public * @method refreshSubmenu * @return {undefined} */ refreshSubmenu: function() { var submenu = this.getSubmenu(); var args; if (submenu === null) { return; } args = this.getSubmenuArgs(); if (BX.type.isArray(args)) { this.destroySubmenu(); this.createSubmenu(); this.showSubmenu(); } }, /** * Sets value this.isSubmenuShown * @private * @method setSubmenuShown * @param {boolean} value */ setSubmenuShown: function(value) { this.isSubmenuShown = false; if (BX.type.isBoolean(value)) { this.isSubmenuShown = value; } }, /** * Adds class active for item * @private * @method activateItem * @param {object} item * @return {undefined} */ activateItem: function(item) { if (!BX.type.isDomNode(item)) { return; } if (!BX.hasClass(item, this.classItemActive)) { BX.addClass(item, this.classItemActive); } }, /** * Removes class active for item * @private * @method deactivateItem * @param {object} item * @return {undefined} */ deactivateItem: function(item) { if (!BX.type.isDomNode(item)) { return; } if (BX.hasClass(item, this.classItemActive)) { BX.removeClass(item, this.classItemActive); } }, /** * Gets current component settings * @public * @method getCurrentSettings * @return {object} */ getCurrentSettings: function() { var settings = {}; this.getAllItems().forEach(function(current, index) { settings[current.id] = {sort: index, isDisabled: this.isDisabled(current)}; }, this); return settings; }, /** * Saves current component settings * @public * @method saveSettings * @return {undefined} */ saveSettings: function() { var settings = this.getCurrentSettings(); var paramName = 'settings'; var containerId; if (!BX.type.isPlainObject(settings)) { return; } if (BX.type.isDomNode(this.listContainer)) { if ('id' in this.listContainer) { containerId = this.listContainer.id; settings = JSON.stringify(settings); BX.userOptions.save('ui', containerId, paramName, settings); this.setHome(); } } }, resetSettings: function() { var button = null; var confirmPopup = BX.PopupWindowManager.create( this.listContainer.id + "_reset_popup", null, { content: this.message('MIB_RESET_ALERT'), autoHide: false, overlay: true, closeByEsc : true, closeIcon : true, draggable : { restrict : true}, titleBar: this.message("MIB_RESET_SETTINGS"), buttons: [ (button = new BX.PopupWindowButton({ text: this.message("MIB_RESET_BUTTON"), className: 'popup-window-button-create', events: { click: function() { if (BX.hasClass(button.buttonNode, "popup-window-button-wait")) { return; } BX.addClass(button.buttonNode, "popup-window-button-wait"); this.handleResetSettings(function(error) { if (error) { BX.removeClass(button.buttonNode, "popup-window-button-wait"); confirmPopup.setContent(error); } else { var paramName = 'settings'; BX.userOptions.save('ui', this.listContainer.id, paramName, JSON.stringify({})); BX.userOptions.save('ui', this.listContainer.id, 'firstPageLink', ''); window.location.reload(); } }.bind(this)); }.bind(this) } })), new BX.PopupWindowButtonLink({ text: this.message("MIB_CANCEL_BUTTON"), className: "popup-window-button-link-cancel", events: { click: function() { this.popupWindow.close(); } } }) ] } ); confirmPopup.show(); }, /** * @callback cb */ handleResetSettings: function(cb) { var promises = []; BX.onCustomEvent("BX.Main.InterfaceButtons:onBeforeResetMenu", [promises, this]); var promise = new BX.Promise(); var firstPromise = promise; for (var i = 0; i < promises.length; i++) { promise = promise.then(promises[i]); } promise.then( function(result) { cb(null, result); }, function(reason) { cb(reason, null); } ); firstPromise.fulfill(); }, /** * Moves alias buttons * @private * @method moveButtonAlias * @param {HTMLElement} item * @return {undefined} */ moveButtonAlias: function(item) { var aliasDragItem, aliasItem; if (!item || !this.dragItem) { return; } aliasDragItem = this.getItemAlias(this.dragItem); aliasItem = this.getItemAlias(item); if (this.isListItem(aliasDragItem)) { if (!aliasItem) { this.listContainer.appendChild(aliasDragItem); } else { this.listContainer.insertBefore(aliasDragItem, aliasItem); } } }, /** * Moves drag item before item, or appendChild to container * @private * @method moveButton * @param {HTMLElement} item * @return {*} */ moveButton: function(item) { var submenuContainer; if (!BX.type.isDomNode(item) || !BX.type.isDomNode(this.dragItem)) { return; } if (this.isListItem(item)) { if (this.isDisabled(this.dragItem)) { this.dragItem.dataset.disabled = 'false'; } if (BX.type.isDomNode(item)) { this.listContainer.insertBefore(this.dragItem, item); } else { this.listContainer.appendChild(this.dragItem); } } if (this.isSubmenuItem(item)) { if (this.isDisabled(this.dragItem) && !this.isDisabled(item)) { this.enableItem(this.dragItem); } submenuContainer = this.getSubmenuContainer(); submenuContainer.insertBefore(this.dragItem, item); } }, /** * Gets submenu container * @private * @method getSubmenuContainer * @return {object} */ getSubmenuContainer: function() { var submenu = this.getSubmenu(); var result = null; if (submenu !== null) { result = submenu.itemsContainer; } return result; }, /** * Gets next element with className * @param {?HTMLElement} item * @param {string} className * @returns {?HTMLElement} */ findNextSiblingByClass: function(item, className) { //noinspection UnnecessaryLocalVariableJS var sourceItem = item; for (; !!item; item = item.nextElementSibling) { if (className) { if (BX.hasClass(item, className) && item !== sourceItem) { return item; } } else { return null; } } }, /** * Finds parent node for item by className * @private * @method findParentByClassName * @param {object} item * @param {string} className * @return {object} */ findParentByClassName: function(item, className) { for (; item && item !== document; item = item.parentNode) { if (className) { if (BX.hasClass(item, className)) { return item; } } else { return null; } } }, /** * Finds children item by className * @private * @method findChildrenByClassName * @param {HTMLElement} item * @param {string} className * @return {?HTMLElement} */ findChildrenByClassName: function(item, className) { var result = null; if (BX.type.isDomNode(item) && BX.type.isNotEmptyString(className)) { result = BX.Buttons.Utils.getByClass(item, className); } return result; }, /** * Initialise Drag And Drop * @private * @method dragAndDropInit * @return {undefined} */ dragAndDropInit: function() { this.getAllItems().forEach(function(current, index) { if (!this.isSeparator(current) && !this.isSettings(current) && !this.isApplySettingsButton(current) && !this.isResetSettingsButton(current)) { current.setAttribute('draggable', 'true'); current.setAttribute('tabindex', '-1'); current.dataset.link = 'item' + index; BX.bind(current, 'dragstart', BX.delegate(this._onDragStart, this)); BX.bind(current, 'dragend', BX.delegate(this._onDragEnd, this)); BX.bind(current, 'dragenter', BX.delegate(this._onDragEnter, this)); BX.bind(current, 'dragover', BX.delegate(this._onDragOver, this)); BX.bind(current, 'dragleave', BX.delegate(this._onDragLeave, this)); BX.bind(current, 'drop', BX.delegate(this._onDrop, this)); } BX.bind(current, 'mouseover', BX.delegate(this._onMouse, this)); BX.bind(current, 'mouseout', BX.delegate(this._onMouse, this)); }, this); }, /** * Initialise Drag And Drop for submenu items * @private * @method dragAndDropInitInSubmenu * @return {undefined} */ dragAndDropInitInSubmenu: function() { var submenu = this.getSubmenu(); var submenuItems = submenu.menuItems; submenuItems.forEach(function(current) { if ((!this.isSeparator(current.layout.item) && !this.isSettings(current.layout.item) && !this.isApplySettingsButton(current.layout.item) && !this.isResetSettingsButton(current.layout.item))) { current.layout.item.draggable = true; current.layout.item.dataset.sortable = true; BX.bind(current.layout.item, 'dragstart', BX.delegate(this._onDragStart, this)); BX.bind(current.layout.item, 'dragenter', BX.delegate(this._onDragEnter, this)); BX.bind(current.layout.item, 'dragover', BX.delegate(this._onDragOver, this)); BX.bind(current.layout.item, 'dragleave', BX.delegate(this._onDragLeave, this)); BX.bind(current.layout.item, 'dragend', BX.delegate(this._onDragEnd, this)); BX.bind(current.layout.item, 'drop', BX.delegate(this._onDrop, this)); } if (BX.hasClass(current.layout.item, this.classHiddenLabel) && !BX.hasClass(current.layout.item, this.classManage)) { BX.bind(current.layout.item, 'dragover', BX.delegate(this._onDragOver, this)); } }, this); }, /** * Gets drag and drop event target element * @private * @method getItem * @param {object} eventOrItem * @return {?HTMLElement} */ getItem: function(eventOrItem) { if (!BX.type.isDomNode(eventOrItem)) { if ((!eventOrItem || !BX.type.isDomNode(eventOrItem.target))) { return null; } } else { eventOrItem = {target: eventOrItem}; } var item = this.findParentByClassName(eventOrItem.target, this.classItem); if (!BX.type.isDomNode(item)) { item = this.findParentByClassName(eventOrItem.target, this.classDefaultSubmenuItem); } return item; }, /** * Sets default opacity style * @private * @method setOpacity * @param {object} item */ setOpacity: function(item) { if (!BX.type.isDomNode(item)) { return; } BX.style(item, 'opacity', '.1'); }, /** * Unset opacity style * @private * @method unsetOpacity * @param {object} item * @return {undefined} */ unsetOpacity: function(item) { if (!BX.type.isDomNode(item)) { return; } BX.style(item, 'opacity', '1'); }, /** * Sets drag styles * @private * @method setDragStyles */ setDragStyles: function() { BX.addClass(this.listContainer, this.classOnDrag); BX.addClass(BX(this.getSubmenuId(true)), this.classOnDrag); this.setOpacity(this.dragItem); }, /** * Unset drag styles * @private * @method unsetDragStyles * @return {undefined} */ unsetDragStyles: function() { var submenu = this.getSubmenu(); this.getAllItems().forEach(function(current) { this.unsetOpacity(current); BX.removeClass(current, 'over'); }, this); if (submenu && ('menuItems' in submenu) && BX.type.isArray(submenu.menuItems) && submenu.menuItems.length) { submenu.menuItems.forEach(function(current) { this.unsetOpacity(current); BX.removeClass(current.layout.item, 'over'); }, this); } BX.removeClass(this.listContainer, this.classOnDrag); BX.removeClass(BX(this.getSubmenuId(true)), this.classOnDrag); }, /** * Gets icon class * @private * @method getIconClass * @param {object} item * @return {string} className */ getIconClass: function(item) { var result = ''; if (BX.type.isDomNode(item) && ('dataset' in item) && ('class' in item.dataset) && (BX.type.isNotEmptyString(item.dataset.class))) { result = item.dataset.class; } return result; }, /** * Disables the element * @private * @method disableItem * @param {HTMLElement} item * @return {undefined} */ disableItem: function(item) { var alias = this.getItemAlias(item); if (item && ('dataset' in item)) { item.dataset.disabled = 'true'; if (alias) { alias.dataset.disabled = 'true'; } } }, /** * Disables the element * @private * @method enableItem * @param {HTMLElement} item * @return {undefined} */ enableItem: function(item) { var alias; if (!BX.type.isDomNode(item)) { return; } if (this.isSubmenuItem(item)) { BX.removeClass(item, this.classItemDisabled); alias = this.getItemAlias(item); if (BX.type.isDomNode(alias)) { alias.dataset.disabled = 'false'; } } }, /** * Gets alias link * @private * @method getAliasLink * @param {object} item * @return {string} */ getAliasLink: function(item) { return this.dataValue(item, 'link') || ''; }, /** * Gets item alias * @private * @method getItemAlias * @param {HTMLElement} item * @return {?HTMLElement} */ getItemAlias: function(item) { var result = null; if (!BX.type.isDomNode(item)) { return result; } var allItems = this.getAllItems(); var isSubmenuItem = this.isSubmenuItem(item); var isListItem = this.isListItem(item); if (!isSubmenuItem && !isListItem) { return result; } if (isSubmenuItem) { allItems.forEach(function(current) { BX.hasClass(item, this.getAliasLink(current)) && (result = current); }, this); } if (isListItem) { result = BX.Buttons.Utils.getByClass(document, this.getAliasLink(item)); } return result; }, /** * @param {?HTMLElement} item */ hideItem: function(item) { !!item && BX.addClass(item, this.classSecret); }, /** * @param {?HTMLElement} item */ showItem: function(item) { !!item && BX.removeClass(item, this.classSecret); }, /** * Replaces drag item * @private * @method fakeDragItem * @return {undefined} */ fakeDragItem: function() { var fakeDragItem = null; if (!BX.type.isDomNode(this.dragItem) || !BX.type.isDomNode(this.overItem)) { return; } if (this.isDragToSubmenu()) { fakeDragItem = this.getItemAlias(this.dragItem); if (fakeDragItem !== this.dragItem) { this.listContainer.appendChild(this.dragItem); this.dragItem = fakeDragItem; this.showItem(this.dragItem); this.adjustMoreButtonPosition(); this.updateSubmenuItems(); this.tmp.moved = false; this.tmp.movetToSubmenu = true; this.setOpacity(this.dragItem); } } if (this.isDragToList() && !this.tmp.movetToSubmenu) { fakeDragItem = this.getItemAlias(this.dragItem); if (fakeDragItem !== this.dragItem) { this.hideItem(this.dragItem); this.dragItem = fakeDragItem; this.adjustMoreButtonPosition(); this.updateSubmenuItems(); this.setOpacity(this.dragItem); } } this.tmp.movetToSubmenu = false; }, /** * Updates submenu items relative to hidden items * @private * @method updateSubmenuItems * @return {undefined} */ updateSubmenuItems: function() { var hiddenItems = this.getHiddenItems(); var disabledItems = this.getDisabledItems(); var self = this; var items = []; var submenu, submenuItems, some; submenu = this.getSubmenu(); if (submenu === null) { return; } submenuItems = submenu.menuItems; if (!BX.type.isArray(submenuItems) || !submenuItems.length) { return; } items = disabledItems.concat(hiddenItems); submenuItems.forEach(function(current) { some = [].some.call(items, function(someEl) { return ( BX.hasClass(current.layout.item, self.dataValue(someEl, 'link')) || self.isDisabled(current.layout.item) || self.isSeparator(current.layout.item) || self.isDropzone(current.layout.item) ); }); if (some || (self.isSettings(current.layout.item) || self.isApplySettingsButton(current.layout.item) || self.isResetSettingsButton(current.layout.item) || self.isNotHiddenItem(current.layout.item) || self.isSeparator(current.layout.item) || current.layout.item === self.dragItem) && !self.isMoreButton(current.layout.item)) { self.showItem(current.layout.item); } else { self.hideItem(current.layout.item); } }); }, /** * @param {HTMLElement} item * @return {boolean} */ isNotHiddenItem: function(item) { return BX.hasClass(item, this.classSubmenuNoHiddenItem); }, /** * @return {?HTMLElement} */ getNotHidden: function() { return BX.Buttons.Utils.getByClass(this.getSubmenuContainer(), this.classSubmenuNoHiddenItem); }, /** * Sets styles for hovered item * @private * @method setOverStyles * @param {object} item */ setOverStyles: function(item) { if (BX.type.isDomNode(item) && !BX.hasClass(item, this.classItemOver)) { BX.addClass(item, this.classItemOver); } }, /** * Unset styles for hovered item * @private * @method unsetOverStyles * @param {object} item * @return {undefined} */ unsetOverStyles: function(item) { if (BX.type.isDomNode(item) && BX.hasClass(item, this.classItemOver)) { BX.removeClass(item, this.classItemOver); } }, /** * Gets value data attribute * @private * @method dataValue * @param {object} item * @param {string} key * @return {string} */ dataValue: function(item, key) { var result = ''; var tmpResult; if (BX.type.isDomNode(item)) { tmpResult = BX.data(item, key); if (typeof(tmpResult) !== 'undefined') { result = tmpResult; } } return result; }, /** * Executes script * @private * @method execScript * @param {string} script */ /*jshint -W061 */ execScript: function(script) { if (BX.type.isNotEmptyString(script)) { eval(script); } }, /** * Shows license window * @return {undefined} */ showLicenseWindow: function() { var popup; if (!B24.licenseInfoPopup) { return; } popup = B24.licenseInfoPopup; popup.init({ B24_LICENSE_BUTTON_TEXT: this.message('MIB_LICENSE_BUY_BUTTON'), B24_TRIAL_BUTTON_TEXT: this.message('MIB_LICENSE_TRIAL_BUTTON'), IS_FULL_DEMO_EXISTS: this.licenseParams.isFullDemoExists, HOST_NAME: this.licenseParams.hostname, AJAX_URL: this.licenseParams.ajaxUrl, LICENSE_ALL_PATH: this.licenseParams.licenseAllPath, LICENSE_DEMO_PATH: this.licenseParams.licenseDemoPath, FEATURE_GROUP_NAME: this.licenseParams.featureGroupName, AJAX_ACTIONS_URL: this.licenseParams.ajaxActionsUrl, B24_FEATURE_TRIAL_SUCCESS_TEXT: this.message('MIB_LICENSE_WINDOW_TRIAL_SUCCESS_TEXT') }); popup.show( 'main-buttons', this.message('MIB_LICENSE_WINDOW_HEADER_TEXT'), this.message('MIB_LICENSE_WINDOW_TEXT') ); }, /** * dragstart event handler * @private * @method _onDragStart * @param {object} event ondragstart event object * @return {undefined} */ _onDragStart: function(event) { var visibleItems = this.getVisibleItems(); var visibleItemsLength = BX.type.isArray(visibleItems) ? visibleItems.length : null; this.dragItem = this.getItem(event); if (!BX.type.isDomNode(this.dragItem)) { return; } if (visibleItemsLength === 2 && this.isListItem(this.dragItem)) { event.preventDefault(); BX.onCustomEvent(window, 'BX.Main.InterfaceButtons:onHideLastVisibleItem', [this.dragItem, this]); return; } if (this.isMoreButton(this.dragItem) || this.isSeparator(this.dragItem) || this.isNotHiddenItem(this.dragItem)) { event.preventDefault(); return; } this.isSubmenuShownOnDragStart = !!this.isSubmenuShown; if (this.isListItem(this.dragItem)) { this.showSubmenu(); } this.setDragStyles(); if (!this.isEditEnabled()) { this.enableEdit(); } }, /** * dragend event handler * @private * @method _onDragEnd * @param {object} event dragend event object * @return {undefined} */ _onDragEnd: function(event) { event.preventDefault(); var item = this.getItem(event); var nextVisible, prevVisible; if (!BX.type.isDomNode(item)) { return; } this.unsetDragStyles(); if (!this.isSubmenuShownOnDragStart) { this.refreshSubmenu(); if (!this.isEditEnabled()) { this.closeSubmenu(); } } else { this.refreshSubmenu(); } nextVisible = BX.findNextSibling(this.dragItem, BX.delegate(function(node) { return this.isVisibleItem(node); }, this)); prevVisible = BX.findPreviousSibling(this.dragItem, BX.delegate(function(node) { return this.isVisibleItem(node); }, this)); if (BX.type.isDomNode(prevVisible) && (BX.hasClass(prevVisible, this.classHiddenLabel) || (this.isDisabled(prevVisible) && this.isSubmenuItem(prevVisible))) || (BX.type.isDomNode(nextVisible) && BX.hasClass(nextVisible, this.classManage) || (this.isDisabled(nextVisible) && this.isSubmenuItem(nextVisible)))) { this.disableItem(this.dragItem); this.refreshSubmenu(); } if (this.isEditEnabled()) { this.enableEdit(); BX.show(this.getSettingsApplyButton()); BX.hide(this.getSettingsButton()); } else { this.disableEdit(); BX.hide(this.getSettingsApplyButton()); BX.show(this.getSettingsButton()); } this.updateMoreButtonCounter(); this.saveSettings(); this.dragItem = null; this.overItem = null; this.tmp.moved = false; }, updateMoreButtonCounter: function() { var hiddenItems, sumCount, counter, disabledItems; hiddenItems = this.getHiddenItems(); disabledItems = this.getDisabledItems(); hiddenItems = hiddenItems.concat(disabledItems); sumCount = 0; if (BX.type.isArray(hiddenItems)) { hiddenItems.forEach(function(current) { sumCount += parseInt(this.dataValue(current, 'counter')) || 0; }, this); } if (BX.type.isNumber(sumCount)) { this.setMoreButtonCounter(sumCount); } }, /** * dragenter event handler * @private * @method _onDragEnter * @param {object} event dragenter event object * @return {undefined} */ _onDragEnter: function(event) { var item = this.getItem(event); if (BX.type.isDomNode(item) && this.isNotHiddenItem(item)) { this.setOverStyles(item); } }, /** * dragover event handler * @private * @method _onDragOver * @param {object} event dragover event object * @return {undefined} */ _onDragOver: function(event) { event.preventDefault(); var nextSiblingItem = null; this.overItem = this.getItem(event); if (!BX.type.isDomNode(this.overItem) || !BX.type.isDomNode(this.dragItem) || this.overItem === this.dragItem || this.isNotHiddenItem(this.overItem)) { return; } this.fakeDragItem(); if (this.isNext(event) && this.isGoodPosition(event) && !this.isMoreButton(this.overItem)) { nextSiblingItem = this.findNextSiblingByClass( this.overItem, this.classItem ); if (this.isMoreButton(nextSiblingItem) && !this.tmp.moved) { nextSiblingItem = nextSiblingItem.previousElementSibling; this.tmp.moved = true; } if (!BX.type.isDomNode(nextSiblingItem)) { nextSiblingItem = this.findNextSiblingByClass( this.overItem, this.classSubmenuItem ); } if (BX.type.isDomNode(nextSiblingItem)) { this.moveButton(nextSiblingItem); this.moveButtonAlias(nextSiblingItem); this.adjustMoreButtonPosition(); this.updateSubmenuItems(); } } if ((!this.isNext(event) && this.isGoodPosition(event) && !this.isMoreButton(this.overItem)) || (!this.isGoodPosition(event) && this.isMoreButton(this.overItem) && this.getVisibleItems().length === 1)) { this.moveButton(this.overItem); this.moveButtonAlias(this.overItem); this.adjustMoreButtonPosition(); this.updateSubmenuItems(); } }, /** * dragleave event handler * @private * @method _onDragLeave * @param {object} event dragleave event object * @return {undefined} */ _onDragLeave: function(event) { var item = this.getItem(event); if (BX.type.isDomNode(item)) { this.unsetOverStyles(event.target); } }, /** * drop event handler * @private * @method _onDrop * @param {object} event drop event object * @return {undefined} */ _onDrop: function(event) { var item = this.getItem(event); if (!BX.type.isDomNode(item)) { return; } if (this.isNotHiddenItem(item) || this.isDisabled(item)) { this.disableItem(this.dragItem); this.adjustMoreButtonPosition(); } this.unsetDragStyles(); event.preventDefault(); }, /** * @param {array|NodeList} collection * @param {*} item - collection item * @return {number} */ getIndex: function(collection, item) { return [].indexOf.call((collection || []), item); }, /** * submenuClose custom BX.PopupMenu event handler * @private * @method _onSubmenuClose * @return {undefined} */ _onSubmenuClose: function() { this.setSubmenuShown(false); if (this.isEditEnabled()) { this.activateItem(this.moreButton); } else { if (!this.isActiveInMoreMenu()) { this.deactivateItem(this.moreButton); } } }, /** * resize window event handler * @private * @method _onResizeHandler * @return {object} window resize event object */ _onResizeHandler: function() { this.adjustMoreButtonPosition(); this.updateSubmenuItems(); if (!this.isSettingsEnabled) { this.visibleControlMoreButton(); } }, /** * click on more button event handler * @private * @method _onClickMoreButton * @param {object} event click event object * @return {undefined} */ _onClickMoreButton: function(event) { event.preventDefault(); this.showSubmenu(); }, /** * mouseover and mouseout events handler * @private * @method _onMouse * @param {object} event mouseover and mouseout event object * @return {undefined} */ _onMouse: function(event) { var item = this.getItem(event); if (event.type === 'mouseover' && !BX.hasClass(item, this.classItemOver)) { if (!BX.hasClass(item, this.classItemMore)) { this.showChildMenu(item); } BX.addClass(item, this.classItemOver); } if (event.type === 'mouseout' && BX.hasClass(item, this.classItemOver)) { BX.removeClass(item, this.classItemOver); } }, /** * @return {?HTMLElement} */ getSettingsResetButton: function() { return BX.Buttons.Utils.getByClass(this.getSubmenuContainer(), this.classSettingsResetButton); }, _onScroll: function() { if (BX.style(this.pinContainer, 'position') === 'fixed') { this.closeSubmenu(); } }, /** * Checks whether the item is disabled * @private * @method isDisabled * @param {object} item * @return {boolean} */ isDisabled: function(item) { var result = false; if (BX.type.isDomNode(item)) { result = ( this.dataValue(item, 'disabled') === 'true' || BX.hasClass(item, this.classItemDisabled) ); } return result; }, /** * @param {HTMLElement} item * @return {boolean} */ isSettings: function(item) { var result = false; if (BX.type.isDomNode(item)) { result = BX.hasClass(item, this.classSettingMenuItem); } return result; }, /** * Checks whether the item is locked * @private * @method isLocked * @param {object} item * @return {boolean} */ isLocked: function(item) { var result = false; if (BX.type.isDomNode(item)) { result = ( this.dataValue(item, 'locked') === 'true' || BX.hasClass(item, this.classItemLocked) ); } return result; }, /** * Checks whether the item is dropzone * @private * @method isOvered * @param {object} item * @return {boolean} */ isDropzone: function(item) { return BX.hasClass(item, this.classDropzone); }, /** * Checks whether the hovered item is next * @private * @method isNext * @param {object} event dragover event object * @return {boolean} */ isNext: function(event) { var dragItemRect = this.dragItem.getBoundingClientRect(); var overItemRect = this.overItem.getBoundingClientRect(); var styles = getComputedStyle(this.dragItem); var dragItemMarginRight = parseInt(styles.marginRight.replace('px', '')); var result = null; if (this.isListItem(this.overItem)) { result = ( event.clientX > (overItemRect.left - dragItemMarginRight) && event.clientX > dragItemRect.right ); } if (this.isSubmenuItem(this.overItem)) { result = ( event.clientY > dragItemRect.top ); } return result; }, /** * Checks whether it is possible to move the item * @private * @method isGoodPosition * @param {object} event dragover event object * @return {boolean} */ isGoodPosition: function(event) { var overItem = this.overItem; var overItemRect, result; if (!BX.type.isDomNode(overItem)) { return false; } overItemRect = overItem.getBoundingClientRect(); if (this.isListItem(overItem)) { result = ( (this.isNext(event) && (event.clientX >= (overItemRect.left + (overItemRect.width / 2)))) || (!this.isNext(event) && (event.clientX <= (overItemRect.left + (overItemRect.width / 2)))) ); } if (this.isSubmenuItem(overItem)) { result = ( (this.isNext(event) && (event.clientY >= (overItemRect.top + (overItemRect.height / 2)))) || (!this.isNext(event) && (event.clientY <= (overItemRect.top + (overItemRect.height / 2)))) ); } return result; }, /** * Checks whether the item is a submenu item * @private * @method isSubmenuItem * @param {object} item * @return {boolean} */ isSubmenuItem: function(item) { return BX.hasClass(item, this.classSubmenuItem); }, /** * Checks whether the item is visible * @private * @method isVisibleItem * @param {object} item * @return {boolean} */ isVisibleItem: function(item) { if (!BX.type.isDomNode(item)) { return false; } return item.offsetTop === 0; }, /** * Checks whether the item is more button * @private * @method isMoreButton * @param {object} item * @return {boolean} */ isMoreButton: function(item) { var result = false; if (BX.type.isDomNode(item) && BX.hasClass(item, this.classItemMore)) { result = true; } return result; }, /** * Checks whether the item is list item * @private * @method isListItem * @param {object} item * @return {boolean} */ isListItem: function(item) { var result = false; if (BX.type.isDomNode(item) && BX.hasClass(item, this.classItem)) { result = true; } return result; }, /** * Checks whether the item is sublink * @private * @method isSublink * @param {object} item * @return {boolean} */ isSublink: function(item) { var result = false; if (BX.type.isDomNode(item)) { result = BX.hasClass(item, this.classItemSublink); } return result; }, /** * Checks whether the item is separator * @private * @method isSeparator * @param {object} item * @return {boolean} */ isSeparator: function(item) { var result = false; if (BX.type.isDomNode(item)) { result = BX.hasClass(item, this.classSeporator); } return result; }, /** * Checks that the element is dragged into the submenu * @return {boolean} */ isDragToSubmenu: function() { return (!this.isSubmenuItem(this.dragItem) && this.isSubmenuItem(this.overItem) ); }, /** * Checks that the element is dragged into the list * @return {boolean} */ isDragToList: function() { return ( this.isSubmenuItem(this.dragItem) && !this.isSubmenuItem(this.overItem) ); } }; } if (typeof(BX.Main.interfaceButtonsManager) === 'undefined') { BX.Main.interfaceButtonsManager = { data: {}, init: function(params) { var container = null; if (!BX.type.isPlainObject(params) || !('containerId' in params)) { throw 'BX.Main.interfaceButtonsManager: containerId not set in params Object'; } container = BX(params.containerId); if (BX.type.isDomNode(container)) { this.data[params.containerId] = new BX.Main.interfaceButtons(container, params); } else { BX(BX.delegate(function() { container = BX(params.containerId); if (!BX.type.isDomNode(container)) { throw 'BX.Main.interfaceButtonsManager: container is not dom node'; } this.data[params.containerId] = new BX.Main.interfaceButtons(container, params); }, this)); } }, getById: function(containerId) { var result = null; if (BX.type.isString(containerId) && BX.type.isNotEmptyString(containerId)) { try { result = this.data[containerId]; } catch (e) {} } return result; }, getObjects: function() { return this.data; } }; }