mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 18:55:26 +00:00
feature(cloudcmd) add ability to use not only alphabet and number symbols (#167)
This commit is contained in:
parent
48c36eb5d3
commit
5479dce7da
8 changed files with 199 additions and 117 deletions
87
client/dom/current-file.js
Normal file
87
client/dom/current-file.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
'use strict';
|
||||
|
||||
/* global DOM */
|
||||
/* global CloudCmd */
|
||||
|
||||
const {
|
||||
encode,
|
||||
decode,
|
||||
} = require('../../common/entity');
|
||||
|
||||
const {
|
||||
FS,
|
||||
} = require('../../common/cloudfunc');
|
||||
|
||||
const NBSP_REG = RegExp(String.fromCharCode(160), 'g');
|
||||
const SPACE = ' ';
|
||||
|
||||
/**
|
||||
* set name from current (or param) file
|
||||
*
|
||||
* @param name
|
||||
* @param current
|
||||
*/
|
||||
module.exports.setCurrentName = (name, current) => {
|
||||
const Info = DOM.CurrentInfo;
|
||||
const {link} = Info;
|
||||
const {PREFIX} = CloudCmd;
|
||||
const dir = PREFIX + FS + Info.dirPath;
|
||||
const encoded = encode(name);
|
||||
|
||||
link.title = encoded;
|
||||
link.href = dir + encoded;
|
||||
link.innerHTML = encoded;
|
||||
|
||||
current.setAttribute('data-name', 'js-file-' + btoa(name));
|
||||
CloudCmd.emit('current-file', current);
|
||||
|
||||
return link;
|
||||
};
|
||||
|
||||
/**
|
||||
* get name from current (or param) file
|
||||
*
|
||||
* @param currentFile
|
||||
*/
|
||||
module.exports.getCurrentName = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
|
||||
if (!current)
|
||||
return '';
|
||||
|
||||
const link = DOM.getCurrentLink(current);
|
||||
|
||||
if (!link)
|
||||
return '';
|
||||
|
||||
return decode(link.title)
|
||||
.replace(NBSP_REG, SPACE);
|
||||
};
|
||||
|
||||
/**
|
||||
* get current direcotory path
|
||||
*/
|
||||
module.exports.getCurrentDirPath = (panel = DOM.getPanel()) => {
|
||||
const path = DOM.getByDataName('js-path', panel);
|
||||
return path.textContent
|
||||
.replace(NBSP_REG, SPACE);
|
||||
};
|
||||
|
||||
/**
|
||||
* get link from current (or param) file
|
||||
*
|
||||
* @param currentFile - current file by default
|
||||
*/
|
||||
module.exports.getCurrentPath = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const element = DOM.getByTag('a', current)[0];
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
|
||||
const path = element
|
||||
.getAttribute('href')
|
||||
.replace(RegExp('^' + prefix + FS), '')
|
||||
.replace(NBSP_REG, SPACE);
|
||||
|
||||
return decode(path);
|
||||
};
|
||||
|
||||
|
|
@ -12,26 +12,29 @@ const {
|
|||
FS,
|
||||
} = require('../../common/cloudfunc');
|
||||
|
||||
const {encode} = require('../../common/entity');
|
||||
|
||||
const DOMTree = require('./dom-tree');
|
||||
|
||||
const DOM = Object.assign({}, DOMTree, new CmdProto());
|
||||
|
||||
module.exports = DOM;
|
||||
|
||||
const Images = require('./images');
|
||||
const load = require('./load');
|
||||
const Files = require('./files');
|
||||
const RESTful = require('./rest');
|
||||
const Storage = require('./storage');
|
||||
|
||||
const currentFile = require('./current-file');
|
||||
const DOMTree = require('./dom-tree');
|
||||
|
||||
const DOM = {
|
||||
...DOMTree,
|
||||
...currentFile,
|
||||
...new CmdProto(),
|
||||
};
|
||||
|
||||
DOM.Images = Images;
|
||||
DOM.load = load;
|
||||
DOM.Files = Files;
|
||||
DOM.RESTful = RESTful;
|
||||
DOM.Storage = Storage;
|
||||
|
||||
module.exports = DOM;
|
||||
|
||||
DOM.uploadDirectory = require('./directory');
|
||||
DOM.Buffer = require('./buffer');
|
||||
DOM.Events = require('./events');
|
||||
|
|
@ -103,10 +106,10 @@ function CmdProto() {
|
|||
|
||||
function promptNew(typeName, type) {
|
||||
const {Dialog} = DOM;
|
||||
const dir = Cmd.getCurrentDirPath();
|
||||
const dir = DOM.getCurrentDirPath();
|
||||
const msg = 'New ' + typeName || 'File';
|
||||
const getName = () => {
|
||||
const name = Cmd.getCurrentName();
|
||||
const name = DOM.getCurrentName();
|
||||
|
||||
if (name === '..')
|
||||
return '';
|
||||
|
|
@ -156,16 +159,6 @@ function CmdProto() {
|
|||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* get current direcotory path
|
||||
*/
|
||||
this.getCurrentDirPath = (panel = DOM.getPanel()) => {
|
||||
const path = DOM.getByDataName('js-path', panel);
|
||||
const ret = path && path.textContent;
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* get current direcotory path
|
||||
*/
|
||||
|
|
@ -202,7 +195,7 @@ function CmdProto() {
|
|||
* get current file by name
|
||||
*/
|
||||
this.getCurrentByName = (name, panel = CurrentInfo.panel) => {
|
||||
const dataName = 'js-file-' + name;
|
||||
const dataName = 'js-file-' + btoa(name);
|
||||
const element = DOM.getByDataName(dataName, panel);
|
||||
|
||||
return element;
|
||||
|
|
@ -246,7 +239,7 @@ function CmdProto() {
|
|||
};
|
||||
|
||||
this.getCurrentDate = (currentFile) => {
|
||||
const current = currentFile || Cmd.getCurrentFile();
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const date = DOM
|
||||
.getByDataName('js-date', current)
|
||||
.textContent;
|
||||
|
|
@ -259,7 +252,7 @@ function CmdProto() {
|
|||
* @currentFile
|
||||
*/
|
||||
this.getCurrentSize = (currentFile) => {
|
||||
const current = currentFile || Cmd.getCurrentFile();
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
/* если это папка - возвращаем слово dir вместо размера*/
|
||||
const size = DOM.getByDataName('js-size', current)
|
||||
.textContent
|
||||
|
|
@ -460,9 +453,9 @@ function CmdProto() {
|
|||
|
||||
currentFile.classList.add(CURRENT_FILE);
|
||||
|
||||
let path = DOM.getCurrentDirPath();
|
||||
|
||||
const path = DOM.getCurrentDirPath();
|
||||
const name = CloudCmd.config('name');
|
||||
|
||||
if (path !== pathWas) {
|
||||
DOM.setTitle(getTitle({
|
||||
name,
|
||||
|
|
@ -680,42 +673,6 @@ function CmdProto() {
|
|||
return link[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* get link from current (or param) file
|
||||
*
|
||||
* @param currentFile - current file by default
|
||||
*/
|
||||
this.getCurrentPath = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const element = DOM.getByTag('a', current)[0];
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const path = element.getAttribute('href')
|
||||
.replace(RegExp('^' + prefix + FS), '');
|
||||
|
||||
return path;
|
||||
};
|
||||
|
||||
/**
|
||||
* get name from current (or param) file
|
||||
*
|
||||
* @param currentFile
|
||||
*/
|
||||
this.getCurrentName = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
|
||||
if (!current)
|
||||
return '';
|
||||
|
||||
const link = DOM.getCurrentLink(current);
|
||||
|
||||
if (!link)
|
||||
return '';
|
||||
|
||||
const name = link.title;
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
this.getFilenames = (files) => {
|
||||
if (!files)
|
||||
throw Error('AllFiles could not be empty');
|
||||
|
|
@ -735,27 +692,6 @@ function CmdProto() {
|
|||
return names;
|
||||
};
|
||||
|
||||
/**
|
||||
* set name from current (or param) file
|
||||
*
|
||||
* @param name
|
||||
* @param current
|
||||
*/
|
||||
this.setCurrentName = (name, current) => {
|
||||
const Info = CurrentInfo;
|
||||
const link = Info.link;
|
||||
const PREFIX = CloudCmd.PREFIX;
|
||||
const dir = PREFIX + FS + Info.dirPath;
|
||||
|
||||
link.title = name;
|
||||
link.innerHTML = encode(name);
|
||||
link.href = dir + name;
|
||||
|
||||
current.setAttribute('data-name', 'js-file-' + name);
|
||||
|
||||
return link;
|
||||
};
|
||||
|
||||
/**
|
||||
* check storage hash
|
||||
*/
|
||||
|
|
@ -935,10 +871,10 @@ function CmdProto() {
|
|||
*/
|
||||
this.deleteCurrent = (current) => {
|
||||
if (!current)
|
||||
Cmd.getCurrentFile();
|
||||
DOM.getCurrentFile();
|
||||
|
||||
const parent = current && current.parentElement;
|
||||
const name = Cmd.getCurrentName(current);
|
||||
const name = DOM.getCurrentName(current);
|
||||
|
||||
if (current && name !== '..') {
|
||||
const next = current.nextSibling;
|
||||
|
|
@ -970,10 +906,10 @@ function CmdProto() {
|
|||
this.renameCurrent = (current) => {
|
||||
const Dialog = DOM.Dialog;
|
||||
|
||||
if (!Cmd.isCurrentFile(current))
|
||||
current = Cmd.getCurrentFile();
|
||||
if (!DOM.isCurrentFile(current))
|
||||
current = DOM.getCurrentFile();
|
||||
|
||||
const from = Cmd.getCurrentName(current);
|
||||
const from = DOM.getCurrentName(current);
|
||||
|
||||
if (from === '..')
|
||||
return Dialog.alert.noFiles(TITLE);
|
||||
|
|
@ -982,7 +918,7 @@ function CmdProto() {
|
|||
|
||||
Dialog.prompt(TITLE, 'Rename', from, {cancel}).then((to) => {
|
||||
const isExist = !!DOM.getCurrentByName(to);
|
||||
const dirPath = Cmd.getCurrentDirPath();
|
||||
const dirPath = DOM.getCurrentDirPath();
|
||||
|
||||
if (from === to)
|
||||
return;
|
||||
|
|
@ -1157,38 +1093,38 @@ function CmdProto() {
|
|||
this.CurrentInfo = CurrentInfo,
|
||||
|
||||
this.updateCurrentInfo = (currentFile) => {
|
||||
const info = Cmd.CurrentInfo;
|
||||
const current = currentFile || Cmd.getCurrentFile();
|
||||
const info = DOM.CurrentInfo;
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const files = current.parentElement;
|
||||
const panel = files.parentElement;
|
||||
|
||||
const panelPassive = Cmd.getPanel({
|
||||
const panelPassive = DOM.getPanel({
|
||||
active: false
|
||||
});
|
||||
|
||||
const filesPassive = DOM.getFiles(panelPassive);
|
||||
const name = Cmd.getCurrentName(current);
|
||||
const name = DOM.getCurrentName(current);
|
||||
|
||||
info.dir = Cmd.getCurrentDirName();
|
||||
info.dirPath = Cmd.getCurrentDirPath();
|
||||
info.parentDirPath = Cmd.getParentDirPath();
|
||||
info.dir = DOM.getCurrentDirName();
|
||||
info.dirPath = DOM.getCurrentDirPath();
|
||||
info.parentDirPath = DOM.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.getData = DOM.getCurrentData;
|
||||
info.last = files.lastChild;
|
||||
info.link = Cmd.getCurrentLink(current);
|
||||
info.mode = Cmd.getCurrentMode(current);
|
||||
info.link = DOM.getCurrentLink(current);
|
||||
info.mode = DOM.getCurrentMode(current);
|
||||
info.name = name;
|
||||
info.path = Cmd.getCurrentPath(current);
|
||||
info.path = DOM.getCurrentPath(current);
|
||||
info.panel = panel;
|
||||
info.panelPassive = panelPassive;
|
||||
info.size = Cmd.getCurrentSize(current);
|
||||
info.isDir = Cmd.isCurrentIsDir();
|
||||
info.isSelected = Cmd.isSelected(current);
|
||||
info.panelPosition = Cmd.getPanel().dataset.name.replace('js-', '');
|
||||
info.size = DOM.getCurrentSize(current);
|
||||
info.isDir = DOM.isCurrentIsDir();
|
||||
info.isSelected = DOM.isSelected(current);
|
||||
info.panelPosition = DOM.getPanel().dataset.name.replace('js-', '');
|
||||
info.isOnePanel =
|
||||
info.panel.getAttribute('data-name') ===
|
||||
info.panelPassive.getAttribute('data-name');
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
const itype = require('itype/legacy');
|
||||
|
||||
const {FS} = require('../../common/cloudfunc');
|
||||
const {
|
||||
encode,
|
||||
} = require('../../common/entity');
|
||||
|
||||
module.exports = new RESTful();
|
||||
|
||||
|
|
@ -194,10 +197,12 @@ function RESTful() {
|
|||
const statusText = jqXHR.statusText;
|
||||
const status = jqXHR.status;
|
||||
const text = status === 404 ? response : statusText;
|
||||
const encoded = encode(text);
|
||||
|
||||
Images.show.error(encoded);
|
||||
|
||||
Images.show.error(text);
|
||||
setTimeout(() => {
|
||||
DOM.Dialog.alert(CloudCmd.TITLE, text);
|
||||
DOM.Dialog.alert(CloudCmd.TITLE, encoded);
|
||||
}, 100);
|
||||
|
||||
p.callback(Error(text));
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ const currify = require('currify/legacy');
|
|||
const wraptile = require('wraptile/legacy');
|
||||
const exec = require('execon');
|
||||
|
||||
const {
|
||||
encode,
|
||||
} = require('../../../common/entity');
|
||||
|
||||
const RESTful = require('../../dom/rest');
|
||||
const removeExtension = require('./remove-extension');
|
||||
const setListeners = require('./set-listeners');
|
||||
|
|
@ -213,7 +217,7 @@ function OperationProto(operation, data) {
|
|||
if (n >= 5)
|
||||
name += '\n...';
|
||||
|
||||
msg = msgAsk + msgSel + n + ' files/directories?\n' + name ;
|
||||
msg = msgAsk + msgSel + n + ' files/directories?\n' + encode(name);
|
||||
} else {
|
||||
const current = DOM.getCurrentFile();
|
||||
const isDir = DOM.isCurrentIsDir(current);
|
||||
|
|
@ -312,7 +316,7 @@ function OperationProto(operation, data) {
|
|||
const operation = isCopy ? copyFn : moveFn;
|
||||
|
||||
if (shouldAsk && config(option))
|
||||
return message(title, to, names)
|
||||
return message(title, to, names.map(encode))
|
||||
.then(ask);
|
||||
|
||||
ask(to);
|
||||
|
|
@ -331,10 +335,10 @@ function OperationProto(operation, data) {
|
|||
function go() {
|
||||
showLoad();
|
||||
|
||||
files = {
|
||||
from : from,
|
||||
to : to,
|
||||
names : names
|
||||
files = {
|
||||
from,
|
||||
to,
|
||||
names,
|
||||
};
|
||||
|
||||
operation(files, (error) => {
|
||||
|
|
|
|||
13
common/btoa.js
Normal file
13
common/btoa.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
/* global btoa */
|
||||
|
||||
module.exports = (str) => {
|
||||
if (typeof btoa === 'function')
|
||||
return btoa(str);
|
||||
|
||||
return Buffer
|
||||
.from(str)
|
||||
.toString('base64');
|
||||
};
|
||||
|
||||
|
|
@ -4,6 +4,7 @@ const rendy = require('rendy');
|
|||
const currify = require('currify/legacy');
|
||||
const store = require('fullstore/legacy');
|
||||
const encode = require('./entity').encode;
|
||||
const btoa = require('./btoa');
|
||||
|
||||
const getHeaderField = currify(_getHeaderField);
|
||||
|
||||
|
|
@ -12,7 +13,6 @@ const getHeaderField = currify(_getHeaderField);
|
|||
/* название программы */
|
||||
const NAME = 'Cloud Commander';
|
||||
const FS = '/fs';
|
||||
|
||||
const Path = store();
|
||||
|
||||
Path('/');
|
||||
|
|
@ -96,6 +96,11 @@ function getPathLink(url, prefix, template) {
|
|||
return pathHTML;
|
||||
}
|
||||
|
||||
const getDataName = (name) => {
|
||||
const encoded = btoa(name);
|
||||
return `data-name="js-file-${encoded}" `;
|
||||
};
|
||||
|
||||
/**
|
||||
* Функция строит таблицу файлв из JSON-информации о файлах
|
||||
* @param params - информация о файлах
|
||||
|
|
@ -108,7 +113,7 @@ module.exports.buildFromJSON = (params) => {
|
|||
const templateLink = template.link;
|
||||
const json = params.data;
|
||||
|
||||
const path = json.path;
|
||||
const path = encode(json.path);
|
||||
const files = json.files;
|
||||
|
||||
const sort = params.sort || 'name';
|
||||
|
|
@ -123,7 +128,7 @@ module.exports.buildFromJSON = (params) => {
|
|||
let fileTable = rendy(template.path, {
|
||||
link : prefix + FS + path,
|
||||
fullPath : path,
|
||||
path : htmlPath
|
||||
path : htmlPath,
|
||||
});
|
||||
|
||||
const owner = 'owner';
|
||||
|
|
@ -197,7 +202,7 @@ module.exports.buildFromJSON = (params) => {
|
|||
attribute: getAttribute(file.size)
|
||||
});
|
||||
|
||||
const dataName = `data-name="js-file-${name}" `;
|
||||
const dataName = getDataName(file.name);
|
||||
const attribute = `draggable="true" ${dataName}`;
|
||||
|
||||
return rendy(templateFile, {
|
||||
|
|
|
|||
32
test/common/btoa.js
Normal file
32
test/common/btoa.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('tape');
|
||||
const diff = require('sinon-called-with-diff');
|
||||
const sinon = diff(require('sinon'));
|
||||
|
||||
const btoa = require('../../common/btoa');
|
||||
|
||||
test('btoa: browser', (t) => {
|
||||
const btoaOriginal = global.btoa;
|
||||
const str = 'hello';
|
||||
|
||||
global.btoa = sinon.stub();
|
||||
|
||||
btoa(str);
|
||||
|
||||
t.ok(global.btoa.calledWith(str), 'should call global.btoa');
|
||||
t.end();
|
||||
|
||||
global.btoa = btoaOriginal;
|
||||
});
|
||||
|
||||
test('btoa: node', (t) => {
|
||||
const str = 'hello';
|
||||
const expected = 'aGVsbG8=';
|
||||
|
||||
const result = btoa(str);
|
||||
|
||||
t.equal(result, expected, 'should encode base64');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -12,14 +12,14 @@
|
|||
<span data-name="js-date" class="date reduce-text">--.--.----</span>
|
||||
<span data-name="js-owner" class="owner reduce-text">.</span>
|
||||
<span data-name="js-mode" class="mode reduce-text">--- --- ---</span>
|
||||
</li><li draggable="true" data-name="js-file-applnk" class="">
|
||||
</li><li draggable="true" data-name="js-file-YXBwbG5r" class="">
|
||||
<span data-name="js-type" class="mini-icon directory"></span>
|
||||
<span data-name="js-name" class="name reduce-text"><a href="/fs/etc/X11/applnk" title="applnk" draggable="true">applnk</a></span>
|
||||
<span data-name="js-size" class="size reduce-text"><dir></span>
|
||||
<span data-name="js-date" class="date reduce-text">21.02.2016</span>
|
||||
<span data-name="js-owner" class="owner reduce-text">root</span>
|
||||
<span data-name="js-mode" class="mode reduce-text">rwx r-x r-x</span>
|
||||
</li><li draggable="true" data-name="js-file-prefdm" class="">
|
||||
</li><li draggable="true" data-name="js-file-cHJlZmRt" class="">
|
||||
<span data-name="js-type" class="mini-icon text-file"></span>
|
||||
<span data-name="js-name" class="name reduce-text"><a href="/fs/etc/X11/prefdm" title="prefdm" target="_blank" draggable="true">prefdm</a></span>
|
||||
<span data-name="js-size" class="size reduce-text">1.30kb</span>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue