cloudcmd/lib/client/view.js

388 lines
13 KiB
JavaScript

var CloudCmd, Util, DOM, CloudFunc, $;
(function(CloudCmd, Util, DOM, CloudFunc) {
'use strict';
/* global rendy */
CloudCmd.View = ViewProto;
function ViewProto(CallBack) {
var Name = 'View',
Loading = false,
Events = DOM.Events,
Dialog = DOM.Dialog,
Info = DOM.CurrentInfo,
Key = CloudCmd.Key,
Images = DOM.Images,
View = Util.exec.bind(Util),
Element, TemplateAudio, Overlay,
Config = {
beforeShow : function(callback) {
Images.hide();
Key.unsetBind();
showOverlay();
Util.exec(callback);
},
beforeClose : function(callback) {
Key.setBind();
Util.exec(callback);
hideOverlay();
},
afterShow : function(callback) {
Element.focus();
Util.exec(callback);
},
afterClose : function(callback) {
Util.exec(callback);
},
fitToView : true,
loop : false,
openEffect : 'none',
closeEffect : 'none',
autoSize : false,
height : '100%',
width : '100%',
minWidth : 0,
minHeight : 0,
padding : 0,
preload : 0,
keys : null,
mouseWheel : false,
arrows : false,
helpers : {
overlay : null,
title : null
}
};
View.show = show;
View.hide = hide;
function init() {
var func = CallBack || Util.exec.with(show, null);
Loading = true;
Util.exec.series([
DOM.loadJquery,
load,
function(callback) {
Loading = false;
Util.exec(callback);
},
func
]);
Config.parent = Overlay = DOM.load({
id : 'js-view',
name : 'div',
className : 'fancybox-overlay fancybox-overlay-fixed'
});
['click', 'contextmenu'].forEach(function(name) {
Events.add(name, Overlay, onOverLayClick);
});
Events.addKey(listener);
}
/**
* function shows FancyBox
*/
function show(data, options) {
var path, element, type,
config = {};
if (!Loading) {
Element = $('<div class="view" tabindex=0>');
if (data) {
element = $(Element).append(data);
Util.copyObj(config, Config);
if (options)
Object.keys(options).forEach(function(name) {
var func,
isConfig = !!config[name],
series = Util.exec.series,
item = options[name],
isFunc = Util.type.function(item);
if (isFunc && isConfig) {
func = config[name];
config[name] = function() {
series([func, item]);
};
} else {
config[name] = options[name];
}
});
$.fancybox(element, config);
} else {
Images.show.load();
path = CloudFunc.FS + Info.path;
type = getType(path);
switch(type) {
default:
Info.getData(function(error, data) {
var element;
if (error) {
Images.hide();
Dialog.alert(error);
} else {
element = document.createTextNode(data);
/* add margin only for view text documents */
Element.css('margin', '2%');
$.fancybox(Element.append(element), Config);
}
});
break;
case 'image':
showImage(path);
break;
case 'media':
getMediaElement(path, function(element) {
var media = DOM.getByDataName('js-media', element),
onKey = Util.exec.with(onMediaKey, media);
$.fancybox.open(element, {
parent : Overlay,
beforeShow : function() {
Config.beforeShow();
Events.addKey(onKey);
},
beforeClose : function() {
Config.beforeClose();
Events.rmKey(onKey);
},
afterShow: function() {
element
.querySelector('audio, video')
.focus();
},
helpers: {
overlay : null,
title : null
}
});
});
break;
}
}
}
}
function hide() {
$.fancybox.close();
}
function showImage() {
var config,
current = Info.name,
files = [].slice.call(Info.files),
names = DOM.getSelectedNames(files)
.filter(isImage)
.filter(function(name) {
return name !== current;
}).map(function(name) {
return {
href: name,
title: name
};
});
names.unshift({
href: current,
title: current
});
config = Util.copyObj({
}, Config);
config = Util.copyObj(config, {
autoSize : true,
type : 'image',
prevEffect : 'none',
nextEffect : 'none',
arrows : true,
keys : true,
helpers : {
overlay : null,
title : {}
}
});
$.fancybox.open(names, config);
}
function isImage(name) {
var isMatch;
isMatch = [
'jp(e|g|eg)',
'gif',
'png',
'bmp',
'webp',
'svg',
'ico'
].some(function(ext) {
var reg = RegExp('\\.' + ext + '$', 'i');
return reg.test(name);
});
return isMatch;
}
function isMedia(name) {
var isMatch;
isMatch = isAudio(name) || isVideo(name);
return isMatch;
}
function isAudio(name) {
return /\.(mp3|ogg|m4a)$/i.test(name);
}
function isVideo(name) {
return /\.(mp4|avi)$/i.test(name);
}
function getType(name) {
var type;
if (isImage(name))
type = 'image';
else if (isMedia(name))
type = 'media';
return type;
}
function getMediaElement(src, callback) {
Util.check(arguments, ['src', 'callback']);
DOM.Files.get('view/media-tmpl', function(error, template) {
var rendered, element, type, is,
name = Info.name;
if (error) {
alert(error);
} else {
if (!TemplateAudio)
TemplateAudio = template;
is = isAudio(name);
type = is ? 'audio' : 'video';
rendered = rendy(TemplateAudio, {
src : src,
type: type,
name: Info.name
});
element = $(rendered)[0];
callback(element);
}
});
}
function onMediaKey(media, event) {
var key = event.keyCode;
if (key === Key.SPACE) {
if (media.paused)
media.play();
else
media.pause();
}
}
/**
* function loads css and js of FancyBox
* @callback - executes, when everything loaded
*/
function load(callback) {
Util.time(Name + ' load');
DOM.loadRemote('fancybox', function() {
var prefix = CloudCmd.PREFIX;
DOM.load.css(prefix + '/css/view.css', callback);
DOM.load.style({
id : 'view-inlince-css',
inner : [
'.fancybox-title-float-wrap .child {',
'-webkit-border-radius: 0;',
'-moz-border-radius: 0;',
'border-radius: 0;',
'}'
].join('')
});
});
}
function onOverLayClick(event) {
var isCurrent, isFiles, isFilesPassive,
files = Info.files,
filesPassive = Info.filesPassive,
element = event.target,
isOverlay = element === Overlay,
position = {
x: event.clientX,
y: event.clientY
};
if (isOverlay) {
hideOverlay();
element = DOM.getCurrentByPosition(position);
if (element) {
isFiles = ~[].indexOf.call(files, element);
isFilesPassive = ~[].indexOf.call(filesPassive, element);
if (isFiles || isFilesPassive) {
isCurrent = DOM.isCurrentFile(element);
if (!isCurrent)
DOM.setCurrentFile(element);
}
}
View.hide();
}
}
function hideOverlay() {
Overlay.classList.remove('view-overlay');
}
function showOverlay() {
Overlay.classList.add('view-overlay');
}
function listener(event) {
var keyCode = event.keyCode,
ESC = Key.ESC;
if (keyCode === ESC)
hide();
}
init();
return View;
}
})(CloudCmd, Util, DOM, CloudFunc);