%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/js/ui/viewer/ |
| Current File : /home/bitrix/www/bitrix/js/ui/viewer/ui.viewer.js |
;(function () {
'use strict';
BX.namespace('BX.UI.Viewer');
BX.UI.Viewer.Controller = function(options)
{
/**
* @type {BX.UI.Viewer.Item[]}
*/
this.items = null;
this.currentIndex = null;
this.handlers = {};
this.setItems(options.items || []);
/**
* @type {BX.UI.ActionPanel}
*/
this.actionPanel = new BX.UI.ActionPanel({
darkMode: true,
autoHide: false,
showTotalSelectedBlock: false,
showResetAllBlock: false,
alignItems: 'center',
renderTo: function() {
return this.getPanelWrapper();
}.bind(this)
});
this.init();
this.zIndex = options.zIndex || 999999;
this.layout = {
container: null,
content: null,
inner: null,
items: null,
next: null,
prev: null,
close: null,
error: null,
loader: null,
loaderContainer: null,
panel: null
}
};
BX.UI.Viewer.Controller.prototype = {
handleDocumentClick: function (event)
{
var target = BX.getEventTarget(event);
if (!target.dataset.hasOwnProperty('viewer'))
{
return;
}
var indexToShow = 0;
var viewer = BX.UI.Viewer.Instance;
if (!target.dataset.viewerGroupBy)
{
viewer.setItems([
BX.UI.Viewer.buildItemByNode(target)
]);
}
else
{
var nodes = [].slice.call(target.ownerDocument.querySelectorAll("[data-viewer][data-viewer-group-by='" + target.dataset.viewerGroupBy + "']"));
var items = nodes.map(function(node, index) {
if (node === target)
{
indexToShow = index;
}
return BX.UI.Viewer.buildItemByNode(node);
});
viewer.setItems(items);
}
viewer.open(indexToShow);
event.preventDefault();
},
bindEvents: function ()
{
this.handlers.keyPress = this.handleKeyPress.bind(this);
this.handlers.touchStart = this.handleTouchStart.bind(this);
this.handlers.touchEnd = this.handleTouchEnd.bind(this);
this.handlers.resize = this.adjustViewerHeight.bind(this);
BX.bind(document, 'keydown', this.handlers.keyPress);
BX.bind(window, 'resize', this.handlers.resize);
BX.bind(this.getItemListNode(), 'touchstart', this.handlers.touchStart);
BX.bind(this.getItemListNode(), 'touchend', this.handlers.touchEnd);
BX.bind(this.getNextButton(), 'click', this.showNext.bind(this));
BX.bind(this.getPrevButton(), 'click', this.showPrev.bind(this));
BX.bind(this.getCloseButton(), 'click', this.close.bind(this));
BX.addCustomEvent('SidePanel.Slider:onOpen', function(event) {
if (!this.originalZIndex)
{
this.originalZIndex = this.getZindex();
}
this.setZindex(event.getSlider().getZindex() - 1);
}.bind(this));
BX.addCustomEvent('SidePanel.Slider:onCloseComplete', function(event) {
var slider = BX.SidePanel.Instance.getTopSlider();
if (slider)
{
this.setZindex(slider.getZindex() - 1);
}
else
{
this.setZindex(this.originalZIndex);
this.originalZIndex = null;
}
}.bind(this));
},
unbindEvents: function()
{
BX.unbind(document, 'keydown', this.handlers.keyPress);
BX.unbind(window, 'resize', this.handlers.resize);
BX.unbind(this.getItemListNode(), 'touchstart', this.handlers.touchStart);
BX.unbind(this.getItemListNode(), 'touchend', this.handlers.touchEnd);
},
init: function ()
{},
getZindex: function ()
{
return this.zIndex;
},
setZindex: function (zIndex)
{
this.zIndex = zIndex;
this.getViewerContainer().style.zIndex = zIndex;
},
setItems: function (items)
{
if (!BX.type.isArray(items))
{
throw new Error("BX.UI.Viewer.Controller.setItems: 'items' has to be Array.");
}
BX.onCustomEvent('BX.UI.Viewer.Controller:onSetItems', [this, items]);
this.items = items;
this.items.forEach(function (item) {
item.setController(this);
}, this);
},
appendItem: function (item)
{
if (!(item instanceof BX.UI.Viewer.Item))
{
throw new Error("BX.UI.Viewer.Controller.appendItem: 'item' has to be instance of BX.UI.Viewer.Item.");
}
item.setController(this);
this.items.push(item);
},
show: function (index, forceReload)
{
if (typeof index === 'undefined')
{
index = 0;
}
BX.onCustomEvent('BX.UI.Viewer.Controller:onBeforeShow', [this, index]);
var item = this.getItemByIndex(index);
if (!item)
{
return;
}
var prevItem = this.getCurrentItem();
this.currentIndex = index;
this.hideErrorBlock();
if (prevItem)
{
this.hideCurrentItem();
}
this.actionPanel.removeItems();
this.actionPanel.addItems(
this.refineActions(this.getCurrentItem().getActions(), this.getCurrentItem())
);
this.showLoading();
var promise;
if (forceReload)
{
promise = item.reload();
}
else
{
promise = item.load();
}
promise.then(function (item) {
if (this.getCurrentItem() === item)
{
this.processShowItem.call(this, item);
}
}.bind(this))
.catch(function (reason) {
this.processError.call(this, reason, item);
}.bind(this))
;
this.updateControls();
this.lockScroll();
this.adjustViewerHeight();
},
reload: function (item)
{
var isCurrentVisibleItem = this.getCurrentItem() === item;
if (isCurrentVisibleItem)
{
this.show(this.currentIndex, true);
}
},
reloadCurrentItem: function ()
{
return this.reload(this.getCurrentItem());
},
processShowItem: function(item)
{
BX.cleanNode(this.layout.items);
// this.actionPanel.addItems(this.getCurrentItem().getActions());
this.hideLoading();
var contentWrapper = BX.create('div', {
props: {
className: 'ui-viewer-inner-content-wrapper'
}
});
var fragment = document.createDocumentFragment();
fragment.appendChild(item.render());
var title = item.getTitle();
if (title)
{
fragment.appendChild(BX.create('div', {
props: {
className: 'viewer-inner-caption'
},
text: title
}));
}
contentWrapper.appendChild(fragment);
this.layout.items.appendChild(contentWrapper);
item.afterRender();
},
processError: function(reason, item)
{
this.hideCurrentItem();
this.hideLoading();
this.layout.container.appendChild(this.getErrorBlock());
},
hideErrorBlock: function()
{
if (this.layout.error)
{
BX.remove(this.layout.error);
}
},
getErrorBlock: function(options)
{
options = options || {};
var title = options.title || BX.message('JS_UI_VIEWER_DEFAULT_ERROR_TITLE');
var description = options.description;
this.layout.error = BX.create('div', {
props: {
className: 'ui-viewer-error'
},
children: [
BX.create('div', {
props: {
className: 'ui-viewer-error-title'
},
text: title
}),
BX.create('div', {
props: {
className: 'ui-viewer-error-text'
},
text: description
})
]
});
return this.layout.error;
},
refineActions: function (actions, item)
{
var defaultActions = {
download: {
id: 'download',
type: 'download',
text: BX.message('JS_UI_VIEWER_ITEM_ACTION_DOWNLOAD'),
href: item.src,
buttonIconClass: 'ui-btn-icon-download'
},
edit: {
id: 'edit',
type: 'edit',
text: BX.message('JS_UI_VIEWER_ITEM_ACTION_EDIT'),
buttonIconClass: 'ui-btn-icon-edit'
},
share: {
id: 'share',
type: 'share',
text: BX.message('JS_UI_VIEWER_ITEM_ACTION_SHARE'),
buttonIconClass: 'ui-btn-icon-share'
},
info: {
id: 'info',
type: 'info',
text: '',
buttonIconClass: 'ui-btn-icon-info ui-action-panel-item-last'
},
delete: {
id: 'delete',
type: 'delete',
text: BX.message('JS_UI_VIEWER_ITEM_ACTION_DELETE'),
buttonIconClass: 'ui-btn-icon-remove'
}
};
return actions.map(function(action) {
if (defaultActions[action.type])
{
action = BX.mergeEx(defaultActions[action.type], action)
}
if (BX.type.isString(action.action) && (typeof eval(action.action) === 'function'))
{
var fn = eval(action.action);
action.onclick = function(event, panelItem) {
fn.call(this, item, panelItem);
};
}
return action;
}, this);
},
getLoader: function(options)
{
if (!this.layout.loader)
{
this.layout.loader = BX.create('div', {
props: {
className: 'ui-viewer-loader'
},
children: [
this.layout.loaderContainer = BX.create('div', {
props: {
className: 'ui-viewer-loader-container'
}
}),
BX.create('div', {
props: {
className: 'ui-viewer-loader-text'
},
text: ''
})
]
});
var loader = new BX.Loader({size: 130});
loader.show(this.layout.loaderContainer);
}
return this.layout.loader;
},
getPrevButton: function()
{
if (!this.layout.prev)
{
this.layout.prev = BX.create('div', {
props: {
className: 'ui-viewer-prev'
}
})
}
return this.layout.prev;
},
getNextButton: function()
{
if (!this.layout.next)
{
this.layout.next = BX.create('div', {
props: {
className: 'ui-viewer-next'
}
});
}
return this.layout.next;
},
getCloseButton: function()
{
if (!this.layout.close)
{
this.layout.close = BX.create('div', {
props: {
className: 'ui-viewer-close'
},
html: '<div class="ui-viewer-close-icon"></div>'
});
}
return this.layout.close;
},
isOpen: function ()
{
return this._isOpen;
},
open: function(index)
{
document.body.appendChild(this.getViewerContainer());
this.show(index);
this.showPanel();
this.bindEvents();
this._isOpen = true;
},
getPanelWrapper: function()
{
if (!this.layout.panel)
{
this.layout.panel = BX.create('div', {
props: {
className: 'ui-viewer-panel'
}
});
}
return this.layout.panel;
},
showPanel: function()
{
this.actionPanel.layout.container.style.zIndex = '9999999';
this.actionPanel.layout.container.style.background = 'none';
this.actionPanel.layout.container.style.maxWidth = this.layout.inner.offsetWidth + 'px';
this.actionPanel.draw();
this.actionPanel.showPanel();
},
hideCurrentItem: function()
{
BX.cleanNode(this.layout.items);
},
updateControls: function()
{
if (this.currentIndex + 1 >= this.items.length)
{
BX.addClass(this.getNextButton(), 'ui-viewer-navigation-hide');
}
else
{
BX.removeClass(this.getNextButton(), 'ui-viewer-navigation-hide');
}
if (this.currentIndex === 0)
{
BX.addClass(this.getPrevButton(), 'ui-viewer-navigation-hide');
}
else
{
BX.removeClass(this.getPrevButton(), 'ui-viewer-navigation-hide');
}
},
/**
* @return {BX.UI.Viewer.Item}
*/
getCurrentItem: function ()
{
return this.getItemByIndex(this.currentIndex);
},
/**
*
* @param index
* @returns BX.UI.Viewer.Item
*/
getItemByIndex: function (index)
{
index = parseInt(index, 10);
BX.onCustomEvent('BX.UI.Viewer.Controller:onGetItemByIndex', [this, index]);
if (index < 0 || (index - 1) > this.items.length)
{
return null;
}
return this.items[index];
},
showNext: function ()
{
this.show(this.currentIndex + 1);
},
showPrev: function ()
{
this.show(this.currentIndex - 1);
},
close: function ()
{
this._isOpen = false;
BX.onCustomEvent('BX.UI.Viewer.Controller:onClose', [this]);
this.layout.container.parentNode.removeChild(this.layout.container);
this.actionPanel.hidePanel();
this.unLockScroll();
this.unbindEvents();
// this.items = null;
// this.currentIndex = null;
// this.layout.container = null;
// this.layout.close = null;
},
showLoading: function ()
{
this.layout.inner.appendChild(this.getLoader());
},
hideLoading: function ()
{
BX.remove(this.layout.loader);
},
lockScroll: function()
{
document.body.style.overflow = 'hidden';
},
unLockScroll: function()
{
document.body.style.overflow = null;
},
adjustViewerHeight: function()
{
if(!this.layout.container)
return;
this.layout.container.style.height = document.documentElement.clientHeight + 'px';
},
getViewerContainer: function()
{
if (!this.layout.container)
{
this.layout.container = BX.create('div', {
props: {
className: 'ui-viewer'
},
style: {
zIndex: this.zIndex,
height: window.clientHeight + 'px'
},
children: [
this.layout.inner = BX.create('div', {
props: {
className: 'ui-viewer-inner'
},
children: [
this.getItemListNode()
]
}),
this.getCloseButton(),
this.getPrevButton(),
this.getNextButton(),
this.getPanelWrapper()
]
});
}
return this.layout.container;
},
getItemListNode: function()
{
if (!this.layout.items)
{
this.layout.items = BX.create('div', {
props: {
className: 'ui-viewer-inner-content'
}
});
}
return this.layout.items
},
handleTouchStart: function(event)
{
var touchObject = event.changedTouches[0];
this.swipeDirection = null;
this.startX = touchObject.pageX;
this.startY = touchObject.pageY;
this.startTime = (new Date()).getTime();
event.preventDefault();
},
handleTouchEnd: function(event)
{
var touchObject = event.changedTouches[0];
var allowedTime = 300;
var threshold = 80;
var restraint = 100;
var distanceX = touchObject.pageX - this.startX;
var distanceY = touchObject.pageY - this.startY;
var elapsedTime = (new Date()).getTime() - this.startTime;
if (elapsedTime <= allowedTime)
{
if (Math.abs(distanceX) >= threshold && Math.abs(distanceY) <= restraint)
{
this.swipeDirection = (distanceX < 0) ? 'left' : 'right';
}
else if (Math.abs(distanceY) >= threshold && Math.abs(distanceX) <= restraint)
{
this.swipeDirection = (distanceY < 0) ? 'up' : 'down';
}
}
switch (this.swipeDirection)
{
case 'up':
case 'left':
this.showPrev();
break;
case 'down':
case 'right':
this.showNext();
break;
}
event.preventDefault();
},
handleKeyPress: function (event)
{
switch (event.code)
{
case 'Space':
case 'ArrowRight':
case 'PageDown':
case 'ArrowDown':
this.showNext();
event.preventDefault();
break;
case 'ArrowLeft':
case 'PageUp':
case 'ArrowUp':
this.showPrev();
event.preventDefault();
break;
case 'Escape':
this.close();
event.preventDefault();
break;
}
}
};
/**
* @param type
* @param {HTMLElement} node
* @return {BX.UI.Viewer.Item}
*/
BX.UI.Viewer.buildItemByTypeAndNode = function (type, node)
{
var item = new type();
item.setPropertiesByNode(node);
item.bindSourceNode(node);
return item;
};
/**
* @param {HTMLElement} node
* @returns {BX.UI.Viewer.Item}
*/
BX.UI.Viewer.buildItemByNode = function (node)
{
if (!BX.type.isDomNode(node))
{
throw new Error("BX.UI.Viewer.buildItemByNode: 'node' has to be DomNode.");
}
var typeCode = node.dataset.viewerType;
if (!typeCode)
{
if (node.tagName.toLowerCase() === 'img')
{
typeCode = 'image';
}
}
switch (typeCode)
{
case 'image':
return BX.UI.Viewer.buildItemByTypeAndNode(BX.UI.Viewer.Image, node);
case 'plainText':
return BX.UI.Viewer.buildItemByTypeAndNode(BX.UI.Viewer.PlainText, node);
case 'unknown':
return BX.UI.Viewer.buildItemByTypeAndNode(BX.UI.Viewer.Unknown, node);
case 'video':
return BX.UI.Viewer.buildItemByTypeAndNode(BX.UI.Viewer.Video, node);
case 'document':
return BX.UI.Viewer.buildItemByTypeAndNode(BX.UI.Viewer.Document, node);
}
};
/**
* @param {HTMLElement} container
* @param filter
* @returns {BX.Promise}
*/
BX.UI.Viewer.bind = function (container, filter)
{
if (!BX.type.isDomNode(container))
{
throw new Error("BX.UI.Viewer.bind: 'container' has to be DomNode.");
}
if (!BX.type.isPlainObject(filter) && !BX.type.isFunction(filter))
{
filter = function(node) {
return BX.type.isElementNode(node) && node.dataset.hasOwnProperty('viewer');
};
}
BX.bindDelegate(container, 'click', filter, function(event) {
var viewer = new BX.UI.Viewer.Controller({});
var nodes = BX.findChildren(container, filter, true);
var indexToShow = 0;
var targetNode = BX.getEventTarget(event);
var items = nodes.map(function(node, index) {
if (node === targetNode)
{
indexToShow = index;
}
return BX.UI.Viewer.buildItemByNode(node);
});
viewer.setItems(items);
viewer.open(indexToShow);
event.preventDefault();
});
};
var instance = null;
/**
* @memberOf BX.UI.Viewer
* @name BX.UI.Viewer#Instance
* @type BX.UI.Viewer.Controller
* @static
* @readonly
*/
Object.defineProperty(BX.UI.Viewer, 'Instance', {
enumerable: false,
get: function()
{
if (window.top !== window && BX.getClass('window.top.BX.UI.Viewer.Instance'))
{
return window.top.BX.UI.Viewer.Instance;
}
if (instance === null)
{
instance = new BX.UI.Viewer.Controller({});
}
return instance;
}
});
window.document.addEventListener('click', function(event){
if (window.top !== window && !BX.getClass('window.top.BX.UI.Viewer.Instance'))
{
window.top.BX.loadExt('ui.viewer').then(function () {
top.BX.UI.Viewer.Instance.handleDocumentClick(event);
});
}
else
{
top.BX.UI.Viewer.Instance.handleDocumentClick(event);
}
}, true);
//try to load ui.viewer to the top window if there is no viewer.
if (window.top !== window && !BX.getClass('window.top.BX.UI.Viewer.Instance'))
{
window.top.BX.loadExt('ui.viewer');
}
})();