cloudcmd/lib/client/dom.js

1624 lines
58 KiB
JavaScript

var CloudCmd, Util, DOM, CloudFunc, Dialog;
(function(Util, window) {
'use strict';
/* global rendy */
var DOMFunc = function() {},
DOMProto,
DialogProto = function() {
var self = this;
this.alert = alert.bind(window);
this.prompt = prompt.bind(window);
this.confirm = confirm.bind(window);
this.alert.noFiles = function() {
self.alert('No files selected!');
};
},
ImagesProto = function() {
var Images,
ImageElementProto = function() {
var LOADING = 'loading',
LoadingImage,
HIDDEN = 'hidden',
ERROR = 'error';
function init() {
var is;
if (!LoadingImage) {
LoadingImage = LOADING;
is = DOM.isSVG();
if (is)
LoadingImage += '-svg';
else
LoadingImage += '-gif';
}
}
function getElement() {
var element;
init();
element = DOM.load({
name : 'span',
id : 'js-status-image',
className : 'icon',
attribute : 'data-progress',
notAppend : true
});
return element;
}
this.get = getElement;
/* Функция создаёт картинку загрузки */
this.loading = function() {
var element = getElement(),
classList = element.classList;
classList.add(LOADING, LoadingImage);
classList.remove(ERROR, HIDDEN);
return element;
};
/* Функция создаёт картинку ошибки загрузки */
this.error = function() {
var element = getElement(),
classList = element.classList;
classList.add(ERROR);
classList.remove(HIDDEN, LOADING, LoadingImage);
return element;
};
};
Images = new ImageElementProto();
this.show = load;
this.show.load = load;
this.show.error = error;
/**
* Function shows loading spinner
* position = {top: true};
*/
function load(position, panel) {
var current,
image = Images.loading(),
parent = image.parentElement,
refreshButton = DOM.getRefreshButton(panel);
if (position === 'top') {
current = refreshButton.parentElement;
} else {
current = DOM.getCurrentFile();
if (current)
current = DOM.getByDataName('js-name', current);
else
current = refreshButton.parentElement;
}
if (!parent || (parent && parent !== current))
current.appendChild(image);
DOM.show(image);
return image;
}
function error(text) {
var image = Images.error();
DOM.show(image);
image.title = text;
CloudCmd.log(text);
return image;
}
/**
* hide load image
*/
this.hide = function() {
var element = Images.get();
DOM.hide(element);
return this;
};
this.setProgress = function(value, title) {
var DATA = 'data-progress',
element = Images.get();
if (element) {
element.setAttribute(DATA, value + '%');
if (title)
element.title = title;
}
return this;
};
this.clearProgress = function() {
var DATA = 'data-progress',
element = Images.get();
if (element) {
element.setAttribute(DATA, '');
element.title = '';
}
return this;
};
},
DOMTreeProto = function() {
var DOM = this;
/**
* check class of element
*
* @param element
* @param pClass
*/
this.isContainClass = function(element, className) {
var ret, classList;
if (!element)
throw(Error('element could not be empty!'));
if (!className)
throw(Error('className could not be empty!'));
classList = element.classList;
ret = classList.contains(className);
return ret;
};
/**
* Function search element by tag
* @param pTag - className
* @param element - element
*/
this.getByTag = function(pTag, element) {
return (element || document).getElementsByTagName(pTag);
};
/**
* Function search element by id
* @param Id - id
*/
this.getById = function(id, element) {
return (element || document).querySelector('#' + id);
};
/**
* Function search first element by class name
* @param pClass - className
* @param element - element
*/
this.getByClass = function(pClass, elementParam) {
var element = elementParam || document,
ret = this.getByClassAll(pClass, element)[0];
return ret;
};
this.getByDataName = function(attribute, element) {
var ret,
selector = '[' + 'data-name="' + attribute + '"]';
if (!element)
element = document;
ret = element.querySelector(selector);
return ret;
};
/**
* Function search element by class name
* @param pClass - className
* @param element - element
*/
this.getByClassAll = function(pClass, element) {
return (element || document).getElementsByClassName(pClass);
};
/**
* check SVG SMIL animation support
*/
this.isSVG = function() {
var ret, svgNode, name,
create = document.createElementNS,
SVG_URL = 'http://www.w3.org/2000/svg';
if (create) {
create = create.bind(document);
svgNode = create(SVG_URL, 'animate');
name = svgNode.toString();
ret = /SVGAnimate/.test(name);
}
return ret;
};
/**
* add class=hidden to element
*
* @param element
*/
this.hide = function(element) {
element.classList.add('hidden');
return DOM;
};
this.show = function(element) {
element.classList.remove('hidden');
return DOM;
};
},
CmdProto = function() {
var Cmd = this,
CurrentInfo = {},
CURRENT_FILE = 'current-file',
SELECTED_FILE = 'selected-file',
SelectType = '*.*',
Title,
TabPanel = {
'js-left' : null,
'js-right' : null
};
/**
* private function thet unset currentfile
*
* @currentFile
*/
function unsetCurrentFile(currentFile) {
var ret = DOM.isCurrentFile(currentFile);
if (ret)
currentFile.classList.remove(CURRENT_FILE);
return ret;
}
this.loadRemote = function(name, options, callback) {
var o = options,
Files = DOM.Files;
if (!callback)
callback = options;
if (o.name && window[o.name])
callback();
else
Files.get(['config', 'modules'], function(error, config, modules) {
var remoteTmpls, local, remote,
load = DOM.load,
prefix = CloudCmd.PREFIX,
online = config.online && navigator.onLine,
remoteObj = Util.findObjByNameInArr(modules, 'remote'),
module = Util.findObjByNameInArr(remoteObj, name),
isArray = Util.type.array(module.local),
version = module.version,
funcON = function() {
load.parallel(remote, function(error) {
if (error)
funcOFF();
else
callback();
});
},
funcOFF = function() {
load.parallel(local, callback);
};
if (isArray) {
remoteTmpls = module.remote;
local = module.local;
} else {
remoteTmpls = [module.remote];
local = [module.local];
}
local = local.map(function(url) {
return o.noPrefix ? url : prefix + url;
});
remote = remoteTmpls.map(function(tmpl) {
return rendy(tmpl, {
version: version
});
});
Util.exec.if(online, funcON, funcOFF);
});
return DOM;
};
/**
* load jquery from google cdn or local copy
* @param callback
*/
this.loadJquery = function(callback) {
DOM.loadRemote('jquery', {
name : '$',
noPrefix: true
}, callback);
return DOM;
};
this.loadSocket = function(callback) {
DOM.loadRemote('socket', {
name : 'io',
noPrefix: true
}, callback);
return DOM;
};
/** function loads css and js of Menu
* @param callback
*/
this.loadMenu = function(callback) {
return DOM.loadRemote('menu', callback);
};
this.uploadFiles = function(dir, files) {
var array,
slice = [].slice,
i = 0,
n = 0,
func = function(name) {
return function() {
CloudCmd.refresh(null, function() {
var current = DOM.getCurrentByName(name);
DOM.setCurrentFile(current);
});
};
},
percent = function(i, n, per) {
var value;
if (!per)
per = 100;
value = Math.round(i * per / n);
return value;
},
step = function(n) {
return 100 / n;
},
load = function(file, callback) {
var uploader,
Images = DOM.Images,
name = file.name,
path = dir + name;
++i;
uploader = DOM.load.put(path, file);
uploader.on('progress', function(count) {
var max = step(n),
value = (i - 1) * max + percent(count, 100, max);
Images.show.load('top');
Images.setProgress(Math.round(value));
});
uploader.on('end', callback);
};
if (!files) {
files = dir;
dir = CurrentInfo.dirPath;
}
n = files.length;
array = slice.call(files);
if (n) {
Util.exec.eachSeries(array, load, func(files[0].name));
}
};
/**
* create new folder
*
*/
this.promptNewDir = function() {
promptNew('directory', '?dir');
};
/**
* create new file
*
* @typeName
* @type
*/
this.promptNewFile = function() {
promptNew('file');
};
function promptNew(typeName, type) {
var RESTful = DOM.RESTful,
path = '',
name = Cmd.getCurrentName(),
dir = Cmd.getCurrentDirPath(),
msg = 'New ' + typeName || 'File';
if (name === '..')
name = '';
name = Dialog.prompt(msg, name);
path = dir + name;
if (type)
path += type;
if (name)
RESTful.write(path, function(error) {
!error && CloudCmd.refresh(null, function() {
var current = DOM.getCurrentByName(name);
DOM.setCurrentFile(current);
});
});
}
/**
* get current direcotory name
*/
this.getCurrentDirName = function() {
var ret,
substr,
/* получаем имя каталога в котором находимся */
href = this.getCurrentDirPath();
href = href.replace(/\/$/, '');
substr = href.substr(href, href.lastIndexOf('/'));
ret = href.replace(substr + '/', '') || '/';
return ret;
};
/**
* get current direcotory path
*/
this.getCurrentDirPath = function(panel) {
var ret, path;
if (!panel)
panel = this.getPanel();
path = this.getByDataName('js-path', panel);
ret = path && path.textContent;
return ret;
};
/**
* get current direcotory path
*/
this.getParentDirPath = function(panel) {
var path = DOM.getCurrentDirPath(panel),
dirName = DOM.getCurrentDirName() + '/';
if (path !== '/')
path = path.replace(dirName, '');
return path;
};
/**
* get not current direcotory path
*/
this.getNotCurrentDirPath = function() {
var panel = this.getPanel({active: false}),
path = this.getCurrentDirPath(panel);
return path;
};
/**
* unified way to get current file
*
* @currentFile
*/
this.getCurrentFile = function() {
var ret = this.getByClass(CURRENT_FILE);
return ret;
};
/**
* get current file by name
*/
this.getCurrentByName = function(name, panelParam) {
var element,
panel = panelParam || CurrentInfo.panel;
name = 'js-file-' + name;
element = DOM.getByDataName(name, panel);
return element;
};
/**
* unified way to get current file
*
* @currentFile
*/
this.getSelectedFiles = function() {
var panel = DOM.getPanel(),
selected = this.getByClassAll(SELECTED_FILE, panel),
ret = [].slice.call(selected);
return ret;
};
/**
* get all selected files with current included
*
* @currentFile
*/
this.getActiveFiles = function() {
var current = DOM.getCurrentFile(),
files = DOM.getSelectedFiles(),
selected = ~files.indexOf(current),
name = DOM.getCurrentName(current);
if (!selected && name !== '..')
files.push(current);
return files;
};
/**
* get size
* @currentFile
*/
this.getCurrentSize = function(currentFile) {
var current = currentFile || Cmd.getCurrentFile(),
size = this.getByDataName('js-size', current);
/* если это папка - возвращаем слово dir вместо размера*/
size = size
.textContent
.replace(/^<|>$/g, '');
return size;
};
/**
* get size
* @currentFile
*/
this.loadCurrentSize = function(callback, currentFile) {
var RESTful = DOM.RESTful,
Images = DOM.Images,
current = currentFile || this.getCurrentFile(),
query = '?size',
link = this.getCurrentPath(current);
Images.show.load();
if (name !== '..')
RESTful.read(link + query, function(error, size) {
if (!error) {
DOM.setCurrentSize(size, current);
Util.exec(callback, current);
Images.hide();
}
});
};
/**
* load hash
* @callback
* @currentFile
*/
this.loadCurrentHash = function(callback, currentFile) {
var RESTful = DOM.RESTful,
current = currentFile || DOM.getCurrentFile(),
query = '?hash',
link = DOM.getCurrentPath(current);
RESTful.read(link + query, callback);
};
/**
* load current modification time of file
* @callback
* @currentFile
*/
this.loadCurrentTime = function(callback, currentFile) {
var RESTful = DOM.RESTful,
current = currentFile || this.getCurrentFile(),
query = '?time',
link = this.getCurrentPath(current);
RESTful.read(link + query, callback);
};
/**
* set size
* @currentFile
*/
this.setCurrentSize = function(size, currentFile) {
var current = currentFile || this.getCurrentFile(),
sizeElement = this.getByDataName('js-size', current);
sizeElement.textContent = size;
};
/**
* @currentFile
*/
this.getCurrentMode = function(currentFile) {
var ret,
current = currentFile || this.getCurrentFile(),
lMode = this.getByDataName('js-mode', current);
ret = lMode.textContent;
return ret;
};
/**
* @currentFile
*/
this.getCurrentOwner = function(currentFile) {
var ret,
current = currentFile || this.getCurrentFile(),
owner = this.getByDataName('js-owner', current);
ret = owner.textContent;
return ret;
};
/**
* unified way to get current file content
*
* @param callback
* @param currentFile
*/
this.getCurrentData = function(callback, currentFile) {
var hash,
RESTful = DOM.RESTful,
Info = DOM.CurrentInfo,
current = currentFile || DOM.getCurrentFile(),
path = DOM.getCurrentPath(current),
isDir = DOM.isCurrentIsDir(current),
func = function(error, data) {
var length,
ONE_MEGABYTE = 1024 * 1024 * 1024;
if (!error) {
if (Util.type.object(data))
data = Util.json.stringify(data);
length = data.length;
if (hash && length < ONE_MEGABYTE)
DOM.saveDataToStorage(path, data, hash);
}
callback(error, data);
};
if (Info.name === '..') {
Dialog.alert.noFiles();
callback(Error('No files selected!'));
} else if (isDir) {
RESTful.read(path, func);
} else {
DOM.checkStorageHash(path, function(error, equal, hashNew) {
Util.exec.if(!error && equal, function() {
DOM.getDataFromStorage(path, callback);
}, function() {
hash = hashNew;
RESTful.read(path, func);
});
});
}
};
/**
* unified way to save current file content
*
* @callback - function({data, name}) {}
* @currentFile
*/
this.saveCurrentData = function(url, data, callback, query) {
if (!query)
query = '';
DOM.RESTful.write(url + query, data, function(error) {
!error && DOM.saveDataToStorage(url, data);
});
};
/**
* unified way to get RefreshButton
*/
this.getRefreshButton = function(panel) {
var currentPanel = panel || this.getPanel(),
refresh = this.getByDataName('js-refresh', currentPanel);
return refresh;
};
/**
* unified way to set current file
*/
this.setCurrentFile = function(currentFile, options) {
var ret, path, pathWas, title,
o = options,
FS = CloudFunc.FS,
CENTER = true,
currentFileWas = this.getCurrentFile();
if (currentFile) {
if (currentFileWas) {
pathWas = DOM.getCurrentDirPath();
unsetCurrentFile(currentFileWas);
}
currentFile.classList.add(CURRENT_FILE);
path = DOM.getCurrentDirPath();
if (path !== pathWas) {
title = CloudFunc.getTitle(path);
this.setTitle(title);
/* history could be present
* but it should be false
* to prevent default behavior
*/
if (!o || o.history !== false) {
if (path !== '/')
path = FS + path;
DOM.setHistory(path, null, path);
}
}
/* scrolling to current file */
this.scrollIntoViewIfNeeded(currentFile, CENTER);
ret = true;
Cmd.updateCurrentInfo();
}
return this;
};
/*
* set current file by position
*
* @param layer - element
* @param - position {x, y}
*/
this.getCurrentByPosition = function(position) {
var element, tag, isChild,
x = position.x,
y = position.y;
element = document.elementFromPoint(x, y),
tag = element.tagName;
isChild = /A|SPAN|LI/.test(tag);
if (!isChild) {
element = null;
} else {
switch (tag) {
case 'A':
element = element.parentElement.parentElement;
break;
case 'SPAN':
element = element.parentElement;
break;
}
}
if (element && element.tagName !== 'LI')
element = null;
return element;
};
/**
* select current file
* @param currentFile
*/
this.toggleSelectedFile = function(currentFile) {
var current = currentFile || this.getCurrentFile();
current.classList.toggle(SELECTED_FILE);
return Cmd;
};
this.toggleAllSelectedFiles = function() {
var i, n,
panel = DOM.getPanel(),
files = DOM.getFiles(panel),
name = DOM.getCurrentName(files[0]);
if (name === '..')
i = 1;
else
i = 0;
n = files.length;
for (; i < n; i++)
DOM.toggleSelectedFile(files[i]);
return Cmd;
};
function selectByPattern(msg, files) {
var n, regExp,
allMsg = 'Specify file type for ' + msg + ' selection',
i = 0,
type,
matches = 0,
name,
shouldSel = msg === 'expand',
isSelected, isMatch,
current;
type = Dialog.prompt(allMsg, SelectType);
if (type !== null) {
SelectType = type;
regExp = Util.getRegExp(type);
n = files && files.length;
for (i = 0; i < n; i++) {
current = files[i];
name = DOM.getCurrentName(current);
if (name !== '..') {
isMatch = regExp.test(name);
if (isMatch) {
++matches;
isSelected = DOM.isSelected(current);
if (shouldSel)
isSelected = !isSelected;
if (isSelected)
DOM.toggleSelectedFile(current);
}
}
}
if (!matches)
Dialog.alert('No matches found!');
}
}
/**
* open dialog with expand selection
*/
this.expandSelection = function() {
var msg = 'expand',
files = CurrentInfo.files;
selectByPattern(msg, files);
};
/**
* open dialog with shrink selection
*/
this.shrinkSelection = function() {
var msg = 'shrink',
files = DOM.getSelectedFiles();
selectByPattern(msg, files);
};
/**
* setting history wrapper
*/
this.setHistory = function(data, pTitle, url) {
var ret = window.history;
url = CloudCmd.PREFIX + url;
if (ret)
history.pushState(data, pTitle, url);
return ret;
};
/**
* set title or create title element
*
* @param name
*/
this.setTitle = function(name) {
if (!Title)
Title = DOM.getByTag('title')[0] ||
DOM.load({
name : 'title',
innerHTML : name,
parentElement : document.head
});
Title.textContent = name;
return this;
};
/**
* current file check
*
* @param currentFile
*/
this.isCurrentFile = function(currentFile) {
var ret;
if (currentFile)
ret = this.isContainClass(currentFile, CURRENT_FILE);
return ret;
};
/**
* selected file check
*
* @param currentFile
*/
this.isSelected = function(pSelected) {
var ret;
if (pSelected)
ret = this.isContainClass(pSelected, SELECTED_FILE);
return ret;
};
/**
* check is current file is a directory
*
* @param currentFile
*/
this.isCurrentIsDir = function(currentFile) {
var current = currentFile || this.getCurrentFile(),
fileType = this.getByDataName('js-type', current),
ret = this.isContainClass(fileType, 'directory');
return ret;
};
/**
* get link from current (or param) file
*
* @param currentFile - current file by default
*/
this.getCurrentLink = function(currentFile) {
var current = currentFile || this.getCurrentFile(),
link = this.getByTag('a', current);
return link[0];
};
/**
* get link from current (or param) file
*
* @param currentFile - current file by default
*/
this.getCurrentPath = function(currentFile) {
var current = currentFile || DOM.getCurrentFile(),
element = DOM.getByTag('a', current)[0],
path = element.getAttribute('href');
path = path.replace(CloudFunc.FS, '');
return path;
};
/**
* get name from current (or param) file
*
* @param currentFile
*/
this.getCurrentName = function(currentFile) {
var link,
name = '',
current = currentFile || this.getCurrentFile();
if (current)
link = this.getCurrentLink(current);
if (link) {
name = link.title;
}
return name;
};
this.getSelectedNames = function(selected) {
var first, name, isSelected,
ret = [];
if (!selected)
selected = this.getSelectedFiles() || [];
first = selected[0];
if (first) {
name = this.getCurrentName(first);
} else {
first = this.getCurrentFile();
name = this.getCurrentName(first);
}
isSelected = this.isSelected(first);
if (name === '..' && isSelected) {
selected.shift();
this.toggleSelectedFile(first);
}
ret = selected.map(function(current) {
return Cmd.getCurrentName(current);
});
return ret;
};
/**
* set name from current (or param) file
*
* @param name
* @param current
*/
this.setCurrentName = function(name, current) {
var Info = CurrentInfo,
link = Info.link,
FS = CloudFunc.FS,
dir = FS + Info.dirPath;
link.title = name;
link.innerHTML = CloudFunc.Entity.encode(name);
link.href = dir + name;
current.setAttribute('data-name', 'js-file-' + name);
return link;
};
/**
* check storage hash
*/
this.checkStorageHash = function(name, callback) {
var Storage = DOM.Storage,
parallel = Util.exec.parallel,
loadHash = DOM.loadCurrentHash,
nameHash = name + '-hash',
getStoreHash = Util.exec.with(Storage.get, nameHash);
Util.check(arguments, ['name', 'callback']);
parallel([loadHash, getStoreHash], function(error, loadHash, storeHash) {
var equal,
isContain = /error/.test(loadHash);
if (isContain)
error = loadHash;
else if (loadHash === storeHash)
equal = true;
callback(error, equal, loadHash);
});
};
/**
* save data to storage
*
* @param name
* @param data
* @param callback
*/
this.saveDataToStorage = function(name, data, hash, callback) {
DOM.Files.get('config', function(error, config) {
var allowed = config.localStorage,
isDir = DOM.isCurrentIsDir(),
nameHash = name + '-hash',
nameData = name + '-data';
if (!allowed || isDir)
Util.exec(callback);
else
Util.exec.if(hash, function() {
var Storage = DOM.Storage;
Storage.set(nameHash, hash);
Storage.set(nameData, data);
Util.exec(callback, hash);
}, function(callback) {
DOM.loadCurrentHash(function(error, loadHash) {
hash = loadHash;
callback();
});
});
});
};
/**
* save data to storage
*
* @param name
* @param data
* @param callback
*/
this.getDataFromStorage = function(name, callback) {
DOM.Files.get('config', function(error, config) {
var Storage = DOM.Storage,
nameHash = name + '-hash',
nameData = name + '-data',
allowed = config.localStorage,
isDir = DOM.isCurrentIsDir();
if (!allowed || isDir)
Util.exec(callback);
else {
Util.exec.parallel([
function(callback) {
Storage.get(nameData, callback);
},
function(callback) {
Storage.get(nameHash, callback);
}
], callback);
}
});
};
/** function getting FM
* @param pPanel_o = {active: true}
*/
this.getFM = function() {
return this.getPanel().parentElement;
};
/** function getting panel active, or passive
* @param options = {active: true}
*/
this.getPanel = function(options) {
var files, panel, isLeft,
dataName = 'js-',
current = this.getCurrentFile();
if (!current) {
panel = this.getByDataName('js-left');
} else {
files = current.parentElement,
panel = files.parentElement,
isLeft = panel.getAttribute('data-name') === 'js-left';
}
/* if {active : false} getting passive panel */
if (options && !options.active) {
dataName += isLeft ? 'right' : 'left';
panel = this.getByDataName(dataName);
}
/* if two panels showed
* then always work with passive
* panel
*/
if (window.innerWidth < CloudCmd.MIN_ONE_PANEL_WIDTH)
panel = this.getByDataName('js-left');
if (!panel)
throw(Error('can not find Active Panel!'));
return panel;
};
this.getFiles = function(element) {
var files = DOM.getByDataName('js-files', element),
ret = files.children || [];
return ret;
};
/**
* shows panel right or left (or active)
*/
this.showPanel = function(active) {
var ret = true,
panel = this.getPanel({active: active});
if (panel)
this.show(panel);
else
ret = false;
return ret;
};
/**
* hides panel right or left (or active)
*/
this.hidePanel = function(active) {
var ret = false,
panel = this.getPanel({active: active});
if (panel)
ret = this.hide(panel);
return ret;
};
/**
* open window with URL
* @param url
*/
this.openWindow = function(url) {
var left = 140,
top = 187,
width = 1000,
height = 650,
options = 'left=' + left +
',top=' + top +
',width=' + width +
',height=' + height +
',personalbar=0,toolbar=0' +
',scrollbars=1,resizable=1',
wnd = window.open(url, 'Cloud Commander Auth', options);
if (!wnd)
Dialog.alert('Please disable your popup blocker and try again.');
return wnd;
};
/**
* remove child of element
* @param pChild
* @param element
*/
this.remove = function(child, element) {
var parent = element || document.body;
parent.removeChild(child);
return DOM;
};
/**
* remove current file from file table
* @param current
*
*/
this.deleteCurrent = function(current) {
var name, next, prev, parent, currentNew;
if (!current)
Cmd.getCurrentFile();
parent = current && current.parentElement;
name = Cmd.getCurrentName(current);
if (current && name !== '..') {
next = current.nextSibling,
prev = current.previousSibling;
if (next)
currentNew = next;
else if (prev)
currentNew = prev;
this.setCurrentFile(currentNew);
parent.removeChild(current);
}
return currentNew;
};
/**
* remove selected files from file table
* @Selected
*/
this.deleteSelected = function(selected) {
var i, n, current;
if (!selected)
selected = this.getSelectedFiles();
if (selected) {
n = selected.length;
for (i = 0; i < n; i++) {
current = selected[i];
this.deleteCurrent(current);
}
}
return selected;
};
/**
* rename current file
*
* @currentFile
*/
this.renameCurrent = function(current) {
var from, to, dirPath, files, isExist,
RESTful = DOM.RESTful;
if (!Cmd.isCurrentFile(current))
current = Cmd.getCurrentFile();
from = Cmd.getCurrentName(current);
if (from === '..') {
Dialog.alert.noFiles();
} else {
to = Dialog.prompt('Rename', from) || from;
isExist = !!DOM.getCurrentByName(to);
dirPath = Cmd.getCurrentDirPath();
if (from !== to) {
files = {
from : dirPath + from,
to : dirPath + to
};
RESTful.mv(files, function(error) {
var Storage = DOM.Storage;
if (!error) {
DOM.setCurrentName(to, current);
Cmd.updateCurrentInfo();
Storage.remove(dirPath);
if (isExist)
CloudCmd.refresh();
}
});
}
}
};
/**
* unified way to scrollIntoViewIfNeeded
* (native suporte by webkit only)
* @param element
* @param pCenter
*/
this.scrollIntoViewIfNeeded = function(element, center) {
var ret = element && element.scrollIntoViewIfNeeded;
/* for scroll as small as possible
* param should be false
*/
if (arguments.length === 1)
center = false;
if (ret)
element.scrollIntoViewIfNeeded(center);
return ret;
};
/* scroll on one page*/
this.scrollByPages = function(element, pPages) {
var ret = element && element.scrollByPages && pPages;
if (ret)
element.scrollByPages(pPages);
return ret;
};
this.changePanel = function() {
var dataName, files, current,
panel = DOM.getPanel(),
panelPassive = DOM.getPanel({
active: false
}),
name = DOM.getCurrentName(),
filesPassive = DOM.getFiles(panelPassive);
dataName = panel.getAttribute('data-name');
TabPanel[dataName] = name;
panel = panelPassive;
dataName = panel.getAttribute('data-name');
name = TabPanel[dataName];
if (name) {
current = DOM.getCurrentByName(name, panel);
if (current)
files = current.parentElement;
}
if (!files || !files.parentElement) {
current = DOM.getCurrentByName(name, panel);
if (!current)
current = filesPassive[0];
}
DOM.setCurrentFile(current, {
history: true
});
return this;
};
this.goToDirectory = function() {
var msg = 'Go to directory:',
path = CurrentInfo.dirPath;
path = prompt(msg, path);
path && CloudCmd.loadDir({
path: path
});
},
this.duplicatePanel = function() {
var isDir = CurrentInfo.isDir,
path = CurrentInfo.dirPath,
panel = CurrentInfo.panelPassive;
if (isDir)
path = CurrentInfo.path;
CloudCmd.loadDir({
path: path,
panel: panel,
noCurrent: true
});
};
this.swapPanels = function() {
var Info = CurrentInfo,
panel = Info.panel,
panelPassive = Info.panelPassive,
currentIndex = [].indexOf.call(Info.files, Info.element),
dirPath = DOM.getCurrentDirPath(),
dirPathPassive = DOM.getNotCurrentDirPath();
CloudCmd.loadDir({
path: dirPath,
panel: panelPassive,
noCurrent: true
});
CloudCmd.loadDir({
path: dirPathPassive,
panel: panel
}, function() {
var el,
files = Info.files,
length = files.length - 1;
if (currentIndex > length)
currentIndex = length;
el = files[currentIndex];
DOM.setCurrentFile(el);
});
};
this.CurrentInfo = CurrentInfo,
this.updateCurrentInfo = function(currentFile) {
var info = Cmd.CurrentInfo,
current = currentFile || Cmd.getCurrentFile(),
files = current.parentElement,
panel = files.parentElement,
panelPassive = Cmd.getPanel({
active: false
}),
filesPassive = DOM.getFiles(panelPassive),
name = Cmd.getCurrentName(current);
info.dir = Cmd.getCurrentDirName();
info.dirPath = Cmd.getCurrentDirPath();
info.parentDirPath = Cmd.getParentDirPath();
info.element = current;
info.ext = Util.getExt(name);
info.files = files.children,
info.filesPassive = filesPassive,
info.first = files.firstChild;
info.getData = Cmd.getCurrentData;
info.last = files.lastChild;
info.link = Cmd.getCurrentLink(current);
info.mode = Cmd.getCurrentMode(current);
info.name = name;
info.path = Cmd.getCurrentPath(current);
info.panel = panel;
info.panelPassive = panelPassive;
info.size = Cmd.getCurrentSize(current);
info.isDir = Cmd.isCurrentIsDir();
info.isSelected = Cmd.isSelected(current);
info.isOnePanel =
info.panel.getAttribute('data-name') ===
info.panelPassive.getAttribute('data-name');
};
},
DOMTree = Util.extendProto(DOMTreeProto),
Images = Util.extendProto(ImagesProto);
DOMProto = DOMFunc.prototype = new CmdProto();
Dialog = new DialogProto();
Util.extend(DOMProto, [
DOMTree, {
Images : Images,
Dialog : Dialog
}
]);
DOM = new DOMFunc();
})(Util, window);