mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 10:45:47 +00:00
525 lines
20 KiB
JavaScript
525 lines
20 KiB
JavaScript
var Util, DOM, CloudFunc;
|
||
|
||
(function(scope, Util, DOM, CloudFunc) {
|
||
'use strict';
|
||
|
||
scope.CloudCmd = new CloudCmdProto(Util, DOM, CloudFunc);
|
||
|
||
function CloudCmdProto(Util, DOM, CloudFunc) {
|
||
var Key, Config, Modules, Extensions,
|
||
FileTemplate, PathTemplate, Listeners,
|
||
DIR_HTML = '/html/',
|
||
DIR_HTML_FS = DIR_HTML + 'fs/',
|
||
DIR_JSON = '/json/',
|
||
|
||
Images = DOM.Images,
|
||
Info = DOM.CurrentInfo,
|
||
CloudCmd = this,
|
||
Storage = DOM.Storage;
|
||
|
||
this.MousePosition = {};
|
||
this.LIBDIR = '/lib/';
|
||
this.LIBDIRCLIENT = '/lib/client/';
|
||
this.MIN_ONE_PANEL_WIDTH = 1155;
|
||
this.OLD_BROWSER = false;
|
||
this.HOST = location.origin ||
|
||
location.protocol + '//' + location.host;
|
||
/**
|
||
* Функция привязываеться ко всем ссылкам и
|
||
* загружает содержимое каталогов
|
||
*
|
||
* @param params - {
|
||
* paramLink - ссылка
|
||
* needRefresh - необходимость обязательной загрузки данных с сервера
|
||
* panel
|
||
* }
|
||
* @param event
|
||
*/
|
||
this.loadDir = function(params) {
|
||
var link, imgPosition, panelChanged, pathParams,
|
||
isRefresh, panel, nohistory,
|
||
p = params,
|
||
currentLink = DOM.getCurrentLink(),
|
||
href = currentLink.href;
|
||
|
||
if (params) {
|
||
pathParams = p.path;
|
||
isRefresh = p.isRefresh;
|
||
panel = p.panel;
|
||
nohistory = p.nohistory;
|
||
}
|
||
|
||
if (pathParams)
|
||
link = pathParams;
|
||
else
|
||
link = Util.rmStr(href, CloudCmd.HOST);
|
||
|
||
if (link || currentLink.target !== '_blank') {
|
||
if (panel && panel !== Info.panel) {
|
||
DOM.changePanel();
|
||
panelChanged = true;
|
||
}
|
||
|
||
if (panelChanged || isRefresh)
|
||
imgPosition = {
|
||
top: true
|
||
};
|
||
|
||
Images.showLoad(imgPosition);
|
||
|
||
/* загружаем содержимое каталога */
|
||
ajaxLoad(link, {
|
||
refresh : isRefresh,
|
||
nohistory : nohistory
|
||
}, panel);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* функция устанавливает курсор на каталог
|
||
* с которого мы пришли, если мы поднялись
|
||
* в верх по файловой структуре
|
||
* @param pDirName - имя каталога с которого мы пришли
|
||
*/
|
||
function currentToParent(dirName) {
|
||
var rootDir;
|
||
/* убираем слэш с имени каталога */
|
||
dirName = Util.rmStr(dirName, '/');
|
||
rootDir = DOM.getCurrentFileByName(dirName);
|
||
|
||
if (rootDir)
|
||
DOM.setCurrentFile(rootDir);
|
||
}
|
||
|
||
/**
|
||
* function load modules
|
||
* @pParams = {name, path, func, dobefore, arg}
|
||
*/
|
||
function loadModule(params) {
|
||
var name, path, func, doBefore, slash, afterSlash,
|
||
isContain;
|
||
|
||
if (params) {
|
||
name = params.name,
|
||
path = params.path,
|
||
func = params.func,
|
||
doBefore = params.dobefore;
|
||
|
||
if (path && !name) {
|
||
name = Util.getStrBigFirst(path);
|
||
name = Util.rmStr(name, '.js');
|
||
|
||
slash = name.indexOf('/');
|
||
if (slash > 0) {
|
||
afterSlash = name.substr(slash);
|
||
name = Util.rmStr(name, afterSlash);
|
||
}
|
||
}
|
||
|
||
isContain = Util.isContainStr(path, '.js');
|
||
|
||
if (!isContain)
|
||
path += '.js';
|
||
|
||
if (!CloudCmd[name]) {
|
||
CloudCmd[name] = function() {
|
||
var pathFull = CloudCmd.LIBDIRCLIENT + path,
|
||
args = arguments;
|
||
|
||
Util.exec(doBefore);
|
||
|
||
return DOM.load.js(pathFull, func ||
|
||
function() {
|
||
var Proto = CloudCmd[name];
|
||
|
||
if (Util.isFunction(Proto))
|
||
CloudCmd[name] = Util.applyConstructor(Proto, args);
|
||
});
|
||
};
|
||
|
||
CloudCmd[name].show = CloudCmd[name];
|
||
}
|
||
}
|
||
}
|
||
|
||
/** Конструктор CloudClient, который
|
||
* выполняет весь функционал по
|
||
* инициализации
|
||
*/
|
||
this.init = function() {
|
||
var callback = function() {
|
||
Util.exec.series([
|
||
initModules,
|
||
baseInit,
|
||
Util.exec.with(CloudCmd.route, location.hash)
|
||
]);
|
||
},
|
||
|
||
func = function(callback) {
|
||
var src = CloudCmd.LIBDIRCLIENT + 'polyfill.js';
|
||
|
||
CloudCmd.OLD_BROWSER = true;
|
||
|
||
DOM.loadJquery(function() {
|
||
DOM.load.js(src, callback);
|
||
});
|
||
};
|
||
|
||
Util.exec.if(document.body.scrollIntoViewIfNeeded, callback, func);
|
||
};
|
||
|
||
this.route = function(path) {
|
||
var module, file, current, msg,
|
||
query = path.split('/');
|
||
|
||
if (path) {
|
||
module = query[0];
|
||
module = Util.slice(module, 1).join('');
|
||
module = Util.getStrBigFirst(module);
|
||
|
||
file = query[1];
|
||
current = DOM.getCurrentFileByName(file);
|
||
|
||
if (file && !current) {
|
||
msg = CloudFunc.formatMsg('set current file', file, 'error');
|
||
Util.log(msg);
|
||
} else {
|
||
DOM.setCurrentFile(current);
|
||
CloudCmd.execFromModule(module, 'show');
|
||
}
|
||
}
|
||
};
|
||
|
||
function initModules(callback) {
|
||
Util.exec.if(CloudCmd.Key, function() {
|
||
Key = new CloudCmd.Key();
|
||
CloudCmd.Key = Key;
|
||
Key.bind();
|
||
}, function(callback) {
|
||
loadModule({
|
||
/* привязываем клавиши к функциям */
|
||
path : 'key.js',
|
||
func : callback
|
||
});
|
||
});
|
||
|
||
CloudCmd.getModules(function(error, modules) {
|
||
var storageObj, mod, path,
|
||
STORAGE = 'storage',
|
||
showLoad = Images.showLoad.bind(Images),
|
||
|
||
doBefore = {
|
||
'edit' : showLoad,
|
||
'menu' : showLoad,
|
||
'storage/_filepicker' : showLoad
|
||
},
|
||
|
||
load = function(name, path, func) {
|
||
loadModule({
|
||
name : name,
|
||
path : path,
|
||
dobefore : func
|
||
});
|
||
};
|
||
|
||
if (!modules)
|
||
modules = [];
|
||
|
||
modules.forEach(function(module) {
|
||
if (Util.isString(module))
|
||
load(null, module, doBefore[module]);
|
||
});
|
||
|
||
storageObj = Util.findObjByNameInArr(modules, STORAGE),
|
||
mod = Util.getNamesFromObjArray(storageObj);
|
||
|
||
mod.forEach(function(name) {
|
||
path = STORAGE + '/_' + name.toLowerCase();
|
||
|
||
load(name, path, doBefore[path]);
|
||
});
|
||
|
||
callback();
|
||
});
|
||
}
|
||
|
||
function baseInit(callback) {
|
||
var files = DOM.getFiles(),
|
||
LEFT = CloudFunc.PANEL_LEFT,
|
||
RIGHT = CloudFunc.PANEL_RIGHT;
|
||
|
||
/* выделяем строку с первым файлом */
|
||
if (files)
|
||
DOM.setCurrentFile(files[0]);
|
||
|
||
Listeners = CloudCmd.Listeners;
|
||
Listeners.init();
|
||
/* загружаем Google Analytics */
|
||
Listeners.analytics();
|
||
|
||
Listeners.setOnPanel(LEFT);
|
||
Listeners.setOnPanel(RIGHT);
|
||
|
||
Listeners.initKeysPanel();
|
||
|
||
CloudCmd.getConfig(function(error, config) {
|
||
var localStorage = config.localStorage,
|
||
dirPath = DOM.getCurrentDirPath();
|
||
|
||
/* устанавливаем переменную доступности кэша */
|
||
Storage.setAllowed(localStorage);
|
||
/* Устанавливаем кэш корневого каталога */
|
||
|
||
dirPath = CloudFunc.rmLastSlash(dirPath) || '/';
|
||
|
||
Storage.get(dirPath, function(error, data) {
|
||
if (!data) {
|
||
data = getJSONfromFileTable();
|
||
Storage.set(dirPath, data);
|
||
}
|
||
});
|
||
});
|
||
|
||
callback();
|
||
}
|
||
|
||
this.getTemplate = function(data, name, callback) {
|
||
var path = DIR_HTML + name +'.html',
|
||
func = getSystemFile(data, path);
|
||
|
||
func(callback);
|
||
};
|
||
|
||
function getSystemFile(global, url) {
|
||
var get = function (callback) {
|
||
var success = Util.exec.with(callback, null);
|
||
|
||
Util.exec.if(global, success, function() {
|
||
DOM.load.ajax({
|
||
url : url,
|
||
success : function(local) {
|
||
global = local;
|
||
success(local);
|
||
},
|
||
error : function(error) {
|
||
callback(error);
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
return get;
|
||
}
|
||
|
||
this.setConfig = function(config) { Config = config; };
|
||
this.getConfig = function(callback) {
|
||
var func = Util.exec.with(callback, null);
|
||
|
||
Util.exec.if(Config, func, function(callback) {
|
||
var RESTful = DOM.RESTful;
|
||
|
||
RESTful.Config.read(function(config) {
|
||
Config = config;
|
||
callback(config);
|
||
});
|
||
});
|
||
};
|
||
|
||
this.getModules = getSystemFile(Modules, DIR_JSON + 'modules.json');
|
||
this.getExt = getSystemFile(Extensions, DIR_JSON + 'ext.json');
|
||
this.getFileTemplate = getSystemFile(FileTemplate, DIR_HTML_FS + 'file.html');
|
||
this.getPathTemplate = getSystemFile(PathTemplate, DIR_HTML_FS + 'path.html');
|
||
this.getPathLinkTemplate = getSystemFile(PathTemplate, DIR_HTML_FS + 'pathLink.html');
|
||
this.getLinkTemplate = getSystemFile(PathTemplate, DIR_HTML_FS + 'link.html');
|
||
|
||
this.execFromModule = function(moduleName, funcName, params) {
|
||
var obj = CloudCmd[moduleName],
|
||
isObj = Util.isObject(obj);
|
||
|
||
Util.exec.if(isObj,
|
||
function() {
|
||
var obj = CloudCmd[moduleName],
|
||
func = obj[funcName];
|
||
|
||
Util.exec(func, params);
|
||
},
|
||
|
||
function(callback) {
|
||
Util.exec(obj, callback);
|
||
});
|
||
};
|
||
|
||
this.refresh = function(current, panelParam) {
|
||
var NEEDREFRESH = true,
|
||
panel = panelParam || current && current.parentElement,
|
||
path = DOM.getCurrentDirPath(panel),
|
||
link = CloudFunc.FS + path,
|
||
notSlashlLink = CloudFunc.rmLastSlash(link);
|
||
|
||
CloudCmd.loadDir({
|
||
path : notSlashlLink,
|
||
isRefresh : NEEDREFRESH,
|
||
panel: panel
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Функция загружает json-данные о Файловой Системе
|
||
* через ajax-запрос.
|
||
* @param path - каталог для чтения
|
||
* @param pOptions
|
||
* { refresh, nohistory } - необходимость обновить данные о каталоге
|
||
*/
|
||
function ajaxLoad(path, options, panel) {
|
||
var SLASH = '/',
|
||
fsPath = decodeURI(path),
|
||
cleanPath = Util.rmStrOnce(fsPath, CloudFunc.FS) || SLASH;
|
||
|
||
if (!options)
|
||
options = {};
|
||
|
||
Util.log ('reading dir: "' + cleanPath + '";');
|
||
|
||
Storage.get(cleanPath, function(error, json) {
|
||
var RESTful = DOM.RESTful,
|
||
obj = Util.parseJSON(json),
|
||
isRefresh = options.refresh,
|
||
nohistory = options.nohistory;
|
||
|
||
if (!isRefresh && json)
|
||
createFileTable(obj, panel, nohistory);
|
||
else
|
||
RESTful.read(cleanPath, 'json', function(obj) {
|
||
createFileTable(obj, panel, nohistory);
|
||
Storage.set(cleanPath, obj);
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Функция строит файловую таблицу
|
||
* @param json - данные о файлах
|
||
* @param panelParam
|
||
* @param nohistory
|
||
*/
|
||
function createFileTable(json, panelParam, nohistory) {
|
||
var files,
|
||
panel = panelParam || DOM.getPanel(),
|
||
/* getting current element if was refresh */
|
||
path = DOM.getCurrentDirPath(panel),
|
||
wasRefresh = path === json.path,
|
||
funcs = [
|
||
CloudCmd.getFileTemplate,
|
||
CloudCmd.getPathTemplate,
|
||
CloudCmd.getPathLinkTemplate,
|
||
CloudCmd.getLinkTemplate
|
||
];
|
||
|
||
Util.exec.parallel(funcs, function(error, templFile, templPath, templPathLink, templLink) {
|
||
var n, found, varCurrent, varName, current,
|
||
dir = DOM.getCurrentDirName(),
|
||
name = DOM.getCurrentName(),
|
||
i = panel.childNodes.length;
|
||
|
||
while(i--)
|
||
panel.removeChild(panel.lastChild);
|
||
|
||
panel.innerHTML = CloudFunc.buildFromJSON({
|
||
data : json,
|
||
id : panel.id,
|
||
template : {
|
||
file : templFile,
|
||
path : templPath,
|
||
pathLink : templPathLink,
|
||
link : templLink
|
||
}
|
||
});
|
||
|
||
files = DOM.getFiles(panel);
|
||
|
||
/* searching current file */
|
||
if (wasRefresh) {
|
||
n = files.length;
|
||
|
||
for (i = 0; i < n ; i++) {
|
||
varCurrent = files[i],
|
||
varName = DOM.getCurrentName(varCurrent);
|
||
found = varName === name;
|
||
|
||
if (found) {
|
||
current = files[i];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (!found) /* .. */
|
||
current = files[0];
|
||
|
||
DOM.setCurrentFile(current, {
|
||
nohistory: nohistory
|
||
});
|
||
|
||
Listeners.setOnPanel(panel.id);
|
||
|
||
if (name === '..' && dir !== '/')
|
||
currentToParent(dir);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Функция генерирует JSON из html-таблицы файлов и
|
||
* используеться при первом заходе в корень
|
||
*/
|
||
function getJSONfromFileTable() {
|
||
var current, name, size, owner, mode, ret,
|
||
path = DOM.getCurrentDirPath(),
|
||
infoFiles = Info.files,
|
||
|
||
fileTable = {
|
||
path : path,
|
||
files : []
|
||
},
|
||
|
||
files = fileTable.files,
|
||
|
||
i, n = infoFiles.length;
|
||
|
||
for (i = 0; i < n; i++) {
|
||
current = infoFiles[i];
|
||
name = DOM.getCurrentName(current);
|
||
size = DOM.getCurrentSize(current);
|
||
owner = DOM.getCurrentOwner(current);
|
||
mode = DOM.getCurrentMode(current);
|
||
|
||
mode = CloudFunc.getNumericPermissions(mode);
|
||
|
||
if (name !== '..')
|
||
files.push({
|
||
name : name,
|
||
size : size,
|
||
mode : mode,
|
||
owner : owner
|
||
});
|
||
}
|
||
|
||
ret = Util.stringifyJSON(fileTable);
|
||
|
||
return ret;
|
||
}
|
||
|
||
this.goToParentDir = function() {
|
||
var path = Info.dirPath,
|
||
parentPath = Info.parentDirPath;
|
||
|
||
if (path !== parentPath) {
|
||
path = parentPath;
|
||
path = CloudFunc.FS + CloudFunc.rmLastSlash(path);
|
||
|
||
CloudCmd.loadDir({
|
||
path: path
|
||
});
|
||
}
|
||
};
|
||
|
||
}
|
||
})(this, Util, DOM, CloudFunc);
|