mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-22 18:29:26 +00:00
chore: lint
This commit is contained in:
parent
f1279666b5
commit
4717e035ee
173 changed files with 1388 additions and 1627 deletions
6
.github/FUNDING.yml
vendored
6
.github/FUNDING.yml
vendored
|
|
@ -1,10 +1,4 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: coderaiser
|
||||
patreon: coderaiser
|
||||
open_collective: cloudcmd
|
||||
ko_fi: coderaiser
|
||||
#issuehunt: # Replace with a single IssueHunt username
|
||||
#otechie: # Replace with a single Otechie username
|
||||
#lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
#liberapay: ~1758956
|
||||
|
|
|
|||
2
.github/workflows/nodejs.yml
vendored
2
.github/workflows/nodejs.yml
vendored
|
|
@ -48,6 +48,6 @@ jobs:
|
|||
- name: Coverage
|
||||
run: redrun coverage coverage:report
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
uses: coverallsapp/github-action@v2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
{
|
||||
"plugins": [
|
||||
"cloudcmd"
|
||||
],
|
||||
"plugins": ["cloudcmd"],
|
||||
"ignore": [
|
||||
"html",
|
||||
"fixture*",
|
||||
|
|
|
|||
|
|
@ -37,11 +37,8 @@ const plugins = clean([
|
|||
const rules = [{
|
||||
test: /\.css$/,
|
||||
exclude: /css\/(nojs|view|config|terminal|user-menu|columns.*)\.css/,
|
||||
use: extractMain.extract([
|
||||
'css-loader',
|
||||
]),
|
||||
},
|
||||
...cssPlugins.map(extract), {
|
||||
use: extractMain.extract(['css-loader']),
|
||||
}, ...cssPlugins.map(extract), {
|
||||
test: /\.(png|gif|svg|woff|woff2|eot|ttf)$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
|
|
@ -63,7 +60,8 @@ function getCSSList(dir) {
|
|||
const addDir = (name) => `${dir}/${name}`;
|
||||
const rootDir = join(__dirname, '..');
|
||||
|
||||
return fs.readdirSync(`${rootDir}/css/${dir}`)
|
||||
return fs
|
||||
.readdirSync(`${rootDir}/css/${dir}`)
|
||||
.map(base)
|
||||
.map(addDir);
|
||||
}
|
||||
|
|
@ -73,9 +71,6 @@ function extract(extractPlugin) {
|
|||
|
||||
return {
|
||||
test: RegExp(`css/${filename}`),
|
||||
use: extractPlugin.extract([
|
||||
'css-loader',
|
||||
]),
|
||||
use: extractPlugin.extract(['css-loader']),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,25 +19,24 @@ module.exports = {
|
|||
|
||||
function getMinifyHtmlOptions() {
|
||||
return {
|
||||
removeComments: true,
|
||||
removeCommentsFromCDATA: true,
|
||||
removeCDATASectionsFromCDATA: true,
|
||||
collapseWhitespace: true,
|
||||
collapseBooleanAttributes: true,
|
||||
removeAttributeQuotes: true,
|
||||
removeRedundantAttributes: true,
|
||||
useShortDoctype: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeComments: true,
|
||||
removeCommentsFromCDATA: true,
|
||||
removeCDATASectionsFromCDATA: true,
|
||||
collapseWhitespace: true,
|
||||
collapseBooleanAttributes: true,
|
||||
removeAttributeQuotes: true,
|
||||
removeRedundantAttributes: true,
|
||||
useShortDoctype: true,
|
||||
removeEmptyAttributes: true,
|
||||
/* оставляем, поскольку у нас
|
||||
* в элемент fm генерируеться
|
||||
* таблица файлов
|
||||
*/
|
||||
removeEmptyElements: false,
|
||||
removeOptionalTags: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
removeEmptyElements: false,
|
||||
removeOptionalTags: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
|
||||
minifyJS: true,
|
||||
minifyJS: true,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,18 +44,17 @@ const rules = clean([
|
|||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
options,
|
||||
}]);
|
||||
},
|
||||
]);
|
||||
|
||||
const plugins = [
|
||||
new EnvironmentPlugin({
|
||||
NODE_ENV,
|
||||
}),
|
||||
|
||||
new ServiceWorkerWebpackPlugin({
|
||||
entry: join(__dirname, '..', 'client', 'sw', 'sw.js'),
|
||||
excludes: ['*'],
|
||||
}),
|
||||
|
||||
new WebpackBar(),
|
||||
];
|
||||
|
||||
|
|
@ -102,9 +101,7 @@ module.exports = {
|
|||
devtoolModuleFilenameTemplate,
|
||||
publicPath: '/dist/',
|
||||
},
|
||||
externals: [
|
||||
externals,
|
||||
],
|
||||
externals: [externals],
|
||||
module: {
|
||||
rules,
|
||||
noParse,
|
||||
|
|
@ -132,4 +129,3 @@ function devtoolModuleFilenameTemplate(info) {
|
|||
const resource = info.absoluteResourcePath.replace(rootDir + sep, '');
|
||||
return `file://cloudcmd/${resource}`;
|
||||
}
|
||||
|
||||
|
|
|
|||
101
HELP.md
101
HELP.md
|
|
@ -374,50 +374,50 @@ Here's a description of all options:
|
|||
|
||||
```json
|
||||
{
|
||||
"name" : "", // set tab name in web browser
|
||||
"auth" : false, // enable http authentication
|
||||
"username" : "root", // username for authentication
|
||||
"password" : "toor", // password hash for authentication
|
||||
"algo" : "sha512WithRSAEncryption", // cryptographic algorithm
|
||||
"editor" : "edward", // default, could be "dword" or "edward"
|
||||
"packer" : "tar", // default, could be "tar" or "zip"
|
||||
"diff" : true, // when save - send patch, not whole file
|
||||
"zip" : true, // zip text before send / unzip before save
|
||||
"buffer" : true, // buffer for copying files
|
||||
"dirStorage" : true, // store directory listing
|
||||
"online" : false, // do not load js files from cdn
|
||||
"open" : true, // open web browser when server started
|
||||
"oneFilePanel" : false, // show one file panel
|
||||
"keysPanel" : true, // show classic panel with buttons of keys
|
||||
"port" : 8000, // http port
|
||||
"ip" : null, // ip or null(default)
|
||||
"root" : "/", // root directory
|
||||
"prefix" : "", // url prefix
|
||||
"prefixSocket" : "", // prefix for socket connection
|
||||
"confirmCopy" : true, // confirm copy
|
||||
"confirmMove" : true, // confirm move
|
||||
"showConfig" : false, // show config at startup
|
||||
"showFileName" : false, // do not show file name in view and edit
|
||||
"contact" : true, // enable contact
|
||||
"configDialog" : true, // enable config dialog
|
||||
"configAuth" : true, // enable auth change in config dialog
|
||||
"console" : true, // enable console
|
||||
"syncConsolePath" : false, // do not sync console path
|
||||
"terminal" : false, // disable terminal
|
||||
"terminalPath" : "", // path of a terminal
|
||||
"terminalCommand" : "", // set command to run in terminal
|
||||
"terminalAutoRestart" : true, // restart command on exit
|
||||
"vim" : false, // disable vim hot keys
|
||||
"columns" : "name-size-date-owner-mode", // set visible columns
|
||||
"export" : false, // enable export of config through a server
|
||||
"exportToken" : "root", // token used by export server
|
||||
"import" : false, // enable import of config
|
||||
"import-url" : "http://localhost:8000", // url of an export server
|
||||
"importToken" : "root", // token used to connect to export server
|
||||
"importListen" : false, // listen on config updates
|
||||
"dropbox" : false, // disable dropbox integration
|
||||
"dropboxToken" : "", // unset dropbox token
|
||||
"log" : true // logging
|
||||
"name": "", // set tab name in web browser
|
||||
"auth": false, // enable http authentication
|
||||
"username": "root", // username for authentication
|
||||
"password": "toor", // password hash for authentication
|
||||
"algo": "sha512WithRSAEncryption", // cryptographic algorithm
|
||||
"editor": "edward", // default, could be "dword" or "edward"
|
||||
"packer": "tar", // default, could be "tar" or "zip"
|
||||
"diff": true, // when save - send patch, not whole file
|
||||
"zip": true, // zip text before send / unzip before save
|
||||
"buffer": true, // buffer for copying files
|
||||
"dirStorage": true, // store directory listing
|
||||
"online": false, // do not load js files from cdn
|
||||
"open": true, // open web browser when server started
|
||||
"oneFilePanel": false, // show one file panel
|
||||
"keysPanel": true, // show classic panel with buttons of keys
|
||||
"port": 8000, // http port
|
||||
"ip": null, // ip or null(default)
|
||||
"root": "/", // root directory
|
||||
"prefix": "", // url prefix
|
||||
"prefixSocket": "", // prefix for socket connection
|
||||
"confirmCopy": true, // confirm copy
|
||||
"confirmMove": true, // confirm move
|
||||
"showConfig": false, // show config at startup
|
||||
"showFileName": false, // do not show file name in view and edit
|
||||
"contact": true, // enable contact
|
||||
"configDialog": true, // enable config dialog
|
||||
"configAuth": true, // enable auth change in config dialog
|
||||
"console": true, // enable console
|
||||
"syncConsolePath": false, // do not sync console path
|
||||
"terminal": false, // disable terminal
|
||||
"terminalPath": "", // path of a terminal
|
||||
"terminalCommand": "", // set command to run in terminal
|
||||
"terminalAutoRestart": true, // restart command on exit
|
||||
"vim": false, // disable vim hot keys
|
||||
"columns": "name-size-date-owner-mode", // set visible columns
|
||||
"export": false, // enable export of config through a server
|
||||
"exportToken": "root", // token used by export server
|
||||
"import": false, // enable import of config
|
||||
"import-url": "http://localhost:8000", // url of an export server
|
||||
"importToken": "root", // token used to connect to export server
|
||||
"importListen": false, // listen on config updates
|
||||
"dropbox": false, // disable dropbox integration
|
||||
"dropboxToken": "", // unset dropbox token
|
||||
"log": true // logging
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -467,9 +467,7 @@ const RENAME_FILE = 'Rename file';
|
|||
|
||||
export default {
|
||||
'__settings': {
|
||||
select: [
|
||||
RENAME_FILE,
|
||||
],
|
||||
select: [RENAME_FILE],
|
||||
run: false,
|
||||
},
|
||||
[`F2 - ${RENAME_FILE}`]: async ({DOM}) => {
|
||||
|
|
@ -499,7 +497,9 @@ export default {
|
|||
const path = `${dirPath}.cloudcmd.menu.js`;
|
||||
const {prefix} = CloudCmd;
|
||||
|
||||
const data = await readDefaultMenu({prefix});
|
||||
const data = await readDefaultMenu({
|
||||
prefix,
|
||||
});
|
||||
await createDefaultMenu({
|
||||
path,
|
||||
data,
|
||||
|
|
@ -743,6 +743,7 @@ const socket2 = new Server(server, {
|
|||
});
|
||||
|
||||
const configManager1 = createConfigManager();
|
||||
|
||||
configManager1('name', '1');
|
||||
|
||||
const configManager2 = createConfigManager();
|
||||
|
|
@ -765,8 +766,10 @@ If you want to enable authorization, you can pass credentials to Cloud Commander
|
|||
|
||||
```js
|
||||
import criton from 'criton';
|
||||
const algo = 'sha512WithRSAEncryption'; // default
|
||||
|
||||
const algo = 'sha512WithRSAEncryption';
|
||||
|
||||
// default
|
||||
// you can generate a hash dynamically
|
||||
const password = criton('root', algo);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@ import {promisify} from 'util';
|
|||
import tryToCatch from 'try-to-catch';
|
||||
import {createSimport} from 'simport';
|
||||
import parse from 'yargs-parser';
|
||||
|
||||
import exit from '../server/exit.js';
|
||||
import {
|
||||
createConfig,
|
||||
configPath,
|
||||
} from '../server/config.js';
|
||||
|
||||
import env from '../server/env.js';
|
||||
import prefixer from '../server/prefixer.js';
|
||||
|
||||
|
|
@ -26,7 +24,7 @@ const simport = createSimport(import.meta.url);
|
|||
const choose = (a, b) => {
|
||||
if (a === undefined)
|
||||
return b;
|
||||
|
||||
|
||||
return a;
|
||||
};
|
||||
|
||||
|
|
@ -39,7 +37,7 @@ const DIR_SERVER = '../server/';
|
|||
const maybeRoot = (a) => {
|
||||
if (a === '.')
|
||||
return process.cwd();
|
||||
|
||||
|
||||
return a;
|
||||
};
|
||||
|
||||
|
|
@ -100,29 +98,29 @@ const yargsOptions = {
|
|||
'dropbox',
|
||||
],
|
||||
default: {
|
||||
'server' : true,
|
||||
'name' : choose(env('name'), config('name')),
|
||||
'auth' : choose(env.bool('auth'), config('auth')),
|
||||
'port' : config('port'),
|
||||
'online' : config('online'),
|
||||
'open' : choose(env.bool('open'), config('open')),
|
||||
'editor' : env('editor') || config('editor'),
|
||||
'packer' : config('packer') || 'tar',
|
||||
'zip' : config('zip'),
|
||||
'username' : env('username') || config('username'),
|
||||
'root' : choose(env('root'), config('root')),
|
||||
'prefix' : choose(env('prefix'), config('prefix')),
|
||||
'console' : choose(env.bool('console'), config('console')),
|
||||
'contact' : choose(env.bool('contact'), config('contact')),
|
||||
'terminal' : choose(env.bool('terminal'), config('terminal')),
|
||||
'columns' : env('columns') || config('columns') || '',
|
||||
'vim' : choose(env.bool('vim'), config('vim')),
|
||||
'log' : config('log'),
|
||||
'server': true,
|
||||
'name': choose(env('name'), config('name')),
|
||||
'auth': choose(env.bool('auth'), config('auth')),
|
||||
'port': config('port'),
|
||||
'online': config('online'),
|
||||
'open': choose(env.bool('open'), config('open')),
|
||||
'editor': env('editor') || config('editor'),
|
||||
'packer': config('packer') || 'tar',
|
||||
'zip': config('zip'),
|
||||
'username': env('username') || config('username'),
|
||||
'root': choose(env('root'), config('root')),
|
||||
'prefix': choose(env('prefix'), config('prefix')),
|
||||
'console': choose(env.bool('console'), config('console')),
|
||||
'contact': choose(env.bool('contact'), config('contact')),
|
||||
'terminal': choose(env.bool('terminal'), config('terminal')),
|
||||
'columns': env('columns') || config('columns') || '',
|
||||
'vim': choose(env.bool('vim'), config('vim')),
|
||||
'log': config('log'),
|
||||
|
||||
'import-url': env('import_url') || config('importUrl'),
|
||||
'import-listen': choose(env.bool('import_listen'), config('importListen')),
|
||||
'import' : choose(env.bool('import'), config('import')),
|
||||
'export' : choose(env.bool('export'), config('export')),
|
||||
'import': choose(env.bool('import'), config('import')),
|
||||
'export': choose(env.bool('export'), config('export')),
|
||||
|
||||
'prefix-socket': config('prefixSocket'),
|
||||
'show-file-name': choose(env.bool('show_file_name'), config('showFileName')),
|
||||
|
|
@ -348,4 +346,3 @@ async function showUpdateInfo(version) {
|
|||
|
||||
console.log('%s %s', latest, current);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import {promisify} from 'util';
|
||||
|
||||
import tryToCatch from 'try-to-catch';
|
||||
import {createSimport} from 'simport';
|
||||
import minor from 'minor';
|
||||
|
|
@ -20,8 +19,9 @@ async function main() {
|
|||
const history = '## Version history\n\n';
|
||||
const link = '//github.com/coderaiser/cloudcmd/releases/tag/';
|
||||
const template = '- *{{ date }}*, ' +
|
||||
'**[v{{ version }}]' +
|
||||
'(' + link + 'v{{ version }})**\n';
|
||||
'**[v{{ version }}]' +
|
||||
'(' + link +
|
||||
'v{{ version }})**\n';
|
||||
|
||||
const {version} = Info;
|
||||
|
||||
|
|
@ -34,8 +34,8 @@ async function main() {
|
|||
await replaceVersion('HELP.md', version, versionNew);
|
||||
|
||||
const historyNew = history + rendy(template, {
|
||||
date : shortdate(),
|
||||
version : versionNew,
|
||||
date: shortdate(),
|
||||
version: versionNew,
|
||||
});
|
||||
|
||||
await replaceVersion('HELP.md', history, historyNew);
|
||||
|
|
@ -68,7 +68,6 @@ async function cl() {
|
|||
function getVersionNew(last, match) {
|
||||
if (match)
|
||||
return minor(match, Info.version);
|
||||
|
||||
|
||||
return last.substr(3);
|
||||
}
|
||||
|
||||
|
|
|
|||
224
client/client.js
224
client/client.js
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global DOM */
|
||||
|
||||
const Emitify = require('emitify');
|
||||
const inherits = require('inherits');
|
||||
const rendy = require('rendy');
|
||||
|
|
@ -16,6 +15,7 @@ const Images = require('./dom/images');
|
|||
const {unregisterSW} = require('./sw/register');
|
||||
const getJsonFromFileTable = require('./get-json-from-file-table');
|
||||
const Key = require('./key');
|
||||
|
||||
const {
|
||||
apiURL,
|
||||
formatMsg,
|
||||
|
|
@ -39,58 +39,60 @@ load.addErrorListener((e, src) => {
|
|||
|
||||
function CloudCmdProto(DOM) {
|
||||
let Listeners;
|
||||
|
||||
|
||||
Emitify.call(this);
|
||||
|
||||
|
||||
const CloudCmd = this;
|
||||
const Info = DOM.CurrentInfo;
|
||||
|
||||
const {
|
||||
Storage,
|
||||
Files,
|
||||
} = DOM;
|
||||
|
||||
|
||||
const {Storage, Files} = DOM;
|
||||
|
||||
this.log = (...a) => {
|
||||
if (!isDev)
|
||||
return;
|
||||
|
||||
|
||||
console.log(...a);
|
||||
};
|
||||
this.prefix = '';
|
||||
this.prefixSocket = '';
|
||||
this.prefixURL = '';
|
||||
|
||||
|
||||
this.MIN_ONE_PANEL_WIDTH = 1155;
|
||||
this.HOST = location.origin || location.protocol + '//' + location.host;
|
||||
|
||||
|
||||
this.TITLE = 'Cloud Commander';
|
||||
|
||||
|
||||
this.sort = {
|
||||
left: 'name',
|
||||
right: 'name',
|
||||
};
|
||||
|
||||
|
||||
this.order = {
|
||||
left: 'asc',
|
||||
right: 'asc',
|
||||
};
|
||||
|
||||
this.changeDir = async (path, {isRefresh, panel, history = true, noCurrent, currentName} = {}) => {
|
||||
|
||||
this.changeDir = async (path, {
|
||||
isRefresh,
|
||||
panel,
|
||||
history = true,
|
||||
noCurrent,
|
||||
currentName,
|
||||
} = {}) => {
|
||||
const refresh = isRefresh;
|
||||
let panelChanged;
|
||||
|
||||
|
||||
if (!noCurrent && panel && panel !== Info.panel) {
|
||||
DOM.changePanel();
|
||||
panelChanged = true;
|
||||
}
|
||||
|
||||
|
||||
let imgPosition;
|
||||
|
||||
|
||||
if (panelChanged || refresh || !history)
|
||||
imgPosition = 'top';
|
||||
|
||||
|
||||
Images.show.load(imgPosition, panel);
|
||||
|
||||
/* загружаем содержимое каталога */
|
||||
await ajaxLoad(addSlashToEnd(path), {
|
||||
refresh,
|
||||
|
|
@ -111,7 +113,7 @@ function CloudCmdProto(DOM) {
|
|||
CloudCmd.prefixSocket = config.prefixSocket;
|
||||
CloudCmd.DIR_DIST = `${prefix}/dist`;
|
||||
CloudCmd.DIR_MODULES = `${this.DIR_DIST}/modules`;
|
||||
|
||||
|
||||
CloudCmd.config = (key) => config[key];
|
||||
CloudCmd.config.if = currify((key, fn, a) => config[key] && fn(a));
|
||||
CloudCmd._config = (key, value) => {
|
||||
|
|
@ -119,61 +121,60 @@ function CloudCmdProto(DOM) {
|
|||
* should be called from config.js only
|
||||
* after successful update on server
|
||||
*/
|
||||
|
||||
if (key === 'password')
|
||||
return;
|
||||
|
||||
|
||||
config[key] = value;
|
||||
};
|
||||
|
||||
|
||||
if (config.oneFilePanel)
|
||||
CloudCmd.MIN_ONE_PANEL_WIDTH = Infinity;
|
||||
|
||||
|
||||
if (!document.body.scrollIntoViewIfNeeded)
|
||||
await load.js(`${CloudCmd.DIR_MODULES}/polyfill.js`);
|
||||
|
||||
|
||||
await initModules();
|
||||
await baseInit();
|
||||
await loadStyle();
|
||||
|
||||
|
||||
CloudCmd.route(location.hash);
|
||||
};
|
||||
|
||||
|
||||
async function loadStyle() {
|
||||
const {prefix} = CloudCmd;
|
||||
const name = `${prefix}/dist/cloudcmd.common.css`;
|
||||
|
||||
|
||||
await load.css(name);
|
||||
}
|
||||
|
||||
this.route = (path) => {
|
||||
const query = path.split('/');
|
||||
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
|
||||
const [kebabModule] = query;
|
||||
const module = noJS(pascalCase(kebabModule.slice(1)));
|
||||
|
||||
|
||||
const file = query[1];
|
||||
const current = DOM.getCurrentByName(file);
|
||||
|
||||
|
||||
if (file && !current) {
|
||||
const msg = formatMsg('set current file', file, 'error');
|
||||
CloudCmd.log(msg);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DOM.setCurrentFile(current);
|
||||
CloudCmd.execFromModule(module, 'show');
|
||||
};
|
||||
|
||||
|
||||
this.logOut = async () => {
|
||||
const url = CloudCmd.prefix + '/logout';
|
||||
const error = () => document.location.reload();
|
||||
const {prefix} = CloudCmd;
|
||||
|
||||
|
||||
await DOM.Storage.clear();
|
||||
unregisterSW(prefix);
|
||||
DOM.load.ajax({
|
||||
|
|
@ -181,19 +182,19 @@ function CloudCmdProto(DOM) {
|
|||
error,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const initModules = async () => {
|
||||
CloudCmd.Key = Key;
|
||||
CloudCmd.Key.bind();
|
||||
|
||||
|
||||
const [, modules] = await tryToCatch(Files.get, 'modules');
|
||||
const showLoad = Images.show.load;
|
||||
|
||||
|
||||
const doBefore = {
|
||||
edit: showLoad,
|
||||
menu: showLoad,
|
||||
};
|
||||
|
||||
|
||||
const load = (name, path, dobefore) => {
|
||||
loadModule({
|
||||
name,
|
||||
|
|
@ -201,28 +202,28 @@ function CloudCmdProto(DOM) {
|
|||
dobefore,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
if (!modules)
|
||||
return;
|
||||
|
||||
|
||||
for (const module of modules.local) {
|
||||
load(null, module, doBefore[module]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
async function saveCurrentName(currentName) {
|
||||
await Storage.set('current-name', currentName);
|
||||
}
|
||||
|
||||
async function baseInit() {
|
||||
const files = DOM.getFiles();
|
||||
|
||||
|
||||
CloudCmd.on('current-file', DOM.updateCurrentInfo);
|
||||
CloudCmd.on('current-name', saveCurrentName);
|
||||
|
||||
|
||||
const name = await Storage.get('current-name');
|
||||
const currentFile = name && DOM.getCurrentByName(name) || files[0];
|
||||
|
||||
|
||||
/* выделяем строку с первым файлом */
|
||||
if (files)
|
||||
DOM.setCurrentFile(currentFile, {
|
||||
|
|
@ -231,31 +232,32 @@ function CloudCmdProto(DOM) {
|
|||
// overwre otherwise
|
||||
history: !location.hash,
|
||||
});
|
||||
|
||||
|
||||
const dirPath = DOM.getCurrentDirPath();
|
||||
|
||||
Listeners = CloudCmd.Listeners;
|
||||
Listeners.init();
|
||||
|
||||
|
||||
const panels = getPanels();
|
||||
panels.forEach(Listeners.setOnPanel);
|
||||
|
||||
|
||||
Listeners.initKeysPanel();
|
||||
|
||||
|
||||
if (!CloudCmd.config('dirStorage'))
|
||||
return;
|
||||
|
||||
|
||||
const data = await Storage.get(dirPath);
|
||||
|
||||
|
||||
if (!data)
|
||||
await Storage.setJson(dirPath, getJsonFromFileTable());
|
||||
}
|
||||
|
||||
function getPanels() {
|
||||
const panels = ['left'];
|
||||
|
||||
|
||||
if (CloudCmd.config('oneFilePanel'))
|
||||
return panels;
|
||||
|
||||
|
||||
return [
|
||||
...panels,
|
||||
'right',
|
||||
|
|
@ -264,23 +266,20 @@ function CloudCmdProto(DOM) {
|
|||
|
||||
this.execFromModule = async (moduleName, funcName, ...args) => {
|
||||
await CloudCmd[moduleName]();
|
||||
|
||||
|
||||
const func = CloudCmd[moduleName][funcName];
|
||||
func(...args);
|
||||
};
|
||||
|
||||
|
||||
this.refresh = async (options = {}) => {
|
||||
const {
|
||||
panel = Info.panel,
|
||||
currentName,
|
||||
} = options;
|
||||
|
||||
const {panel = Info.panel, currentName} = options;
|
||||
|
||||
const path = DOM.getCurrentDirPath(panel);
|
||||
|
||||
|
||||
const isRefresh = true;
|
||||
const history = false;
|
||||
const noCurrent = options ? options.noCurrent : false;
|
||||
|
||||
|
||||
await CloudCmd.changeDir(path, {
|
||||
isRefresh,
|
||||
history,
|
||||
|
|
@ -302,46 +301,43 @@ function CloudCmdProto(DOM) {
|
|||
*/
|
||||
async function ajaxLoad(path, options = {}, panel) {
|
||||
const {RESTful} = DOM;
|
||||
|
||||
|
||||
CloudCmd.log(`reading dir: "${path}";`);
|
||||
|
||||
|
||||
const dirStorage = CloudCmd.config('dirStorage');
|
||||
const json = dirStorage && await Storage.getJson(path);
|
||||
|
||||
|
||||
const name = options.currentName || Info.name;
|
||||
const {
|
||||
noCurrent,
|
||||
refresh,
|
||||
} = options;
|
||||
|
||||
const {noCurrent, refresh} = options;
|
||||
|
||||
if (!refresh && json)
|
||||
return await createFileTable(json, panel, options);
|
||||
|
||||
|
||||
const position = DOM.getPanelPosition(panel);
|
||||
const sort = CloudCmd.sort[position];
|
||||
const order = CloudCmd.order[position];
|
||||
|
||||
|
||||
const query = rendy('?sort={{ sort }}&order={{ order }}', {
|
||||
sort,
|
||||
order,
|
||||
});
|
||||
|
||||
|
||||
const [, newObj] = await RESTful.read(path + query, 'json');
|
||||
|
||||
|
||||
if (!newObj)
|
||||
return; // that's OK, error handled by RESTful
|
||||
|
||||
// that's OK, error handled by RESTful
|
||||
return;
|
||||
options.sort = sort;
|
||||
options.order = order;
|
||||
|
||||
|
||||
await createFileTable(newObj, panel, options);
|
||||
|
||||
|
||||
if (refresh && !noCurrent)
|
||||
DOM.setCurrentByName(name);
|
||||
|
||||
|
||||
if (!CloudCmd.config('dirStorage'))
|
||||
return;
|
||||
|
||||
|
||||
Storage.setJson(path, newObj);
|
||||
}
|
||||
|
||||
|
|
@ -353,69 +349,60 @@ function CloudCmdProto(DOM) {
|
|||
* @param callback
|
||||
*/
|
||||
async function createFileTable(data, panelParam, options) {
|
||||
const {
|
||||
history,
|
||||
noCurrent,
|
||||
} = options;
|
||||
|
||||
const {history, noCurrent} = options;
|
||||
|
||||
const names = [
|
||||
'file',
|
||||
'path',
|
||||
'link',
|
||||
'pathLink',
|
||||
];
|
||||
|
||||
const [
|
||||
error,
|
||||
[file, path, link, pathLink],
|
||||
] = await tryToCatch(Files.get, names);
|
||||
|
||||
|
||||
const [error, [file, path, link, pathLink]] = await tryToCatch(Files.get, names);
|
||||
|
||||
if (error)
|
||||
return DOM.Dialog.alert(error.responseText);
|
||||
|
||||
|
||||
const panel = panelParam || DOM.getPanel();
|
||||
const {prefix} = CloudCmd;
|
||||
|
||||
const {
|
||||
dir,
|
||||
name,
|
||||
} = Info;
|
||||
|
||||
|
||||
const {dir, name} = Info;
|
||||
|
||||
const {childNodes} = panel;
|
||||
let i = childNodes.length;
|
||||
|
||||
|
||||
while (i--)
|
||||
panel.removeChild(panel.lastChild);
|
||||
|
||||
|
||||
panel.innerHTML = buildFromJSON({
|
||||
sort : options.sort,
|
||||
order : options.order,
|
||||
sort: options.sort,
|
||||
order: options.order,
|
||||
data,
|
||||
id : panel.id,
|
||||
id: panel.id,
|
||||
prefix,
|
||||
template : {
|
||||
template: {
|
||||
file,
|
||||
path,
|
||||
pathLink,
|
||||
link,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Listeners.setOnPanel(panel);
|
||||
|
||||
|
||||
if (!noCurrent) {
|
||||
let current;
|
||||
|
||||
|
||||
if (name === '..' && dir !== '/')
|
||||
current = DOM.getCurrentByName(dir);
|
||||
|
||||
|
||||
if (!current)
|
||||
[current] = DOM.getFiles(panel);
|
||||
|
||||
|
||||
DOM.setCurrentFile(current, {
|
||||
history,
|
||||
});
|
||||
|
||||
|
||||
CloudCmd.emit('active-dir', Info.dirPath);
|
||||
}
|
||||
}
|
||||
|
|
@ -427,20 +414,19 @@ function CloudCmdProto(DOM) {
|
|||
parentDirPath,
|
||||
panel,
|
||||
} = Info;
|
||||
|
||||
|
||||
if (dirPath === parentDirPath)
|
||||
return;
|
||||
|
||||
|
||||
const path = parentDirPath;
|
||||
|
||||
|
||||
await CloudCmd.changeDir(path);
|
||||
|
||||
|
||||
const current = DOM.getCurrentByName(dir);
|
||||
const [first] = DOM.getFiles(panel);
|
||||
|
||||
|
||||
DOM.setCurrentFile(current || first, {
|
||||
history,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,7 @@ require('../css/columns/name-size.css');
|
|||
const wraptile = require('wraptile');
|
||||
const load = require('load.js');
|
||||
|
||||
const {
|
||||
registerSW,
|
||||
listenSW,
|
||||
} = require('./sw/register');
|
||||
const {registerSW, listenSW} = require('./sw/register');
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
|
|
@ -65,4 +62,3 @@ async function register(config) {
|
|||
|
||||
listenSW(sw, 'updatefound', onUpdateFound(config));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const tryToPromiseAll = require('../../common/try-to-promise-all');
|
||||
const Storage = require('./storage');
|
||||
const DOM = require('./');
|
||||
|
|
@ -13,24 +12,25 @@ function BufferProto() {
|
|||
const CLASS = 'cut-file';
|
||||
const COPY = 'copy';
|
||||
const CUT = 'cut';
|
||||
|
||||
const Buffer = {
|
||||
cut : callIfEnabled.bind(null, cut),
|
||||
copy : callIfEnabled.bind(null, copy),
|
||||
clear : callIfEnabled.bind(null, clear),
|
||||
paste : callIfEnabled.bind(null, paste),
|
||||
cut: callIfEnabled.bind(null, cut),
|
||||
copy: callIfEnabled.bind(null, copy),
|
||||
clear: callIfEnabled.bind(null, clear),
|
||||
paste: callIfEnabled.bind(null, paste),
|
||||
};
|
||||
|
||||
function showMessage(msg) {
|
||||
DOM.Dialog.alert(msg);
|
||||
}
|
||||
|
||||
|
||||
function getNames() {
|
||||
const files = DOM.getActiveFiles();
|
||||
const names = DOM.getFilenames(files);
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
function addCutClass() {
|
||||
const files = DOM.getActiveFiles();
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ function BufferProto() {
|
|||
element.classList.add(CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function rmCutClass() {
|
||||
const files = DOM.getByClassAll(CLASS);
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ function BufferProto() {
|
|||
element.classList.remove(CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function callIfEnabled(callback) {
|
||||
const is = CloudCmd.config('buffer');
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ function BufferProto() {
|
|||
|
||||
showMessage('Buffer disabled in config!');
|
||||
}
|
||||
|
||||
|
||||
async function readBuffer() {
|
||||
const [e, cp, ct] = await tryToPromiseAll([
|
||||
Storage.getJson(COPY),
|
||||
|
|
@ -68,7 +68,7 @@ function BufferProto() {
|
|||
ct,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
async function copy() {
|
||||
const names = getNames();
|
||||
const from = Info.dirPath;
|
||||
|
|
@ -84,7 +84,7 @@ function BufferProto() {
|
|||
names,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function cut() {
|
||||
const names = getNames();
|
||||
const from = Info.dirPath;
|
||||
|
|
@ -101,14 +101,14 @@ function BufferProto() {
|
|||
names,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function clear() {
|
||||
await Storage.remove(COPY);
|
||||
await Storage.remove(CUT);
|
||||
|
||||
rmCutClass();
|
||||
}
|
||||
|
||||
|
||||
async function paste() {
|
||||
const [error, cp, ct] = await readBuffer();
|
||||
|
||||
|
|
@ -131,7 +131,6 @@ function BufferProto() {
|
|||
|
||||
await clear();
|
||||
}
|
||||
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,12 @@
|
|||
|
||||
/* global DOM */
|
||||
/* global CloudCmd */
|
||||
|
||||
const {atob, btoa} = require('../../common/base64');
|
||||
const createElement = require('@cloudcmd/create-element');
|
||||
|
||||
const {
|
||||
encode,
|
||||
decode,
|
||||
} = require('../../common/entity');
|
||||
const {encode, decode} = require('../../common/entity');
|
||||
|
||||
const {
|
||||
getTitle,
|
||||
FS,
|
||||
} = require('../../common/cloudfunc');
|
||||
const {getTitle, FS} = require('../../common/cloudfunc');
|
||||
|
||||
let Title;
|
||||
|
||||
|
|
@ -23,7 +16,6 @@ const encodeNBSP = (a) => a?.replace('\xa0', ' ');
|
|||
const decodeNBSP = (a) => a?.replace(' ', '\xa0');
|
||||
|
||||
module.exports._CURRENT_FILE = CURRENT_FILE;
|
||||
|
||||
/**
|
||||
* set name from current (or param) file
|
||||
*
|
||||
|
|
@ -85,8 +77,8 @@ const parseHrefAttribute = (prefix, attribute) => {
|
|||
attribute = attribute.replace(RegExp('^' + prefix + FS), '');
|
||||
return decode(decodeNBSP(attribute));
|
||||
};
|
||||
module.exports._parseHrefAttribute = parseHrefAttribute;
|
||||
|
||||
module.exports._parseHrefAttribute = parseHrefAttribute;
|
||||
/**
|
||||
* get current direcotory path
|
||||
*/
|
||||
|
|
@ -112,7 +104,8 @@ module.exports.getCurrentPath = (currentFile) => {
|
|||
* get current direcotory name
|
||||
*/
|
||||
module.exports.getCurrentDirName = () => {
|
||||
const href = DOM.getCurrentDirPath()
|
||||
const href = DOM
|
||||
.getCurrentDirPath()
|
||||
.replace(/\/$/, '');
|
||||
|
||||
const substr = href.substr(href, href.lastIndexOf('/'));
|
||||
|
|
@ -158,7 +151,6 @@ module.exports.getCurrentFile = () => {
|
|||
/**
|
||||
* get current file by name
|
||||
*/
|
||||
|
||||
module.exports.getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => {
|
||||
const dataName = 'js-file-' + btoa(encodeURI(encodeNBSP(name)));
|
||||
return DOM.getByDataName(dataName, panel);
|
||||
|
|
@ -205,7 +197,7 @@ module.exports.setCurrentFile = (currentFile, options) => {
|
|||
name,
|
||||
path,
|
||||
}));
|
||||
|
||||
|
||||
/* history could be present
|
||||
* but it should be false
|
||||
* to prevent default behavior
|
||||
|
|
@ -274,7 +266,7 @@ module.exports.getCurrentByPosition = ({x, y}) => {
|
|||
module.exports.isCurrentFile = (currentFile) => {
|
||||
if (!currentFile)
|
||||
return false;
|
||||
|
||||
|
||||
return DOM.isContainClass(currentFile, CURRENT_FILE);
|
||||
};
|
||||
|
||||
|
|
@ -283,7 +275,6 @@ module.exports.isCurrentFile = (currentFile) => {
|
|||
*
|
||||
* @param name
|
||||
*/
|
||||
|
||||
module.exports.setTitle = (name) => {
|
||||
if (!Title)
|
||||
Title = DOM.getByTag('title')[0] || createElement('title', {
|
||||
|
|
@ -315,10 +306,10 @@ module.exports.isCurrentIsDir = (currentFile) => {
|
|||
module.exports.getCurrentType = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const el = DOM.getByDataName('js-type', current);
|
||||
const type = el.className
|
||||
const type = el
|
||||
.className
|
||||
.split(' ')
|
||||
.pop();
|
||||
|
||||
return type;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const {create} = require('auto-globals');
|
||||
const wraptile = require('wraptile');
|
||||
const currentFile = require('./current-file');
|
||||
|
|
@ -13,10 +11,7 @@ const returns = wraptile(id);
|
|||
const {_CURRENT_FILE} = currentFile;
|
||||
|
||||
test('current-file: setCurrentName: setAttribute', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM();
|
||||
global.CloudCmd = getCloudCmd();
|
||||
|
|
@ -35,10 +30,7 @@ test('current-file: setCurrentName: setAttribute', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: setCurrentName: setAttribute: cyrillic', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM();
|
||||
global.CloudCmd = getCloudCmd();
|
||||
|
|
@ -67,10 +59,7 @@ test('current-file: getCurrentName', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: emit', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
const emit = stub();
|
||||
|
||||
|
|
@ -92,10 +81,7 @@ test('current-file: emit', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: setCurrentName: return', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
const link = {};
|
||||
|
||||
|
|
@ -138,28 +124,22 @@ test('current-file: getParentDirPath: result', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: isCurrentFile: no', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM();
|
||||
global.CloudCmd = getCloudCmd();
|
||||
|
||||
|
||||
const result = currentFile.isCurrentFile();
|
||||
|
||||
|
||||
global.DOM = DOM;
|
||||
global.CloudCmd = CloudCmd;
|
||||
|
||||
|
||||
t.notOk(result);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('current-file: isCurrentFile', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
const isContainClass = stub();
|
||||
|
||||
|
|
@ -180,10 +160,7 @@ test('current-file: isCurrentFile', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: getCurrentType', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM();
|
||||
global.CloudCmd = getCloudCmd();
|
||||
|
|
@ -206,10 +183,7 @@ test('current-file: getCurrentType', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: isCurrentIsDir: getCurrentType', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM();
|
||||
global.CloudCmd = getCloudCmd();
|
||||
|
|
@ -228,10 +202,7 @@ test('current-file: isCurrentIsDir: getCurrentType', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: isCurrentIsDir: directory', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM({
|
||||
getCurrentType: stub().returns('directory'),
|
||||
|
|
@ -251,10 +222,7 @@ test('current-file: isCurrentIsDir: directory', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: isCurrentIsDir: directory-link', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM({
|
||||
getCurrentType: stub().returns('directory-link'),
|
||||
|
|
@ -274,10 +242,7 @@ test('current-file: isCurrentIsDir: directory-link', (t) => {
|
|||
});
|
||||
|
||||
test('current-file: isCurrentIsDir: file', (t) => {
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
global.DOM = getDOM({
|
||||
getCurrentType: stub().returns('file'),
|
||||
|
|
@ -320,15 +285,7 @@ test('current-file: parseHrefAttribute', (t) => {
|
|||
t.end();
|
||||
});
|
||||
|
||||
function getDOM({
|
||||
link = {},
|
||||
getCurrentDirPath = stub(),
|
||||
getCurrentDirName = stub(),
|
||||
getByDataName = stub(),
|
||||
isContainClass = stub(),
|
||||
getCurrentType = stub(),
|
||||
getCurrentPath = stub(),
|
||||
} = {}) {
|
||||
function getDOM({link = {}, getCurrentDirPath = stub(), getCurrentDirName = stub(), getByDataName = stub(), isContainClass = stub(), getCurrentType = stub(), getCurrentPath = stub()} = {}) {
|
||||
return {
|
||||
getCurrentDirPath,
|
||||
getCurrentDirName,
|
||||
|
|
@ -342,4 +299,3 @@ function getDOM({
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,4 +24,3 @@ module.exports.alert.noFiles = () => {
|
|||
cancel: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const philip = require('philip');
|
||||
|
||||
const Images = require('./images');
|
||||
|
|
@ -15,11 +14,12 @@ module.exports = (items) => {
|
|||
if (items.length)
|
||||
Images.show('top');
|
||||
|
||||
const entries = Array.from(items).map((item) => item.webkitGetAsEntry());
|
||||
const entries = Array
|
||||
.from(items)
|
||||
.map((item) => item.webkitGetAsEntry());
|
||||
|
||||
const dirPath = getPathWhenRootEmpty();
|
||||
const path = dirPath
|
||||
.replace(/\/$/, '');
|
||||
const path = dirPath.replace(/\/$/, '');
|
||||
|
||||
const progress = Dialog.progress('Uploading...');
|
||||
|
||||
|
|
@ -74,4 +74,3 @@ function uploadFile(url, data) {
|
|||
function uploadDir(url) {
|
||||
return DOM.load.put(`${url}?dir`);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@ const isContainClass = (element, className) => {
|
|||
throw Error('className could not be empty!');
|
||||
|
||||
if (Array.isArray(className))
|
||||
return className.some(currify(isContainClass, element));
|
||||
return className.some(currify(
|
||||
isContainClass,
|
||||
element,
|
||||
));
|
||||
|
||||
const {classList} = element;
|
||||
|
||||
|
|
@ -26,7 +29,6 @@ const isContainClass = (element, className) => {
|
|||
};
|
||||
|
||||
module.exports.isContainClass = isContainClass;
|
||||
|
||||
/**
|
||||
* Function search element by tag
|
||||
* @param tag - className
|
||||
|
|
@ -79,4 +81,3 @@ module.exports.show = (element) => {
|
|||
element.classList.remove('hidden');
|
||||
return DOM;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,13 +36,8 @@ test('dom: isContainClass: contains: array', (t) => {
|
|||
const {contains} = el.classList;
|
||||
|
||||
const className = 'hello';
|
||||
isContainClass(el, [
|
||||
'world',
|
||||
className,
|
||||
'hello',
|
||||
]);
|
||||
isContainClass(el, ['world', className, 'hello']);
|
||||
|
||||
t.calledWith(contains, [className], 'should call contains');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -15,4 +15,3 @@ module.exports.clear = () => {
|
|||
};
|
||||
|
||||
module.exports.get = () => list;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,13 @@ test('event-store: get', (t) => {
|
|||
|
||||
eventStore.add(el, name, fn);
|
||||
const result = eventStore.get();
|
||||
|
||||
const expected = [
|
||||
[el, name, fn],
|
||||
[
|
||||
el,
|
||||
name,
|
||||
fn,
|
||||
],
|
||||
];
|
||||
|
||||
t.deepEqual(result, expected);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ function EventsProto() {
|
|||
const getEventOptions = (eventName) => {
|
||||
if (eventName !== 'touchstart')
|
||||
return false;
|
||||
|
||||
|
||||
return {
|
||||
passive: true,
|
||||
};
|
||||
|
|
@ -35,12 +35,7 @@ function EventsProto() {
|
|||
if (!type.endsWith('element'))
|
||||
throw Error(`unknown eventName: ${type}`);
|
||||
|
||||
parseArgs(
|
||||
args[EVENT_NAME],
|
||||
args[ELEMENT],
|
||||
listener,
|
||||
callback,
|
||||
);
|
||||
parseArgs(args[EVENT_NAME], args[ELEMENT], listener, callback);
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
|
|
@ -62,33 +57,25 @@ function EventsProto() {
|
|||
break;
|
||||
|
||||
case 'array':
|
||||
|
||||
for (const name of eventName) {
|
||||
parseArgs(
|
||||
name,
|
||||
element,
|
||||
listener,
|
||||
callback,
|
||||
);
|
||||
parseArgs(name, element, listener, callback);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'object':
|
||||
|
||||
for (const name of Object.keys(eventName)) {
|
||||
const eventListener = eventName[name];
|
||||
|
||||
parseArgs(
|
||||
name,
|
||||
element,
|
||||
eventListener,
|
||||
callback,
|
||||
);
|
||||
parseArgs(name, element, eventListener, callback);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* safe add event listener
|
||||
*
|
||||
|
|
@ -108,7 +95,7 @@ function EventsProto() {
|
|||
|
||||
return Events;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe add event listener
|
||||
*
|
||||
|
|
@ -131,7 +118,7 @@ function EventsProto() {
|
|||
|
||||
return Events;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe remove event listener
|
||||
*
|
||||
|
|
@ -148,7 +135,7 @@ function EventsProto() {
|
|||
|
||||
return Events;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* remove all added event listeners
|
||||
*
|
||||
|
|
@ -162,7 +149,7 @@ function EventsProto() {
|
|||
|
||||
EventStore.clear();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe add event keydown listener
|
||||
*
|
||||
|
|
@ -170,11 +157,14 @@ function EventsProto() {
|
|||
*/
|
||||
this.addKey = function(...argsArr) {
|
||||
const name = 'keydown';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.add(...args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe remove event click listener
|
||||
*
|
||||
|
|
@ -182,11 +172,14 @@ function EventsProto() {
|
|||
*/
|
||||
this.rmKey = function(...argsArr) {
|
||||
const name = 'keydown';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.remove(...args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe add event click listener
|
||||
*
|
||||
|
|
@ -194,11 +187,14 @@ function EventsProto() {
|
|||
*/
|
||||
this.addClick = function(...argsArr) {
|
||||
const name = 'click';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.add(...args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe remove event click listener
|
||||
*
|
||||
|
|
@ -206,18 +202,24 @@ function EventsProto() {
|
|||
*/
|
||||
this.rmClick = function(...argsArr) {
|
||||
const name = 'click';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.remove(...args);
|
||||
};
|
||||
|
||||
this.addContextMenu = function(...argsArr) {
|
||||
const name = 'contextmenu';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.add(...args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe add event click listener
|
||||
*
|
||||
|
|
@ -225,11 +227,14 @@ function EventsProto() {
|
|||
*/
|
||||
this.addError = function(...argsArr) {
|
||||
const name = 'error';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.add(...args);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* safe add load click listener
|
||||
*
|
||||
|
|
@ -237,7 +242,10 @@ function EventsProto() {
|
|||
*/
|
||||
this.addLoad = function(...argsArr) {
|
||||
const name = 'load';
|
||||
const args = [name, ...argsArr];
|
||||
const args = [
|
||||
name,
|
||||
...argsArr,
|
||||
];
|
||||
|
||||
return Events.add(...args);
|
||||
};
|
||||
|
|
@ -247,4 +255,3 @@ function EventsProto() {
|
|||
throw Error('type could not be empty!');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const itype = require('itype');
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
|
|
@ -49,6 +48,7 @@ function getModule(name) {
|
|||
return getConfig();
|
||||
|
||||
const path = getPath(name, isHTML, isJSON);
|
||||
|
||||
return getSystemFile(path);
|
||||
}
|
||||
|
||||
|
|
@ -137,4 +137,3 @@ function getTimeoutOnce(time) {
|
|||
}, time);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ function getLoadingType() {
|
|||
}
|
||||
|
||||
module.exports.get = getElement;
|
||||
|
||||
/**
|
||||
* check SVG SMIL animation support
|
||||
*/
|
||||
|
|
@ -69,7 +68,6 @@ module.exports.error = () => {
|
|||
module.exports.show = show;
|
||||
module.exports.show.load = show;
|
||||
module.exports.show.error = error;
|
||||
|
||||
/**
|
||||
* Function shows loading spinner
|
||||
* position = {top: true};
|
||||
|
|
@ -147,4 +145,3 @@ module.exports.clearProgress = () => {
|
|||
|
||||
return Images;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const Util = require('../../common/util');
|
||||
|
||||
const Images = require('./images');
|
||||
|
|
@ -41,8 +40,8 @@ const selectByPattern = require('./select-by-pattern');
|
|||
|
||||
const SELECTED_FILE = 'selected-file';
|
||||
const TabPanel = {
|
||||
'js-left' : null,
|
||||
'js-right' : null,
|
||||
'js-left': null,
|
||||
'js-right': null,
|
||||
};
|
||||
|
||||
module.exports.loadRemote = (name, options, callback) => {
|
||||
|
|
@ -52,7 +51,7 @@ module.exports.loadRemote = (name, options, callback) => {
|
|||
|
||||
module.exports.loadSocket = (callback) => {
|
||||
DOM.loadRemote('socket', {
|
||||
name : 'io',
|
||||
name: 'io',
|
||||
}, callback);
|
||||
|
||||
return DOM;
|
||||
|
|
@ -80,6 +79,7 @@ async function promptNew(typeName) {
|
|||
const {Dialog} = DOM;
|
||||
const dir = DOM.getCurrentDirPath();
|
||||
const msg = `New ${typeName}` || 'File';
|
||||
|
||||
const getName = () => {
|
||||
const name = DOM.getCurrentName();
|
||||
|
||||
|
|
@ -111,11 +111,12 @@ async function promptNew(typeName) {
|
|||
* get current direcotory name
|
||||
*/
|
||||
module.exports.getCurrentDirName = () => {
|
||||
const href = DOM.getCurrentDirPath()
|
||||
const href = DOM
|
||||
.getCurrentDirPath()
|
||||
.replace(/\/$/, '');
|
||||
|
||||
const substr = href.substr(href, href.lastIndexOf('/'));
|
||||
const ret = href.replace(`${substr}/`, '') || '/';
|
||||
const substr = href.substr(href, href.lastIndexOf('/'));
|
||||
const ret = href.replace(`${substr}/`, '') || '/';
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
|
@ -138,7 +139,9 @@ module.exports.getParentDirPath = (panel) => {
|
|||
* get not current direcotory path
|
||||
*/
|
||||
module.exports.getNotCurrentDirPath = () => {
|
||||
const panel = DOM.getPanel({active: false});
|
||||
const panel = DOM.getPanel({
|
||||
active: false,
|
||||
});
|
||||
const path = DOM.getCurrentDirPath(panel);
|
||||
|
||||
return path;
|
||||
|
|
@ -162,7 +165,9 @@ module.exports.getSelectedFiles = () => {
|
|||
module.exports.unselectFiles = (files) => {
|
||||
files = files || DOM.getSelectedFiles();
|
||||
|
||||
Array.from(files).forEach(DOM.toggleSelectedFile);
|
||||
Array
|
||||
.from(files)
|
||||
.forEach(DOM.toggleSelectedFile);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -183,9 +188,7 @@ module.exports.getActiveFiles = () => {
|
|||
|
||||
module.exports.getCurrentDate = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
const date = DOM
|
||||
.getByDataName('js-date', current)
|
||||
.textContent;
|
||||
const date = DOM.getByDataName('js-date', current).textContent;
|
||||
|
||||
return date;
|
||||
};
|
||||
|
|
@ -196,8 +199,10 @@ module.exports.getCurrentDate = (currentFile) => {
|
|||
*/
|
||||
module.exports.getCurrentSize = (currentFile) => {
|
||||
const current = currentFile || DOM.getCurrentFile();
|
||||
|
||||
/* если это папка - возвращаем слово dir вместо размера*/
|
||||
const size = DOM.getByDataName('js-size', current)
|
||||
const size = DOM
|
||||
.getByDataName('js-size', current)
|
||||
.textContent
|
||||
.replace(/^<|>$/g, '');
|
||||
|
||||
|
|
@ -237,6 +242,7 @@ module.exports.loadCurrentHash = async (currentFile) => {
|
|||
const link = DOM.getCurrentPath(current);
|
||||
|
||||
const [, data] = await RESTful.read(link + query);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
|
|
@ -285,7 +291,9 @@ module.exports.getCurrentData = async (currentFile) => {
|
|||
|
||||
if (Info.name === '..') {
|
||||
Dialog.alert.noFiles();
|
||||
return [Error('No Files')];
|
||||
return [
|
||||
Error('No Files'),
|
||||
];
|
||||
}
|
||||
|
||||
if (isDir)
|
||||
|
|
@ -294,7 +302,9 @@ module.exports.getCurrentData = async (currentFile) => {
|
|||
const [hashNew, hash] = await DOM.checkStorageHash(path);
|
||||
|
||||
if (!hashNew)
|
||||
return [Error(`Can't get hash of a file`)];
|
||||
return [
|
||||
Error(`Can't get hash of a file`),
|
||||
];
|
||||
|
||||
if (hash === hashNew)
|
||||
return [null, await Storage.get(`${path}-data`)];
|
||||
|
|
@ -302,7 +312,10 @@ module.exports.getCurrentData = async (currentFile) => {
|
|||
const [e, data] = await RESTful.read(path);
|
||||
|
||||
if (e)
|
||||
return [e, null];
|
||||
return [
|
||||
e,
|
||||
null,
|
||||
];
|
||||
|
||||
const ONE_MEGABYTE = 1024 ** 2 * 1024;
|
||||
const {length} = data;
|
||||
|
|
@ -353,13 +366,17 @@ module.exports.toggleSelectedFile = (currentFile) => {
|
|||
};
|
||||
|
||||
module.exports.toggleAllSelectedFiles = () => {
|
||||
DOM.getAllFiles().map(DOM.toggleSelectedFile);
|
||||
DOM
|
||||
.getAllFiles()
|
||||
.map(DOM.toggleSelectedFile);
|
||||
|
||||
return Cmd;
|
||||
};
|
||||
|
||||
module.exports.selectAllFiles = () => {
|
||||
DOM.getAllFiles().map(DOM.selectFile);
|
||||
DOM
|
||||
.getAllFiles()
|
||||
.map(DOM.selectFile);
|
||||
|
||||
return Cmd;
|
||||
};
|
||||
|
|
@ -372,7 +389,9 @@ module.exports.getAllFiles = () => {
|
|||
const from = (a) => a === '..' ? 1 : 0;
|
||||
const i = from(name);
|
||||
|
||||
return Array.from(files).slice(i);
|
||||
return Array
|
||||
.from(files)
|
||||
.slice(i);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -418,7 +437,7 @@ module.exports.setHistory = (data, title, url) => {
|
|||
module.exports.isSelected = (selected) => {
|
||||
if (!selected)
|
||||
return false;
|
||||
|
||||
|
||||
return DOM.isContainClass(selected, SELECTED_FILE);
|
||||
};
|
||||
|
||||
|
|
@ -550,7 +569,9 @@ module.exports.getFiles = (element) => {
|
|||
* shows panel right or left (or active)
|
||||
*/
|
||||
module.exports.showPanel = (active) => {
|
||||
const panel = DOM.getPanel({active});
|
||||
const panel = DOM.getPanel({
|
||||
active,
|
||||
});
|
||||
|
||||
if (!panel)
|
||||
return false;
|
||||
|
|
@ -627,7 +648,6 @@ module.exports.deleteSelected = (selected) => {
|
|||
* @currentFile
|
||||
*/
|
||||
module.exports.renameCurrent = renameCurrent;
|
||||
|
||||
/**
|
||||
* unified way to scrollIntoViewIfNeeded
|
||||
* (native suporte by webkit only)
|
||||
|
|
@ -702,7 +722,7 @@ module.exports.changePanel = () => {
|
|||
module.exports.getPackerExt = (type) => {
|
||||
if (type === 'zip')
|
||||
return '.zip';
|
||||
|
||||
|
||||
return '.tar.gz';
|
||||
};
|
||||
|
||||
|
|
@ -711,10 +731,7 @@ module.exports.goToDirectory = async () => {
|
|||
const {Dialog} = DOM;
|
||||
const {dirPath} = CurrentInfo;
|
||||
|
||||
const [
|
||||
cancel,
|
||||
path = dirPath,
|
||||
] = await Dialog.prompt(msg, dirPath);
|
||||
const [cancel, path = dirPath] = await Dialog.prompt(msg, dirPath);
|
||||
|
||||
if (cancel)
|
||||
return;
|
||||
|
|
@ -731,7 +748,7 @@ module.exports.duplicatePanel = async () => {
|
|||
const getPath = (isDir) => {
|
||||
if (isDir)
|
||||
return Info.path;
|
||||
|
||||
|
||||
return Info.dirPath;
|
||||
};
|
||||
|
||||
|
|
@ -790,26 +807,29 @@ module.exports.updateCurrentInfo = (currentFile) => {
|
|||
const filesPassive = DOM.getFiles(panelPassive);
|
||||
const name = DOM.getCurrentName(current);
|
||||
|
||||
info.dir = DOM.getCurrentDirName();
|
||||
info.dirPath = DOM.getCurrentDirPath();
|
||||
info.parentDirPath = DOM.getParentDirPath();
|
||||
info.element = current;
|
||||
info.ext = Util.getExt(name);
|
||||
info.files = Array.from(files.children);
|
||||
info.filesPassive = Array.from(filesPassive);
|
||||
info.first = files.firstChild;
|
||||
info.getData = DOM.getCurrentData;
|
||||
info.last = files.lastChild;
|
||||
info.link = DOM.getCurrentLink(current);
|
||||
info.mode = DOM.getCurrentMode(current);
|
||||
info.name = name;
|
||||
info.path = DOM.getCurrentPath(current);
|
||||
info.panel = files.parentElement || DOM.getPanel();
|
||||
info.panelPassive = panelPassive;
|
||||
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');
|
||||
info.dir = DOM.getCurrentDirName();
|
||||
info.dirPath = DOM.getCurrentDirPath();
|
||||
info.parentDirPath = DOM.getParentDirPath();
|
||||
info.element = current;
|
||||
info.ext = Util.getExt(name);
|
||||
info.files = Array.from(files.children);
|
||||
info.filesPassive = Array.from(filesPassive);
|
||||
info.first = files.firstChild;
|
||||
info.getData = DOM.getCurrentData;
|
||||
info.last = files.lastChild;
|
||||
info.link = DOM.getCurrentLink(current);
|
||||
info.mode = DOM.getCurrentMode(current);
|
||||
info.name = name;
|
||||
info.path = DOM.getCurrentPath(current);
|
||||
info.panel = files.parentElement || DOM.getPanel();
|
||||
info.panelPassive = panelPassive;
|
||||
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');
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,4 +29,3 @@ test('cloudcmd: client: dom: goToDirectory', async (t) => {
|
|||
t.calledWith(changeDir, [path]);
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ const imgPosition = {
|
|||
|
||||
module.exports.delete = async (url, data) => {
|
||||
return await sendRequest({
|
||||
method : 'DELETE',
|
||||
url : FS + url,
|
||||
method: 'DELETE',
|
||||
url: FS + url,
|
||||
data,
|
||||
imgPosition : {
|
||||
imgPosition: {
|
||||
top: Boolean(data),
|
||||
},
|
||||
});
|
||||
|
|
@ -149,4 +149,3 @@ module.exports.Markdown = {
|
|||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const mockRequire = require('mock-require');
|
||||
|
||||
const {reRequire, stopAll} = mockRequire;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
const Images = require('../images');
|
||||
|
|
@ -17,17 +16,14 @@ module.exports = promisify((params, callback) => {
|
|||
p.url = replaceHash(p.url);
|
||||
|
||||
load.ajax({
|
||||
method : p.method,
|
||||
url : p.url,
|
||||
data : p.data,
|
||||
dataType : p.dataType,
|
||||
error : (jqXHR) => {
|
||||
method: p.method,
|
||||
url: p.url,
|
||||
data: p.data,
|
||||
dataType: p.dataType,
|
||||
error: (jqXHR) => {
|
||||
const response = jqXHR.responseText;
|
||||
|
||||
const {
|
||||
statusText,
|
||||
status,
|
||||
} = jqXHR;
|
||||
const {statusText, status} = jqXHR;
|
||||
|
||||
const text = status === 404 ? response : statusText;
|
||||
|
||||
|
|
@ -52,4 +48,3 @@ function replaceHash(url) {
|
|||
*/
|
||||
return url.replace(/#/g, '%23');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,4 +11,3 @@ test('cloudcmd: client: io: replaceHash', (t) => {
|
|||
t.equal(result, expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const rendy = require('rendy');
|
||||
const itype = require('itype');
|
||||
const load = require('load.js');
|
||||
|
|
@ -18,41 +17,42 @@ module.exports = (name, options, callback = options) => {
|
|||
if (o.name && window[o.name])
|
||||
return callback();
|
||||
|
||||
Files.get('modules').then(async (modules) => {
|
||||
const online = config('online') && navigator.onLine;
|
||||
const module = findObjByNameInArr(modules.remote, name);
|
||||
Files
|
||||
.get('modules')
|
||||
.then(async (modules) => {
|
||||
const online = config('online') && navigator.onLine;
|
||||
const module = findObjByNameInArr(modules.remote, name);
|
||||
|
||||
const isArray = itype.array(module.local);
|
||||
const {version} = module;
|
||||
const isArray = itype.array(module.local);
|
||||
const {version} = module;
|
||||
|
||||
let remoteTmpls;
|
||||
let local;
|
||||
let remoteTmpls;
|
||||
let local;
|
||||
|
||||
if (isArray) {
|
||||
remoteTmpls = module.remote;
|
||||
local = module.local;
|
||||
} else {
|
||||
remoteTmpls = [module.remote];
|
||||
local = [module.local];
|
||||
}
|
||||
if (isArray) {
|
||||
remoteTmpls = module.remote;
|
||||
local = module.local;
|
||||
} else {
|
||||
remoteTmpls = [module.remote];
|
||||
local = [module.local];
|
||||
}
|
||||
|
||||
const localURL = local.map((url) => prefix + url);
|
||||
const localURL = local.map((url) => prefix + url);
|
||||
|
||||
const remoteURL = remoteTmpls.map((tmpl) => {
|
||||
return rendy(tmpl, {
|
||||
version,
|
||||
const remoteURL = remoteTmpls.map((tmpl) => {
|
||||
return rendy(tmpl, {
|
||||
version,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (online) {
|
||||
const [e] = await tryToCatch(load.parallel, remoteURL);
|
||||
if (online) {
|
||||
const [e] = await tryToCatch(load.parallel, remoteURL);
|
||||
|
||||
if (!e)
|
||||
return callback();
|
||||
}
|
||||
if (!e)
|
||||
return callback();
|
||||
}
|
||||
|
||||
const [e] = await tryToCatch(load.parallel, localURL);
|
||||
callback(e);
|
||||
});
|
||||
const [e] = await tryToCatch(load.parallel, localURL);
|
||||
callback(e);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ const exec = require('execon');
|
|||
const Images = require('./images');
|
||||
|
||||
module.exports.getIdBySrc = getIdBySrc;
|
||||
|
||||
/**
|
||||
* Function gets id by src
|
||||
* @param src
|
||||
|
|
@ -25,6 +24,7 @@ function getIdBySrc(src) {
|
|||
|
||||
const num = src.lastIndexOf('/') + 1;
|
||||
const sub = src.substr(src, num);
|
||||
|
||||
const id = src
|
||||
.replace(sub, '')
|
||||
.replace(/\./g, '-');
|
||||
|
|
@ -43,9 +43,9 @@ module.exports.ajax = (params) => {
|
|||
const isArray = itype.array(p.data);
|
||||
const isArrayBuf = itype(p.data) === 'arraybuffer';
|
||||
const type = p.type || p.method || 'GET';
|
||||
const {
|
||||
headers = {},
|
||||
} = p;
|
||||
|
||||
const {headers = {}} = p;
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open(type, p.url, true);
|
||||
|
|
@ -98,8 +98,7 @@ module.exports.put = (url, body) => {
|
|||
const emitter = Emitify();
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
url = encodeURI(url)
|
||||
.replace(/#/g, '%23');
|
||||
url = encodeURI(url).replace(/#/g, '%23');
|
||||
|
||||
xhr.open('put', url, true);
|
||||
|
||||
|
|
@ -133,4 +132,3 @@ module.exports.put = (url, body) => {
|
|||
|
||||
return emitter;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const capitalize = require('just-capitalize');
|
||||
|
||||
const Dialog = require('../dialog');
|
||||
const Storage = require('../storage');
|
||||
const RESTful = require('../rest');
|
||||
|
||||
const {
|
||||
isCurrentFile,
|
||||
getCurrentName,
|
||||
|
|
@ -60,4 +60,3 @@ module.exports = async (current) => {
|
|||
Storage.remove(dirPath);
|
||||
CloudCmd.refresh();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const mockRequire = require('mock-require');
|
||||
|
||||
const {reRequire, stopAll} = mockRequire;
|
||||
|
|
@ -55,6 +53,7 @@ test('cloudcmd: client: dom: renameCurrent: file exist', async (t) => {
|
|||
await renameCurrent();
|
||||
|
||||
const expected = 'Directory "hello" already exists. Proceed?';
|
||||
|
||||
global.CloudCmd = CloudCmd;
|
||||
|
||||
stopAll();
|
||||
|
|
@ -98,4 +97,3 @@ const stubCurrentFile = (fns = {}) => {
|
|||
setCurrentName,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ module.exports.Markdown = {
|
|||
read: handleError(IO.Markdown.read),
|
||||
render: handleError(IO.Markdown.render),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,7 @@
|
|||
let SelectType = '*.*';
|
||||
|
||||
const {getRegExp} = require('../../common/util');
|
||||
const {
|
||||
alert,
|
||||
prompt,
|
||||
} = require('./dialog');
|
||||
const {alert, prompt} = require('./dialog');
|
||||
|
||||
const DOM = require('.');
|
||||
|
||||
|
|
@ -15,8 +12,6 @@ module.exports = async (msg, files) => {
|
|||
return;
|
||||
|
||||
const allMsg = `Specify file type for ${msg} selection`;
|
||||
|
||||
/* eslint require-atomic-updates: 0 */
|
||||
const [cancel, type] = await prompt(allMsg, SelectType);
|
||||
|
||||
if (cancel)
|
||||
|
|
@ -48,4 +43,3 @@ module.exports = async (msg, files) => {
|
|||
if (!matches)
|
||||
alert('No matches found!');
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -26,4 +26,3 @@ module.exports.clear = () => {
|
|||
module.exports.remove = (item) => {
|
||||
localStorage.removeItem(item);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const storage = require('./storage');
|
||||
|
||||
const {stringify} = JSON;
|
||||
|
|
@ -32,6 +30,7 @@ test('cloudcmd: client: storage: get', async (t) => {
|
|||
};
|
||||
|
||||
const result = await storage.get('hello');
|
||||
|
||||
global.localStorage = localStorage;
|
||||
|
||||
t.equal(result, 'world');
|
||||
|
|
@ -43,6 +42,7 @@ test('cloudcmd: client: storage: getJson', async (t) => {
|
|||
const expected = {
|
||||
hello: 'world',
|
||||
};
|
||||
|
||||
const getItem = stub().returns(stringify(expected));
|
||||
|
||||
global.localStorage = {
|
||||
|
|
@ -50,6 +50,7 @@ test('cloudcmd: client: storage: getJson', async (t) => {
|
|||
};
|
||||
|
||||
const result = await storage.getJson('hello');
|
||||
|
||||
global.localStorage = localStorage;
|
||||
|
||||
t.deepEqual(result, expected);
|
||||
|
|
@ -105,4 +106,3 @@ test('cloudcmd: client: storage: clear', async (t) => {
|
|||
t.ok(clear.calledWith(), 'should call clear');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const {eachSeries} = require('execon');
|
||||
const wraptile = require('wraptile');
|
||||
|
||||
|
|
@ -55,13 +54,14 @@ function _loadFile(dir, n, file, callback) {
|
|||
|
||||
++i;
|
||||
|
||||
load.put(api + path, file)
|
||||
load
|
||||
.put(api + path, file)
|
||||
.on('error', showError)
|
||||
.on('end', callback)
|
||||
.on('progress', (count) => {
|
||||
const max = step(n);
|
||||
const value = (i - 1) * max + percent(count, 100, max);
|
||||
|
||||
|
||||
Images.show.load('top');
|
||||
Images.setProgress(Math.round(value));
|
||||
});
|
||||
|
|
@ -70,4 +70,3 @@ function _loadFile(dir, n, file, callback) {
|
|||
function showError({message}) {
|
||||
alert(message);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global DOM */
|
||||
|
||||
const Info = DOM.CurrentInfo;
|
||||
|
||||
/**
|
||||
|
|
@ -46,4 +45,3 @@ module.exports = () => {
|
|||
|
||||
return fileTable;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,4 +15,3 @@ module.exports.createBinder = () => {
|
|||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM */
|
||||
|
||||
const clipboard = require('@cloudcmd/clipboard');
|
||||
|
||||
const Buffer = require('../dom/buffer');
|
||||
|
|
@ -32,6 +31,7 @@ Chars([]);
|
|||
const {assign} = Object;
|
||||
|
||||
const binder = createBinder();
|
||||
|
||||
module.exports = assign(binder, KEY);
|
||||
module.exports.bind = () => {
|
||||
Events.addKey(listener, true);
|
||||
|
|
@ -45,13 +45,13 @@ function getChar(event) {
|
|||
* event.keyIdentifier deprecated in chrome v51
|
||||
* but event.key is absent in chrome <= v51
|
||||
*/
|
||||
|
||||
const {
|
||||
key,
|
||||
shift,
|
||||
keyCode,
|
||||
keyIdentifier,
|
||||
} = event;
|
||||
|
||||
const char = key || fromCharCode(keyIdentifier);
|
||||
const symbol = getSymbol(shift, keyCode);
|
||||
|
||||
|
|
@ -136,6 +136,7 @@ async function switchKey(event) {
|
|||
changeDir,
|
||||
config,
|
||||
} = CloudCmd;
|
||||
|
||||
const {keyCode} = event;
|
||||
|
||||
const alt = event.altKey;
|
||||
|
|
@ -156,12 +157,14 @@ async function switchKey(event) {
|
|||
break;
|
||||
|
||||
case KEY.INSERT:
|
||||
DOM .toggleSelectedFile(current)
|
||||
DOM
|
||||
.toggleSelectedFile(current)
|
||||
.setCurrentFile(next);
|
||||
break;
|
||||
|
||||
case KEY.INSERT_MAC:
|
||||
DOM .toggleSelectedFile(current)
|
||||
DOM
|
||||
.toggleSelectedFile(current)
|
||||
.setCurrentFile(next);
|
||||
break;
|
||||
|
||||
|
|
@ -170,7 +173,7 @@ async function switchKey(event) {
|
|||
Operation.show('delete:silent');
|
||||
else
|
||||
Operation.show('delete');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.ASTERISK:
|
||||
|
|
@ -305,7 +308,7 @@ async function switchKey(event) {
|
|||
DOM.swapPanels();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
/* navigation on file table: *
|
||||
|
|
@ -403,7 +406,7 @@ async function switchKey(event) {
|
|||
await changeDir(path);
|
||||
else
|
||||
CloudCmd.View.show();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.BACKSPACE:
|
||||
|
|
@ -414,7 +417,7 @@ async function switchKey(event) {
|
|||
case KEY.BACKSLASH:
|
||||
if (ctrlMeta)
|
||||
await changeDir('/');
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.A:
|
||||
|
|
@ -455,6 +458,7 @@ async function switchKey(event) {
|
|||
.catch(CloudCmd.log);
|
||||
|
||||
break;
|
||||
|
||||
/**
|
||||
* обновляем страницу,
|
||||
* загружаем содержимое каталога
|
||||
|
|
@ -468,31 +472,31 @@ async function switchKey(event) {
|
|||
CloudCmd.refresh();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.C:
|
||||
if (ctrlMeta)
|
||||
Buffer.copy();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.X:
|
||||
if (ctrlMeta)
|
||||
Buffer.cut();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.V:
|
||||
if (ctrlMeta)
|
||||
Buffer.paste();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.Z:
|
||||
if (ctrlMeta)
|
||||
Buffer.clear();
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case KEY.COLON:
|
||||
|
|
@ -508,8 +512,7 @@ async function switchKey(event) {
|
|||
CloudCmd.log('storage cleared');
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,8 @@ const autoGlobals = require('auto-globals');
|
|||
const stub = require('@cloudcmd/stub');
|
||||
const mockRequire = require('mock-require');
|
||||
const {ESC} = require('./key');
|
||||
const {
|
||||
getDOM,
|
||||
getCloudCmd,
|
||||
} = require('./vim/globals.fixture');
|
||||
|
||||
const {getDOM, getCloudCmd} = require('./vim/globals.fixture');
|
||||
|
||||
const {reRequire, stopAll} = mockRequire;
|
||||
|
||||
|
|
@ -66,4 +64,3 @@ test('cloudcmd: client: key: disable vim', async (t) => {
|
|||
t.calledWith(_config, ['vim']);
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,81 +1,81 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
BACKSPACE : 8,
|
||||
TAB : 9,
|
||||
ENTER : 13,
|
||||
CAPSLOCK : 20,
|
||||
ESC : 27,
|
||||
BACKSPACE: 8,
|
||||
TAB: 9,
|
||||
ENTER: 13,
|
||||
CAPSLOCK: 20,
|
||||
ESC: 27,
|
||||
|
||||
SPACE : 32,
|
||||
PAGE_UP : 33,
|
||||
PAGE_DOWN : 34,
|
||||
END : 35,
|
||||
HOME : 36,
|
||||
SPACE: 32,
|
||||
PAGE_UP: 33,
|
||||
PAGE_DOWN: 34,
|
||||
END: 35,
|
||||
HOME: 36,
|
||||
|
||||
LEFT : 37,
|
||||
UP : 38,
|
||||
RIGHT : 39,
|
||||
DOWN : 40,
|
||||
LEFT: 37,
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40,
|
||||
|
||||
INSERT : 45,
|
||||
DELETE : 46,
|
||||
INSERT: 45,
|
||||
DELETE: 46,
|
||||
|
||||
ZERO : 48,
|
||||
ZERO: 48,
|
||||
|
||||
SEMICOLON : 52,
|
||||
SEMICOLON: 52,
|
||||
|
||||
A : 65,
|
||||
A: 65,
|
||||
|
||||
C : 67,
|
||||
D : 68,
|
||||
C: 67,
|
||||
D: 68,
|
||||
|
||||
G : 71,
|
||||
G: 71,
|
||||
|
||||
J : 74,
|
||||
K : 75,
|
||||
J: 74,
|
||||
K: 75,
|
||||
|
||||
M : 77,
|
||||
M: 77,
|
||||
|
||||
O : 79,
|
||||
P : 80,
|
||||
Q : 81,
|
||||
R : 82,
|
||||
S : 83,
|
||||
T : 84,
|
||||
U : 85,
|
||||
O: 79,
|
||||
P: 80,
|
||||
Q: 81,
|
||||
R: 82,
|
||||
S: 83,
|
||||
T: 84,
|
||||
U: 85,
|
||||
|
||||
V : 86,
|
||||
V: 86,
|
||||
|
||||
X : 88,
|
||||
X: 88,
|
||||
|
||||
Z : 90,
|
||||
Z: 90,
|
||||
|
||||
INSERT_MAC : 96,
|
||||
INSERT_MAC: 96,
|
||||
|
||||
ASTERISK : 106,
|
||||
PLUS : 107,
|
||||
MINUS : 109,
|
||||
ASTERISK: 106,
|
||||
PLUS: 107,
|
||||
MINUS: 109,
|
||||
|
||||
F1 : 112,
|
||||
F2 : 113,
|
||||
F3 : 114,
|
||||
F4 : 115,
|
||||
F5 : 116,
|
||||
F6 : 117,
|
||||
F7 : 118,
|
||||
F8 : 119,
|
||||
F9 : 120,
|
||||
F10 : 121,
|
||||
F1: 112,
|
||||
F2: 113,
|
||||
F3: 114,
|
||||
F4: 115,
|
||||
F5: 116,
|
||||
F6: 117,
|
||||
F7: 118,
|
||||
F8: 119,
|
||||
F9: 120,
|
||||
F10: 121,
|
||||
|
||||
COLON : 186,
|
||||
EQUAL : 187,
|
||||
HYPHEN : 189,
|
||||
DOT : 190,
|
||||
SLASH : 191,
|
||||
TRA : 192, /* Typewritten Reverse Apostrophe (`) */
|
||||
BACKSLASH : 220,
|
||||
COLON: 186,
|
||||
EQUAL: 187,
|
||||
HYPHEN: 189,
|
||||
DOT: 190,
|
||||
SLASH: 191,
|
||||
/* Typewritten Reverse Apostrophe (`) */
|
||||
TRA: 192,
|
||||
BACKSLASH: 220,
|
||||
|
||||
BRACKET_CLOSE: 221,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ module.exports = function setCurrentByChar(char, charStore) {
|
|||
const isTest = (a) => regExp.test(a);
|
||||
const isRoot = (a) => a === '..';
|
||||
const not = (f) => (a) => !f(a);
|
||||
|
||||
const setCurrent = (name) => {
|
||||
const byName = DOM.getCurrentByName(name);
|
||||
|
||||
|
|
@ -57,4 +58,3 @@ module.exports = function setCurrentByChar(char, charStore) {
|
|||
charStore([char]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,13 @@ module.exports._previous = previous;
|
|||
function next(index, length) {
|
||||
if (index === length - 1)
|
||||
return 0;
|
||||
|
||||
|
||||
return ++index;
|
||||
}
|
||||
|
||||
function previous(index, length) {
|
||||
if (!index)
|
||||
return length - 1;
|
||||
|
||||
|
||||
return --index;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ const {getDOM} = require('./globals.fixture');
|
|||
|
||||
global.DOM = getDOM();
|
||||
|
||||
const {
|
||||
_next,
|
||||
_previous,
|
||||
} = require(`${dir}find`);
|
||||
const {_next, _previous} = require(`${dir}find`);
|
||||
|
||||
test('cloudcmd: client: vim: _next', (t) => {
|
||||
const result = _next(1, 2);
|
||||
|
|
@ -25,4 +22,3 @@ test('cloudcmd: client: vim: _previous', (t) => {
|
|||
t.equal(result, 1, 'should return 1');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ module.exports.getCloudCmd = () => {
|
|||
const show = () => {};
|
||||
|
||||
return {
|
||||
Operation: {
|
||||
Operation: {
|
||||
show,
|
||||
},
|
||||
|
||||
|
|
@ -46,4 +46,3 @@ module.exports.getCloudCmd = () => {
|
|||
_config: noop,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
/* global CloudCmd */
|
||||
/* global DOM */
|
||||
|
||||
const vim = require('./vim');
|
||||
const finder = require('./find');
|
||||
|
||||
|
|
@ -16,43 +15,43 @@ module.exports = async (key, event) => {
|
|||
|
||||
const getOperations = (event) => ({
|
||||
escape: DOM.unselectFiles,
|
||||
|
||||
|
||||
remove: () => {
|
||||
CloudCmd.Operation.show('delete');
|
||||
},
|
||||
|
||||
|
||||
makeDirectory: () => {
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
DOM.promptNewDir();
|
||||
},
|
||||
|
||||
|
||||
makeFile: () => {
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
DOM.promptNewFile();
|
||||
},
|
||||
|
||||
|
||||
terminal: () => {
|
||||
CloudCmd.Terminal.show();
|
||||
},
|
||||
|
||||
|
||||
edit: () => {
|
||||
CloudCmd.EditFileVim.show();
|
||||
},
|
||||
|
||||
|
||||
copy: () => {
|
||||
DOM.Buffer.copy();
|
||||
DOM.unselectFiles();
|
||||
},
|
||||
|
||||
|
||||
select: () => {
|
||||
const current = Info.element;
|
||||
DOM.toggleSelectedFile(current);
|
||||
},
|
||||
|
||||
|
||||
paste: DOM.Buffer.paste,
|
||||
|
||||
|
||||
moveNext: ({count, isVisual, isDelete}) => {
|
||||
setCurrent('next', {
|
||||
count,
|
||||
|
|
@ -60,7 +59,7 @@ const getOperations = (event) => ({
|
|||
isDelete,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
movePrevious: ({count, isVisual, isDelete}) => {
|
||||
setCurrent('previous', {
|
||||
count,
|
||||
|
|
@ -68,25 +67,25 @@ const getOperations = (event) => ({
|
|||
isDelete,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
find: async () => {
|
||||
event.preventDefault();
|
||||
const [, value] = await Dialog.prompt('Find', '');
|
||||
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
|
||||
const names = Info.files.map(DOM.getCurrentName);
|
||||
const [result] = finder.find(value, names);
|
||||
|
||||
|
||||
DOM.setCurrentByName(result);
|
||||
},
|
||||
|
||||
|
||||
findNext: () => {
|
||||
const name = finder.findNext();
|
||||
DOM.setCurrentByName(name);
|
||||
},
|
||||
|
||||
|
||||
findPrevious: () => {
|
||||
const name = finder.findPrevious();
|
||||
DOM.setCurrentByName(name);
|
||||
|
|
@ -97,34 +96,33 @@ module.exports.selectFile = selectFile;
|
|||
|
||||
function selectFile(current) {
|
||||
const name = DOM.getCurrentName(current);
|
||||
|
||||
|
||||
if (name === '..')
|
||||
return;
|
||||
|
||||
|
||||
DOM.selectFile(current);
|
||||
}
|
||||
|
||||
function setCurrent(sibling, {count, isVisual, isDelete}) {
|
||||
let current = Info.element;
|
||||
const select = isVisual ? selectFile : DOM.unselectFile;
|
||||
|
||||
|
||||
select(current);
|
||||
|
||||
|
||||
const position = `${sibling}Sibling`;
|
||||
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const next = current[position];
|
||||
|
||||
|
||||
if (!next)
|
||||
break;
|
||||
|
||||
|
||||
current = next;
|
||||
select(current);
|
||||
}
|
||||
|
||||
|
||||
DOM.setCurrentFile(current);
|
||||
|
||||
|
||||
if (isDelete)
|
||||
CloudCmd.Operation.show('delete');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,20 +2,15 @@
|
|||
|
||||
const {join} = require('path');
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const mockRequire = require('mock-require');
|
||||
|
||||
const dir = '../';
|
||||
|
||||
const pathVim = join(dir, 'vim');
|
||||
|
||||
const {
|
||||
getDOM,
|
||||
getCloudCmd,
|
||||
} = require('./globals.fixture');
|
||||
const {getDOM, getCloudCmd} = require('./globals.fixture');
|
||||
|
||||
global.DOM = getDOM();
|
||||
global.CloudCmd = getCloudCmd();
|
||||
|
|
@ -23,10 +18,7 @@ global.CloudCmd = getCloudCmd();
|
|||
const vim = require(pathVim);
|
||||
|
||||
const {assign} = Object;
|
||||
const {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
} = global;
|
||||
const {DOM, CloudCmd} = global;
|
||||
|
||||
const {Buffer} = DOM;
|
||||
const pathFind = join(dir, 'vim', 'find');
|
||||
|
|
@ -34,14 +26,14 @@ const {reRequire, stopAll} = mockRequire;
|
|||
|
||||
test('cloudcmd: client: key: set next file: no', (t) => {
|
||||
const element = {};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('j', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [element], 'should set next file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -51,14 +43,14 @@ test('cloudcmd: client: key: set next file current: j', (t) => {
|
|||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('j', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [nextSibling], 'should set next file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -68,16 +60,16 @@ test('cloudcmd: client: key: set next file current: mjj', (t) => {
|
|||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('m', {});
|
||||
vim('j', {});
|
||||
vim('j', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [nextSibling], 'should set next file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -87,15 +79,15 @@ test('cloudcmd: client: key: set next file current: g', (t) => {
|
|||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('g', {});
|
||||
vim('j', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [nextSibling], 'should ignore g');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -105,20 +97,21 @@ test('cloudcmd: client: key: set +2 file current', (t) => {
|
|||
const nextSibling = {
|
||||
nextSibling: last,
|
||||
};
|
||||
|
||||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
const event = {};
|
||||
|
||||
|
||||
vim('2', event);
|
||||
vim('j', event);
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [last], 'should set next file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -128,24 +121,25 @@ test('cloudcmd: client: key: select +2 files from current before delete', (t) =>
|
|||
const nextSibling = {
|
||||
nextSibling: last,
|
||||
};
|
||||
|
||||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
global.DOM.selectFile = stub();
|
||||
global.DOM.getCurrentName = () => false;
|
||||
global.CloudCmd.Operation.show = stub();
|
||||
|
||||
|
||||
const event = {};
|
||||
|
||||
|
||||
vim('d', event);
|
||||
vim('2', event);
|
||||
vim('j', event);
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [last], 'should set next file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -155,25 +149,26 @@ test('cloudcmd: client: key: delete +2 files from current', (t) => {
|
|||
const nextSibling = {
|
||||
nextSibling: last,
|
||||
};
|
||||
|
||||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
const show = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
global.DOM.selectFile = stub();
|
||||
global.DOM.getCurrentName = () => false;
|
||||
global.CloudCmd.Operation.show = show;
|
||||
|
||||
|
||||
const event = {};
|
||||
|
||||
|
||||
vim('d', event);
|
||||
vim('2', event);
|
||||
vim('j', event);
|
||||
|
||||
|
||||
t.calledWith(show, ['delete'], 'should call delete');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -183,87 +178,87 @@ test('cloudcmd: client: key: set previous file current', (t) => {
|
|||
const element = {
|
||||
previousSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('k', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [previousSibling], 'should set previous file');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: copy: no', (t) => {
|
||||
const copy = stub();
|
||||
|
||||
|
||||
Buffer.copy = copy;
|
||||
|
||||
|
||||
vim('y', {});
|
||||
|
||||
|
||||
t.notOk(copy.called, 'should not copy files');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: copy', (t) => {
|
||||
const copy = stub();
|
||||
|
||||
|
||||
Buffer.copy = copy;
|
||||
|
||||
|
||||
vim('v', {});
|
||||
vim('y', {});
|
||||
|
||||
|
||||
t.ok(copy.calledWith(), 'should copy files');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: copy: unselectFiles', (t) => {
|
||||
const unselectFiles = stub();
|
||||
|
||||
|
||||
DOM.unselectFiles = unselectFiles;
|
||||
|
||||
|
||||
vim('v', {});
|
||||
vim('y', {});
|
||||
|
||||
|
||||
t.ok(unselectFiles.calledWith(), 'should unselect files');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: paste', (t) => {
|
||||
const paste = stub();
|
||||
|
||||
|
||||
Buffer.paste = paste;
|
||||
|
||||
|
||||
vim('p', {});
|
||||
|
||||
|
||||
t.ok(paste.calledWith(), 'should paste files');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: selectFile: ..', (t) => {
|
||||
const getCurrentName = stub();
|
||||
|
||||
|
||||
DOM.selectFile = stub();
|
||||
DOM.getCurrentName = () => '..';
|
||||
|
||||
|
||||
const current = {};
|
||||
vim.selectFile(current);
|
||||
|
||||
|
||||
t.notOk(getCurrentName.called, 'should not call selectFile');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: selectFile', (t) => {
|
||||
const selectFile = stub();
|
||||
|
||||
|
||||
DOM.selectFile = selectFile;
|
||||
DOM.getCurrentName = (a) => a.name;
|
||||
|
||||
|
||||
const current = {};
|
||||
|
||||
|
||||
vim.selectFile(current);
|
||||
|
||||
|
||||
t.calledWith(selectFile, [current], 'should call selectFile');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -273,17 +268,18 @@ test('cloudcmd: client: key: set last file current: shift + g', (t) => {
|
|||
const nextSibling = {
|
||||
nextSibling: last,
|
||||
};
|
||||
|
||||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('G', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [last], 'should set last file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -293,17 +289,18 @@ test('cloudcmd: client: key: set last file current: $', (t) => {
|
|||
const nextSibling = {
|
||||
nextSibling: last,
|
||||
};
|
||||
|
||||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('$', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [last], 'should set last file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -313,19 +310,19 @@ test('cloudcmd: client: key: set first file current: gg', (t) => {
|
|||
const previousSibling = {
|
||||
previousSibling: first,
|
||||
};
|
||||
|
||||
|
||||
const element = {
|
||||
previousSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('g', {});
|
||||
vim('g', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [first], 'should set first file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -335,46 +332,46 @@ test('cloudcmd: client: key: set first file current: ^', (t) => {
|
|||
const previousSibling = {
|
||||
previousSibling: first,
|
||||
};
|
||||
|
||||
|
||||
const element = {
|
||||
previousSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('^', {});
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [first], 'should set first file');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: visual', (t) => {
|
||||
const element = {};
|
||||
|
||||
|
||||
const toggleSelectedFile = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.toggleSelectedFile = toggleSelectedFile;
|
||||
|
||||
|
||||
vim('v', {});
|
||||
|
||||
|
||||
t.calledWith(toggleSelectedFile, [element], 'should toggle selection');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: ESC', (t) => {
|
||||
const element = {};
|
||||
|
||||
|
||||
const unselectFiles = stub();
|
||||
|
||||
|
||||
global.DOM.CurrentInfo.element = element;
|
||||
global.DOM.unselectFiles = unselectFiles ;
|
||||
|
||||
global.DOM.unselectFiles = unselectFiles;
|
||||
|
||||
vim('Escape');
|
||||
|
||||
|
||||
t.ok(unselectFiles.calledWith(), 'should toggle selection');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -384,16 +381,16 @@ test('cloudcmd: client: key: Enter', (t) => {
|
|||
const element = {
|
||||
nextSibling,
|
||||
};
|
||||
|
||||
|
||||
const setCurrentFile = stub();
|
||||
|
||||
|
||||
DOM.CurrentInfo.element = element;
|
||||
DOM.setCurrentFile = setCurrentFile;
|
||||
|
||||
|
||||
vim('Enter');
|
||||
|
||||
|
||||
vim('j');
|
||||
|
||||
|
||||
t.calledWith(setCurrentFile, [nextSibling], 'should set next file');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -401,14 +398,14 @@ test('cloudcmd: client: key: Enter', (t) => {
|
|||
test('cloudcmd: client: key: /', (t) => {
|
||||
const preventDefault = stub();
|
||||
const element = {};
|
||||
|
||||
|
||||
DOM.CurrentInfo.element = element;
|
||||
DOM.getCurrentName = () => '';
|
||||
|
||||
|
||||
vim('/', {
|
||||
preventDefault,
|
||||
});
|
||||
|
||||
|
||||
t.calledWithNoArgs(preventDefault, 'should call preventDefault');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -417,94 +414,97 @@ test('cloudcmd: client: find', (t) => {
|
|||
assign(DOM.Dialog, {
|
||||
prompt: stub().returns([]),
|
||||
});
|
||||
|
||||
|
||||
const setCurrentByName = stub();
|
||||
|
||||
|
||||
assign(DOM, {
|
||||
setCurrentByName,
|
||||
});
|
||||
|
||||
|
||||
const vim = reRequire(pathVim);
|
||||
|
||||
const event = {
|
||||
preventDefault: stub(),
|
||||
};
|
||||
|
||||
|
||||
vim('/', event);
|
||||
|
||||
|
||||
stopAll();
|
||||
|
||||
|
||||
t.notCalled(setCurrentByName);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: n', (t) => {
|
||||
const findNext = stub();
|
||||
|
||||
|
||||
mockRequire(pathFind, {
|
||||
findNext,
|
||||
});
|
||||
|
||||
|
||||
const vim = reRequire(pathVim);
|
||||
const event = {};
|
||||
|
||||
|
||||
vim('n', event);
|
||||
|
||||
|
||||
stopAll();
|
||||
|
||||
|
||||
t.ok(findNext.calledWith(), 'should call findNext');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: N', (t) => {
|
||||
const findPrevious = stub();
|
||||
|
||||
|
||||
mockRequire(pathFind, {
|
||||
findPrevious,
|
||||
});
|
||||
|
||||
|
||||
const vim = reRequire(`${dir}vim`);
|
||||
const event = {};
|
||||
|
||||
|
||||
vim('N', event);
|
||||
|
||||
|
||||
stopAll();
|
||||
|
||||
|
||||
t.ok(findPrevious.calledWith(), 'should call findPrevious');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: make directory', (t) => {
|
||||
const vim = reRequire(pathVim);
|
||||
|
||||
|
||||
assign(DOM, {
|
||||
promptNewDir: stub(),
|
||||
});
|
||||
|
||||
|
||||
const event = {
|
||||
stopImmediatePropagation: stub(),
|
||||
preventDefault: stub(),
|
||||
};
|
||||
|
||||
vim('m', event);
|
||||
vim('d', event);
|
||||
|
||||
|
||||
t.calledWithNoArgs(DOM.promptNewDir);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('cloudcmd: client: key: make file', (t) => {
|
||||
const vim = reRequire(pathVim);
|
||||
|
||||
|
||||
assign(DOM, {
|
||||
promptNewFile: stub(),
|
||||
});
|
||||
|
||||
|
||||
const event = {
|
||||
stopImmediatePropagation: stub(),
|
||||
preventDefault: stub(),
|
||||
};
|
||||
|
||||
vim('m', event);
|
||||
vim('f', event);
|
||||
|
||||
|
||||
t.calledWithNoArgs(DOM.promptNewDir);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -515,12 +515,12 @@ test('cloudcmd: client: vim: terminal', (t) => {
|
|||
show: stub(),
|
||||
},
|
||||
});
|
||||
|
||||
const event = {
|
||||
};
|
||||
|
||||
const event = {};
|
||||
|
||||
vim('t', event);
|
||||
vim('t', event);
|
||||
|
||||
|
||||
t.calledWithNoArgs(CloudCmd.Terminal.show);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -531,12 +531,11 @@ test('cloudcmd: client: vim: edit', (t) => {
|
|||
show: stub(),
|
||||
},
|
||||
});
|
||||
|
||||
const event = {
|
||||
};
|
||||
|
||||
const event = {};
|
||||
|
||||
vim('e', event);
|
||||
|
||||
|
||||
t.calledWithNoArgs(CloudCmd.EditFileVim.show);
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ module.exports = (key, operations) => {
|
|||
const prevStore = store();
|
||||
const isVisual = visual();
|
||||
const value = store(prevStore.concat(key));
|
||||
|
||||
const {
|
||||
escape = noop,
|
||||
moveNext = noop,
|
||||
|
|
@ -41,132 +42,129 @@ module.exports = (key, operations) => {
|
|||
terminal = noop,
|
||||
edit = noop,
|
||||
} = operations;
|
||||
|
||||
|
||||
if (key === 'Enter')
|
||||
return end();
|
||||
|
||||
|
||||
if (key === 'Escape') {
|
||||
visual(false);
|
||||
escape();
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'j' || key === 'w') {
|
||||
const {
|
||||
count,
|
||||
isDelete,
|
||||
isVisual,
|
||||
} = handleDelete(prevStore);
|
||||
|
||||
|
||||
!isNaN(count) && moveNext({
|
||||
count,
|
||||
isVisual,
|
||||
isDelete,
|
||||
});
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'k' || key === 'b') {
|
||||
const {
|
||||
count,
|
||||
isDelete,
|
||||
isVisual,
|
||||
} = handleDelete(prevStore);
|
||||
|
||||
|
||||
!isNaN(count) && movePrevious({
|
||||
count,
|
||||
isVisual,
|
||||
isDelete,
|
||||
});
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (value === 'gg' || key === '^') {
|
||||
const {
|
||||
isDelete,
|
||||
isVisual,
|
||||
} = handleDelete(prevStore);
|
||||
|
||||
const {isDelete, isVisual} = handleDelete(prevStore);
|
||||
|
||||
movePrevious({
|
||||
count: Infinity,
|
||||
isVisual,
|
||||
isDelete,
|
||||
});
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (value === 'md') {
|
||||
makeDirectory();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (value === 'tt') {
|
||||
terminal();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (value === 'e') {
|
||||
edit();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (value === 'mf') {
|
||||
makeFile();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'd' && (visual() || prevStore === 'd')) {
|
||||
stopVisual();
|
||||
remove();
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'G' || key === '$') {
|
||||
moveNext({
|
||||
count: Infinity,
|
||||
isVisual,
|
||||
});
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'y') {
|
||||
if (!visual())
|
||||
return end();
|
||||
|
||||
|
||||
stopVisual();
|
||||
copy();
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (/^p$/i.test(key)) {
|
||||
paste();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (/^v$/i.test(key)) {
|
||||
visual(!visual());
|
||||
select();
|
||||
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === '/') {
|
||||
find();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'n') {
|
||||
findNext();
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
if (key === 'N') {
|
||||
findPrevious();
|
||||
return end();
|
||||
|
|
@ -175,15 +173,15 @@ module.exports = (key, operations) => {
|
|||
|
||||
function handleDelete(prevStore) {
|
||||
const isDelete = prevStore[0] === 'd';
|
||||
|
||||
|
||||
if (isDelete) {
|
||||
visual(true);
|
||||
prevStore = rmFirst(prevStore);
|
||||
}
|
||||
|
||||
|
||||
const count = getNumber(prevStore);
|
||||
const isVisual = visual();
|
||||
|
||||
|
||||
return {
|
||||
count,
|
||||
isDelete,
|
||||
|
|
@ -194,10 +192,9 @@ function handleDelete(prevStore) {
|
|||
function getNumber(value) {
|
||||
if (!value)
|
||||
return 1;
|
||||
|
||||
|
||||
if (value === 'g')
|
||||
return 1;
|
||||
|
||||
|
||||
return parseInt(value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const vim = require('./vim');
|
||||
|
||||
|
|
@ -64,4 +61,3 @@ test('vim: b', (t) => {
|
|||
t.calledWith(movePrevious, [expected], 'should call movePrevious');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,4 +8,3 @@ module.exports = (array, item) => {
|
|||
|
||||
return index;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,4 +9,3 @@ module.exports = (indexFrom, indexTo, files) => {
|
|||
|
||||
return [files[indexFrom]];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,10 @@ const execAll = currify((funcs, event) => {
|
|||
|
||||
const Info = DOM.CurrentInfo;
|
||||
const {Events} = DOM;
|
||||
|
||||
const EventsFiles = {
|
||||
mousedown: exec.with(execIfNotUL, setCurrentFileByEvent),
|
||||
click: execAll([
|
||||
onClick,
|
||||
unselect,
|
||||
]),
|
||||
click: execAll([onClick, unselect]),
|
||||
dragstart: exec.with(execIfNotUL, onDragStart),
|
||||
dblclick: exec.with(execIfNotUL, onDblClick),
|
||||
touchstart: exec.with(execIfNotUL, onTouch),
|
||||
|
|
@ -79,8 +77,7 @@ function header() {
|
|||
if (parent.dataset.name !== 'js-fm-header')
|
||||
return;
|
||||
|
||||
const name = (el.dataset.name || '')
|
||||
.replace('js-', '');
|
||||
const name = (el.dataset.name || '').replace('js-', '');
|
||||
|
||||
if (!/^(name|size|date)$/.test(name))
|
||||
return;
|
||||
|
|
@ -97,7 +94,7 @@ function header() {
|
|||
function getPath(el, path = []) {
|
||||
if (!el)
|
||||
return path;
|
||||
|
||||
|
||||
return getPath(el.parentElement, path.concat(el));
|
||||
}
|
||||
|
||||
|
|
@ -124,19 +121,19 @@ module.exports.initKeysPanel = () => {
|
|||
};
|
||||
|
||||
const clickFuncs = {
|
||||
'f1' : CloudCmd.Help.show,
|
||||
'f2' : CloudCmd.UserMenu.show,
|
||||
'f3' : CloudCmd.View.show,
|
||||
'f4' : CloudCmd.EditFile.show,
|
||||
'f5' : operation('copy'),
|
||||
'f6' : operation('move'),
|
||||
'f7' : DOM.promptNewDir,
|
||||
'f8' : operation('delete'),
|
||||
'f9' : CloudCmd.Menu.show,
|
||||
'f10' : CloudCmd.Config.show,
|
||||
'~' : CloudCmd.Konsole.show,
|
||||
'shift~' : CloudCmd.Terminal.show,
|
||||
'contact' : CloudCmd.Contact.show,
|
||||
'f1': CloudCmd.Help.show,
|
||||
'f2': CloudCmd.UserMenu.show,
|
||||
'f3': CloudCmd.View.show,
|
||||
'f4': CloudCmd.EditFile.show,
|
||||
'f5': operation('copy'),
|
||||
'f6': operation('move'),
|
||||
'f7': DOM.promptNewDir,
|
||||
'f8': operation('delete'),
|
||||
'f9': CloudCmd.Menu.show,
|
||||
'f10': CloudCmd.Config.show,
|
||||
'~': CloudCmd.Konsole.show,
|
||||
'shift~': CloudCmd.Terminal.show,
|
||||
'contact': CloudCmd.Contact.show,
|
||||
};
|
||||
|
||||
exec(clickFuncs[id]);
|
||||
|
|
@ -146,7 +143,7 @@ module.exports.initKeysPanel = () => {
|
|||
const getPanel = (side) => {
|
||||
if (!itype.string(side))
|
||||
return side;
|
||||
|
||||
|
||||
return DOM.getByDataName(`js-${side}`);
|
||||
};
|
||||
|
||||
|
|
@ -182,10 +179,8 @@ function decodePath(path) {
|
|||
const {prefix} = CloudCmd;
|
||||
const prefixReg = RegExp('^' + prefix + FS);
|
||||
|
||||
return decodeURI(path)
|
||||
.replace(url, '')
|
||||
.replace(prefixReg, '')
|
||||
// browser doesn't replace % -> %25% do it for him
|
||||
return decodeURI(path).replace(url, '')
|
||||
.replace(prefixReg, '') // browser doesn't replace % -> %25% do it for him
|
||||
.replace('%%', '%25%')
|
||||
.replace(NBSP_REG, SPACE) || '/';
|
||||
}
|
||||
|
|
@ -219,8 +214,12 @@ async function onPathElementClick(panel, event) {
|
|||
}
|
||||
|
||||
function copyPath(el) {
|
||||
clipboard.writeText(el.parentElement.title)
|
||||
.then(CloudCmd.log)
|
||||
clipboard
|
||||
.writeText(el
|
||||
.parentElement
|
||||
.title)
|
||||
.then(CloudCmd
|
||||
.log)
|
||||
.catch(CloudCmd.log);
|
||||
}
|
||||
|
||||
|
|
@ -308,12 +307,8 @@ function onDragStart(event) {
|
|||
link.href = prefixURL + '/pack' + Info.path + EXT;
|
||||
}
|
||||
|
||||
event.dataTransfer.setData(
|
||||
'DownloadURL',
|
||||
'application/octet-stream' + ':' +
|
||||
name + ':' +
|
||||
link,
|
||||
);
|
||||
event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name +
|
||||
':' + link);
|
||||
}
|
||||
|
||||
function getLIElement(element) {
|
||||
|
|
@ -397,10 +392,7 @@ function dragndrop() {
|
|||
};
|
||||
|
||||
const onDrop = (event) => {
|
||||
const {
|
||||
files,
|
||||
items,
|
||||
} = event.dataTransfer;
|
||||
const {files, items} = event.dataTransfer;
|
||||
|
||||
const {length: filesCount} = files;
|
||||
|
||||
|
|
@ -410,7 +402,9 @@ function dragndrop() {
|
|||
return uploadFiles(files);
|
||||
|
||||
const isFile = (item) => item.kind === 'file';
|
||||
const dirFiles = Array.from(items).filter(isFile);
|
||||
const dirFiles = Array
|
||||
.from(items)
|
||||
.filter(isFile);
|
||||
|
||||
if (dirFiles.length)
|
||||
return DOM.uploadDirectory(dirFiles);
|
||||
|
|
@ -467,6 +461,7 @@ function pop() {
|
|||
return CloudCmd.route(location.hash);
|
||||
|
||||
const history = false;
|
||||
|
||||
await CloudCmd.changeDir(path, {
|
||||
history,
|
||||
});
|
||||
|
|
@ -495,4 +490,3 @@ function resize() {
|
|||
DOM.changePanel();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const exec = require('execon');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const loadJS = require('load.js').js;
|
||||
|
|
@ -16,45 +15,44 @@ const noJS = (a) => a.replace(/.js$/, '');
|
|||
module.exports = function loadModule(params) {
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
|
||||
const {path} = params;
|
||||
|
||||
|
||||
const name = path && noJS(pascalCase(path));
|
||||
const doBefore = params.dobefore;
|
||||
|
||||
|
||||
if (CloudCmd[name])
|
||||
return;
|
||||
|
||||
|
||||
CloudCmd[name] = async () => {
|
||||
exec(doBefore);
|
||||
|
||||
|
||||
const {DIR_MODULES} = CloudCmd;
|
||||
const pathFull = `${DIR_MODULES}/${path}.js`;
|
||||
|
||||
|
||||
await loadJS(pathFull);
|
||||
const newModule = async (f) => f && f();
|
||||
const module = CloudCmd[name];
|
||||
|
||||
|
||||
Object.assign(newModule, module);
|
||||
|
||||
|
||||
CloudCmd[name] = newModule;
|
||||
CloudCmd.log('init', name);
|
||||
|
||||
|
||||
await module.init();
|
||||
|
||||
|
||||
return newModule;
|
||||
};
|
||||
|
||||
|
||||
CloudCmd[name].show = async (...args) => {
|
||||
CloudCmd.log('show', name, args);
|
||||
const m = CloudCmd[name];
|
||||
|
||||
|
||||
const [e, a] = await tryToCatch(m);
|
||||
|
||||
|
||||
if (e)
|
||||
return console.error(e);
|
||||
|
||||
|
||||
return await a.show(...args);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const {log} = CloudCmd;
|
|||
const upload = currify(_upload);
|
||||
|
||||
const Name = 'Cloud';
|
||||
|
||||
CloudCmd[Name] = module.exports;
|
||||
|
||||
module.exports.init = async () => {
|
||||
|
|
@ -41,10 +42,7 @@ module.exports.saveFile = (callback) => {
|
|||
};
|
||||
|
||||
function _upload(callback, file) {
|
||||
const {
|
||||
url,
|
||||
filename,
|
||||
} = file;
|
||||
const {url, filename} = file;
|
||||
|
||||
const responseType = 'arraybuffer';
|
||||
const success = exec.with(callback, filename);
|
||||
|
|
@ -64,4 +62,3 @@ function loadFiles() {
|
|||
load.js(js),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
CloudCmd.CommandLine = exports;
|
||||
|
||||
const Dialog = require('../dom/dialog');
|
||||
|
|
@ -34,6 +33,4 @@ async function show() {
|
|||
}
|
||||
}
|
||||
|
||||
function hide() {
|
||||
}
|
||||
|
||||
function hide() {}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM, io */
|
||||
|
||||
require('../../../css/config.css');
|
||||
|
||||
const rendy = require('rendy');
|
||||
|
|
@ -22,6 +21,7 @@ const {getTitle} = require('../../../common/cloudfunc');
|
|||
const {Dialog, setTitle} = DOM;
|
||||
|
||||
const Name = 'Config';
|
||||
|
||||
CloudCmd[Name] = module.exports;
|
||||
|
||||
const loadSocket = promisify(DOM.loadSocket);
|
||||
|
|
@ -64,10 +64,7 @@ module.exports.init = async () => {
|
|||
initSocket();
|
||||
};
|
||||
|
||||
const {
|
||||
config,
|
||||
Key,
|
||||
} = CloudCmd;
|
||||
const {config, Key} = CloudCmd;
|
||||
|
||||
let Element;
|
||||
|
||||
|
|
@ -77,6 +74,7 @@ function getHost() {
|
|||
origin,
|
||||
protocol,
|
||||
} = location;
|
||||
|
||||
const href = origin || `${protocol}//${host}`;
|
||||
|
||||
return href;
|
||||
|
|
@ -84,10 +82,7 @@ function getHost() {
|
|||
|
||||
function initSocket() {
|
||||
const href = getHost();
|
||||
const {
|
||||
prefixSocket,
|
||||
prefix,
|
||||
} = CloudCmd;
|
||||
const {prefixSocket, prefix} = CloudCmd;
|
||||
|
||||
const ONE_MINUTE = 60 * 1000;
|
||||
|
||||
|
|
@ -156,7 +151,7 @@ async function fillTemplate() {
|
|||
const innerHTML = rendy(Template, obj);
|
||||
|
||||
Element = createElement('form', {
|
||||
className : 'config',
|
||||
className: 'config',
|
||||
innerHTML,
|
||||
});
|
||||
|
||||
|
|
@ -173,11 +168,13 @@ async function fillTemplate() {
|
|||
const getTarget = ({target}) => target;
|
||||
const handleChange = squad(onChange, getTarget);
|
||||
|
||||
Array.from(inputs)
|
||||
Array
|
||||
.from(inputs)
|
||||
.map(addKey(onKey))
|
||||
.map(addChange(handleChange));
|
||||
|
||||
const autoSize = true;
|
||||
|
||||
CloudCmd.View.show(Element, {
|
||||
autoSize,
|
||||
afterShow,
|
||||
|
|
@ -246,4 +243,3 @@ async function onKey({keyCode, target}) {
|
|||
return await onChange(target);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ module.exports.getElementByName = getElementByName;
|
|||
function getElementByName(selector, element) {
|
||||
const str = `[data-name="js-${selector}"]`;
|
||||
|
||||
return element
|
||||
.querySelector(str);
|
||||
return element.querySelector(str);
|
||||
}
|
||||
|
||||
module.exports.getName = (element) => {
|
||||
|
|
@ -40,7 +39,7 @@ module.exports.convert = (config) => {
|
|||
function setState(state) {
|
||||
if (state)
|
||||
return ' checked';
|
||||
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
@ -74,4 +73,3 @@ module.exports.setValue = (name, value, element) => {
|
|||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,4 +39,3 @@ function onKey({keyCode}) {
|
|||
if (keyCode === Key.ESC)
|
||||
hide();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
CloudCmd.EditFileVim = exports;
|
||||
|
||||
const Events = require('../dom/events');
|
||||
|
|
@ -23,8 +22,7 @@ module.exports.init = async () => {
|
|||
module.exports.show = async () => {
|
||||
Events.addKey(listener);
|
||||
|
||||
const editFile = await CloudCmd.EditFile
|
||||
.show(ConfigView);
|
||||
const editFile = await CloudCmd.EditFile.show(ConfigView);
|
||||
|
||||
editFile
|
||||
.getEditor()
|
||||
|
|
@ -38,14 +36,10 @@ function hide() {
|
|||
}
|
||||
|
||||
function listener(event) {
|
||||
const {
|
||||
keyCode,
|
||||
shiftKey,
|
||||
} = event;
|
||||
const {keyCode, shiftKey} = event;
|
||||
|
||||
if (shiftKey && keyCode === Key.ESC) {
|
||||
event.preventDefault();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM*/
|
||||
|
||||
CloudCmd.EditFile = exports;
|
||||
|
||||
const Format = require('format-io');
|
||||
|
|
@ -11,10 +10,7 @@ const supermenu = require('supermenu');
|
|||
|
||||
const Info = DOM.CurrentInfo;
|
||||
|
||||
const {
|
||||
Dialog,
|
||||
Images,
|
||||
} = DOM;
|
||||
const {Dialog, Images} = DOM;
|
||||
|
||||
const {config} = CloudCmd;
|
||||
|
||||
|
|
@ -65,7 +61,8 @@ module.exports.show = async (options) => {
|
|||
|
||||
Images.show.load();
|
||||
|
||||
CloudCmd.Edit
|
||||
CloudCmd
|
||||
.Edit
|
||||
.getEditor()
|
||||
.setOption('keyMap', 'default');
|
||||
|
||||
|
|
@ -81,7 +78,8 @@ module.exports.show = async (options) => {
|
|||
|
||||
setMsgChanged(name);
|
||||
|
||||
CloudCmd.Edit
|
||||
CloudCmd
|
||||
.Edit
|
||||
.getEditor()
|
||||
.setValueFirst(path, data)
|
||||
.setModeForPath(name)
|
||||
|
|
@ -133,7 +131,8 @@ function setMenu(event) {
|
|||
},
|
||||
|
||||
afterClick: () => {
|
||||
CloudCmd.Edit
|
||||
CloudCmd
|
||||
.Edit
|
||||
.getEditor()
|
||||
.focus();
|
||||
},
|
||||
|
|
@ -151,28 +150,28 @@ function getMenuData() {
|
|||
const editor = CloudCmd.Edit.getEditor();
|
||||
|
||||
return {
|
||||
'Save Ctrl+S' : () => {
|
||||
'Save Ctrl+S': () => {
|
||||
editor.save();
|
||||
},
|
||||
'Go To Line Ctrl+G' : () => {
|
||||
'Go To Line Ctrl+G': () => {
|
||||
editor.goToLine();
|
||||
},
|
||||
'Cut Ctrl+X' : () => {
|
||||
'Cut Ctrl+X': () => {
|
||||
editor.cutToClipboard();
|
||||
},
|
||||
'Copy Ctrl+C' : () => {
|
||||
'Copy Ctrl+C': () => {
|
||||
editor.copyToClipboard();
|
||||
},
|
||||
'Paste Ctrl+V' : () => {
|
||||
'Paste Ctrl+V': () => {
|
||||
editor.pasteFromClipboard();
|
||||
},
|
||||
'Delete Del' : () => {
|
||||
'Delete Del': () => {
|
||||
editor.remove('right');
|
||||
},
|
||||
'Select All Ctrl+A' : () => {
|
||||
'Select All Ctrl+A': () => {
|
||||
editor.selectAll();
|
||||
},
|
||||
'Close Esc' : hide,
|
||||
'Close Esc': hide,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -196,4 +195,3 @@ async function isChanged() {
|
|||
|
||||
editor.save();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
CloudCmd.EditNamesVim = exports;
|
||||
|
||||
const Events = require('../dom/events');
|
||||
|
|
@ -22,7 +21,8 @@ module.exports.init = async () => {
|
|||
module.exports.show = () => {
|
||||
Events.addKey(listener);
|
||||
|
||||
CloudCmd.EditNames
|
||||
CloudCmd
|
||||
.EditNames
|
||||
.show(ConfigView)
|
||||
.getEditor()
|
||||
.setKeyMap('vim');
|
||||
|
|
@ -35,14 +35,10 @@ function hide() {
|
|||
}
|
||||
|
||||
function listener(event) {
|
||||
const {
|
||||
keyCode,
|
||||
shiftKey,
|
||||
} = event;
|
||||
const {keyCode, shiftKey} = event;
|
||||
|
||||
if (shiftKey && keyCode === Key.ESC) {
|
||||
event.preventDefault();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM */
|
||||
|
||||
CloudCmd.EditNames = exports;
|
||||
|
||||
const currify = require('currify');
|
||||
|
|
@ -45,7 +44,8 @@ module.exports.show = (options) => {
|
|||
|
||||
DOM.Events.addKey(keyListener);
|
||||
|
||||
CloudCmd.Edit
|
||||
CloudCmd
|
||||
.Edit
|
||||
.getEditor()
|
||||
.setValueFirst('edit-names', names)
|
||||
.setMode()
|
||||
|
|
@ -65,7 +65,6 @@ async function keyListener(event) {
|
|||
|
||||
if (ctrlMeta && event.keyCode === Key.S)
|
||||
hide();
|
||||
|
||||
else if (ctrlMeta && event.keyCode === Key.P) {
|
||||
const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]');
|
||||
pattern && applyPattern(pattern);
|
||||
|
|
@ -107,7 +106,8 @@ function applyNames() {
|
|||
|
||||
const root = CloudCmd.config('root');
|
||||
|
||||
Promise.resolve(root)
|
||||
Promise
|
||||
.resolve(root)
|
||||
.then(rename(dir, from, to))
|
||||
.then(refresh(to, nameIndex))
|
||||
.catch(alert);
|
||||
|
|
@ -115,7 +115,9 @@ function applyNames() {
|
|||
|
||||
function _refresh(to, nameIndex, res) {
|
||||
if (res.status === 404)
|
||||
return res.text().then(reject);
|
||||
return res
|
||||
.text()
|
||||
.then(reject);
|
||||
|
||||
const currentName = to[nameIndex];
|
||||
|
||||
|
|
@ -127,7 +129,7 @@ function _refresh(to, nameIndex, res) {
|
|||
function getDir(root, dir) {
|
||||
if (root === '/')
|
||||
return dir;
|
||||
|
||||
|
||||
return root + dir;
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +160,7 @@ function setMenu(event) {
|
|||
return;
|
||||
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
|
||||
const options = {
|
||||
beforeShow: (params) => {
|
||||
params.x -= 18;
|
||||
|
|
@ -170,29 +173,29 @@ function setMenu(event) {
|
|||
};
|
||||
|
||||
const menuData = {
|
||||
'Save Ctrl+S' : () => {
|
||||
'Save Ctrl+S': () => {
|
||||
applyNames();
|
||||
hide();
|
||||
},
|
||||
'Go To Line Ctrl+G' : () => {
|
||||
'Go To Line Ctrl+G': () => {
|
||||
editor.goToLine();
|
||||
},
|
||||
'Cut Ctrl+X' : () => {
|
||||
'Cut Ctrl+X': () => {
|
||||
editor.cutToClipboard();
|
||||
},
|
||||
'Copy Ctrl+C' : () => {
|
||||
'Copy Ctrl+C': () => {
|
||||
editor.copyToClipboard();
|
||||
},
|
||||
'Paste Ctrl+V' : () => {
|
||||
'Paste Ctrl+V': () => {
|
||||
editor.pasteFromClipboard();
|
||||
},
|
||||
'Delete Del' : () => {
|
||||
'Delete Del': () => {
|
||||
editor.remove('right');
|
||||
},
|
||||
'Select All Ctrl+A' : () => {
|
||||
'Select All Ctrl+A': () => {
|
||||
editor.selectAll();
|
||||
},
|
||||
'Close Esc' : hide,
|
||||
'Close Esc': hide,
|
||||
};
|
||||
|
||||
const element = CloudCmd.Edit.getElement();
|
||||
|
|
@ -215,4 +218,3 @@ async function isChanged() {
|
|||
const [, names] = await Dialog.confirm(msg);
|
||||
names && applyNames();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const ConfigView = {
|
|||
|
||||
module.exports.init = async () => {
|
||||
const element = create();
|
||||
|
||||
|
||||
await CloudCmd.View();
|
||||
await loadFiles(element);
|
||||
};
|
||||
|
|
@ -47,9 +47,9 @@ function create() {
|
|||
`,
|
||||
notAppend: true,
|
||||
});
|
||||
|
||||
|
||||
Element = element;
|
||||
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
|
|
@ -63,30 +63,29 @@ function initConfig(options = {}) {
|
|||
...options,
|
||||
...ConfigView,
|
||||
};
|
||||
|
||||
|
||||
if (!options.afterShow)
|
||||
return config;
|
||||
|
||||
|
||||
checkFn('options.afterShow', options.afterShow);
|
||||
|
||||
|
||||
config.afterShow = () => {
|
||||
ConfigView.afterShow();
|
||||
options.afterShow();
|
||||
};
|
||||
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
module.exports.show = (options) => {
|
||||
if (Loading)
|
||||
return;
|
||||
|
||||
|
||||
CloudCmd.View.show(Element, initConfig(options));
|
||||
|
||||
getEditor()
|
||||
.setOptions({
|
||||
fontSize: 16,
|
||||
});
|
||||
|
||||
getEditor().setOptions({
|
||||
fontSize: 16,
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.getEditor = getEditor;
|
||||
|
|
@ -106,11 +105,11 @@ const loadFiles = async (element) => {
|
|||
const socketPath = CloudCmd.prefix;
|
||||
const prefixSocket = `${CloudCmd.prefixSocket}/${EditorName}`;
|
||||
const url = `${prefix}/${EditorName}.js`;
|
||||
|
||||
|
||||
time(`${Name} load`);
|
||||
|
||||
|
||||
await loadJS(url);
|
||||
|
||||
|
||||
const word = promisify(window[EditorName]);
|
||||
const [ed] = await tryToCatch(word, element, {
|
||||
maxSize,
|
||||
|
|
@ -118,9 +117,8 @@ const loadFiles = async (element) => {
|
|||
prefixSocket,
|
||||
socketPath,
|
||||
});
|
||||
|
||||
|
||||
timeEnd(`${Name} load`);
|
||||
editor = ed;
|
||||
Loading = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
CloudCmd.Help = exports;
|
||||
|
||||
const Images = require('../dom/images');
|
||||
|
|
@ -17,15 +16,12 @@ function show() {
|
|||
const positionLoad = 'top';
|
||||
const relative = true;
|
||||
|
||||
CloudCmd
|
||||
.Markdown
|
||||
.show('/HELP.md', {
|
||||
positionLoad,
|
||||
relative,
|
||||
});
|
||||
CloudCmd.Markdown.show('/HELP.md', {
|
||||
positionLoad,
|
||||
relative,
|
||||
});
|
||||
}
|
||||
|
||||
function hide() {
|
||||
CloudCmd.View.hide();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
/* global Util */
|
||||
/* global DOM */
|
||||
/* global Console */
|
||||
|
||||
CloudCmd.Konsole = exports;
|
||||
|
||||
const exec = require('execon');
|
||||
|
|
@ -14,10 +13,7 @@ const loadJS = require('load.js').js;
|
|||
const createElement = require('@cloudcmd/create-element');
|
||||
|
||||
const Images = require('../dom/images');
|
||||
const {
|
||||
Dialog,
|
||||
CurrentInfo:Info,
|
||||
} = DOM;
|
||||
const {Dialog, CurrentInfo: Info} = DOM;
|
||||
|
||||
const rmLastSlash = (a) => a.replace(/\/$/, '') || '/';
|
||||
|
||||
|
|
@ -147,4 +143,3 @@ const load = async () => {
|
|||
cancel: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
CloudCmd.Markdown = exports;
|
||||
|
||||
const createElement = require('@cloudcmd/create-element');
|
||||
|
|
@ -22,10 +21,7 @@ module.exports.hide = () => {
|
|||
};
|
||||
|
||||
async function show(name, options = {}) {
|
||||
const {
|
||||
positionLoad,
|
||||
relative,
|
||||
} = options;
|
||||
const {positionLoad, relative} = options;
|
||||
|
||||
Images.show.load(positionLoad);
|
||||
|
||||
|
|
@ -41,6 +37,7 @@ async function show(name, options = {}) {
|
|||
});
|
||||
|
||||
const className = 'help';
|
||||
|
||||
const div = createElement('div', {
|
||||
className,
|
||||
innerHTML,
|
||||
|
|
@ -48,4 +45,3 @@ async function show(name, options = {}) {
|
|||
|
||||
CloudCmd.View.show(div);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ const {FS} = require('../../common/cloudfunc');
|
|||
const {getIdBySrc} = require('../dom/load');
|
||||
const RESTful = require('../dom/rest');
|
||||
|
||||
const {
|
||||
config,
|
||||
Key,
|
||||
} = CloudCmd;
|
||||
const {config, Key} = CloudCmd;
|
||||
|
||||
const {
|
||||
Buffer,
|
||||
|
|
@ -36,15 +33,16 @@ module.exports.ENABLED = false;
|
|||
CloudCmd.Menu = exports;
|
||||
|
||||
module.exports.init = () => {
|
||||
const {
|
||||
isAuth,
|
||||
menuDataFile,
|
||||
} = getFileMenuData();
|
||||
const {isAuth, menuDataFile} = getFileMenuData();
|
||||
|
||||
const fm = DOM.getFM();
|
||||
const menuData = getMenuData(isAuth);
|
||||
const options = getOptions({type: 'context'});
|
||||
const optionsFile = getOptions({type: 'file'});
|
||||
const options = getOptions({
|
||||
type: 'context',
|
||||
});
|
||||
const optionsFile = getOptions({
|
||||
type: 'file',
|
||||
});
|
||||
|
||||
MenuContext = supermenu(fm, options, menuData);
|
||||
MenuContextFile = supermenu(fm, optionsFile, menuDataFile);
|
||||
|
|
@ -77,7 +75,7 @@ function getPosition(position) {
|
|||
x: position.x,
|
||||
y: position.y,
|
||||
};
|
||||
|
||||
|
||||
return getCurrentPosition();
|
||||
}
|
||||
|
||||
|
|
@ -105,9 +103,9 @@ function getOptions({type}) {
|
|||
}
|
||||
|
||||
const options = {
|
||||
icon : true,
|
||||
beforeClose : Key.setBind,
|
||||
beforeShow : exec.with(beforeShow, func),
|
||||
icon: true,
|
||||
beforeClose: Key.setBind,
|
||||
beforeShow: exec.with(beforeShow, func),
|
||||
beforeClick,
|
||||
name,
|
||||
};
|
||||
|
|
@ -252,7 +250,9 @@ function uploadFromCloud() {
|
|||
if (e)
|
||||
return;
|
||||
|
||||
await CloudCmd.refresh({currentName});
|
||||
await CloudCmd.refresh({
|
||||
currentName,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +292,7 @@ function download(type) {
|
|||
src = prefixURL + FS + encodedPath + '?download';
|
||||
|
||||
const element = createElement('iframe', {
|
||||
id : id + '-' + date,
|
||||
id: id + '-' + date,
|
||||
async: false,
|
||||
className: 'hidden',
|
||||
src,
|
||||
|
|
@ -321,10 +321,7 @@ function getCurrentPosition() {
|
|||
}
|
||||
|
||||
function listener(event) {
|
||||
const {
|
||||
F9,
|
||||
ESC,
|
||||
} = Key;
|
||||
const {F9, ESC} = Key;
|
||||
|
||||
const key = event.keyCode;
|
||||
const isBind = Key.isBind();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
module.exports = (operation, from, to) => {
|
||||
if (!to)
|
||||
return `${operation} ${from}`;
|
||||
|
||||
|
||||
return `${operation} ${from} -> ${to}`;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,4 +16,3 @@ module.exports = (currentName, names, removedNames) => {
|
|||
|
||||
return nextNames[length - 1];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const getNextCurrentName = require('./get-next-current-name');
|
|||
const removeQuery = (a) => a.replace(/\?.*/, '');
|
||||
|
||||
const Name = 'Operation';
|
||||
|
||||
CloudCmd[Name] = exports;
|
||||
|
||||
const {config} = CloudCmd;
|
||||
|
|
@ -61,10 +62,7 @@ module.exports.init = promisify((callback) => {
|
|||
if (config('dropbox'))
|
||||
return callback();
|
||||
|
||||
const {
|
||||
prefix,
|
||||
prefixSocket,
|
||||
} = CloudCmd;
|
||||
const {prefix, prefixSocket} = CloudCmd;
|
||||
|
||||
await loadAll();
|
||||
await initOperations(prefix, prefixSocket, callback);
|
||||
|
|
@ -94,7 +92,10 @@ const onConnect = currify((fn, operator) => {
|
|||
async function initOperations(prefix, socketPrefix, fn) {
|
||||
socketPrefix = `${socketPrefix}/fileop`;
|
||||
|
||||
const operator = await fileop({prefix, socketPrefix});
|
||||
const operator = await fileop({
|
||||
prefix,
|
||||
socketPrefix,
|
||||
});
|
||||
operator.on('connect', authCheck(operator, onConnect(fn)));
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +110,8 @@ function setOperations(operator) {
|
|||
to,
|
||||
});
|
||||
|
||||
operator.tar(from, to, names)
|
||||
operator
|
||||
.tar(from, to, names)
|
||||
.then(listen);
|
||||
};
|
||||
|
||||
|
|
@ -123,7 +125,8 @@ function setOperations(operator) {
|
|||
to,
|
||||
});
|
||||
|
||||
operator.zip(from, to, names)
|
||||
operator
|
||||
.zip(from, to, names)
|
||||
.then(listen);
|
||||
};
|
||||
|
||||
|
|
@ -137,7 +140,8 @@ function setOperations(operator) {
|
|||
from,
|
||||
});
|
||||
|
||||
operator.remove(from, files)
|
||||
operator
|
||||
.remove(from, files)
|
||||
.then(listen);
|
||||
};
|
||||
|
||||
|
|
@ -151,7 +155,8 @@ function setOperations(operator) {
|
|||
names,
|
||||
});
|
||||
|
||||
operator.copy(from, to, names)
|
||||
operator
|
||||
.copy(from, to, names)
|
||||
.then(listen);
|
||||
};
|
||||
|
||||
|
|
@ -164,7 +169,8 @@ function setOperations(operator) {
|
|||
to,
|
||||
});
|
||||
|
||||
operator.move(from, to, names)
|
||||
operator
|
||||
.move(from, to, names)
|
||||
.then(listen);
|
||||
};
|
||||
|
||||
|
|
@ -178,7 +184,8 @@ function setOperations(operator) {
|
|||
to,
|
||||
});
|
||||
|
||||
operator.extract(from, to)
|
||||
operator
|
||||
.extract(from, to)
|
||||
.then(listen);
|
||||
};
|
||||
}
|
||||
|
|
@ -186,7 +193,7 @@ function setOperations(operator) {
|
|||
function getPacker(type) {
|
||||
if (type === 'zip')
|
||||
return packZipFn;
|
||||
|
||||
|
||||
return packTarFn;
|
||||
}
|
||||
|
||||
|
|
@ -274,6 +281,7 @@ async function promptDelete() {
|
|||
const type = getType(isDir) + ' ';
|
||||
|
||||
const name = DOM.getCurrentName(current);
|
||||
|
||||
msg = msgAsk + msgSel + type + name + '?';
|
||||
}
|
||||
|
||||
|
|
@ -333,20 +341,19 @@ async function _processFiles(options, data) {
|
|||
|
||||
let names = [];
|
||||
|
||||
/* eslint no-multi-spaces: 0 */
|
||||
if (data) {
|
||||
from = data.from;
|
||||
to = data.to;
|
||||
names = data.names;
|
||||
panel = Info.panel;
|
||||
from = data.from;
|
||||
to = data.to;
|
||||
names = data.names;
|
||||
panel = Info.panel;
|
||||
} else {
|
||||
from = Info.dirPath;
|
||||
to = DOM.getNotCurrentDirPath();
|
||||
selFiles = DOM.getSelectedFiles();
|
||||
names = DOM.getFilenames(selFiles);
|
||||
data = {};
|
||||
shouldAsk = true;
|
||||
panel = Info.panelPassive;
|
||||
from = Info.dirPath;
|
||||
to = DOM.getNotCurrentDirPath();
|
||||
selFiles = DOM.getSelectedFiles();
|
||||
names = DOM.getFilenames(selFiles);
|
||||
data = {};
|
||||
shouldAsk = true;
|
||||
panel = Info.panelPassive;
|
||||
}
|
||||
|
||||
if (!names.length)
|
||||
|
|
@ -383,10 +390,14 @@ async function _processFiles(options, data) {
|
|||
if (ok && !shouldAsk || !sameName)
|
||||
return go();
|
||||
|
||||
const str = `"${ name }" already exist. Overwrite?`;
|
||||
const str = `"${name}" already exist. Overwrite?`;
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(str, {cancel}).then(go);
|
||||
Dialog
|
||||
.confirm(str, {
|
||||
cancel,
|
||||
})
|
||||
.then(go);
|
||||
|
||||
function go() {
|
||||
showLoad();
|
||||
|
|
@ -400,10 +411,7 @@ async function _processFiles(options, data) {
|
|||
operation(files, async () => {
|
||||
await DOM.Storage.remove(from);
|
||||
|
||||
const {
|
||||
panel,
|
||||
panelPassive,
|
||||
} = Info;
|
||||
const {panel, panelPassive} = Info;
|
||||
|
||||
if (!Info.isOnePanel)
|
||||
CloudCmd.refresh({
|
||||
|
|
@ -429,10 +437,7 @@ function twopack(operation, type) {
|
|||
let fileFrom;
|
||||
let currentName = Info.name;
|
||||
|
||||
const {
|
||||
path,
|
||||
dirPath,
|
||||
} = Info;
|
||||
const {path, dirPath} = Info;
|
||||
|
||||
const activeFiles = DOM.getActiveFiles();
|
||||
const names = DOM.getFilenames(activeFiles);
|
||||
|
|
@ -446,7 +451,7 @@ function twopack(operation, type) {
|
|||
case 'extract':
|
||||
op = extractFn;
|
||||
|
||||
fileFrom = {
|
||||
fileFrom = {
|
||||
from: path,
|
||||
to: dirPath,
|
||||
};
|
||||
|
|
@ -459,7 +464,7 @@ function twopack(operation, type) {
|
|||
op = getPacker(type);
|
||||
|
||||
if (names.length > 1)
|
||||
currentName = Info.dir;
|
||||
currentName = Info.dir;
|
||||
|
||||
currentName += DOM.getPackerExt(type);
|
||||
|
||||
|
|
@ -487,9 +492,9 @@ async function prompt(msg, to, names) {
|
|||
msg += ' ';
|
||||
|
||||
if (names.length > 1)
|
||||
msg += `${n} file(s)`;
|
||||
msg += `${n} file(s)`;
|
||||
else
|
||||
msg += `"${name}"`;
|
||||
msg += `"${name}"`;
|
||||
|
||||
msg += ' to';
|
||||
|
||||
|
|
@ -507,4 +512,3 @@ async function loadAll() {
|
|||
|
||||
Loaded = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,4 +17,3 @@ function getExtension(name) {
|
|||
|
||||
return getExt(name);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,4 +26,3 @@ test('cloudcmd: client: modules: operation: removeExtension: .bz2', (t) => {
|
|||
t.equal(removeExtension(fullName), name, 'should remove .bz2');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
/* global DOM */
|
||||
|
||||
const forEachKey = require('for-each-key');
|
||||
|
||||
const wraptile = require('wraptile');
|
||||
const format = require('./format');
|
||||
|
||||
const {
|
||||
Dialog,
|
||||
Images,
|
||||
} = DOM;
|
||||
const {Dialog, Images} = DOM;
|
||||
|
||||
module.exports = (options) => (emitter) => {
|
||||
const {
|
||||
|
|
@ -28,6 +24,7 @@ module.exports = (options) => (emitter) => {
|
|||
emitter.abort();
|
||||
|
||||
const msg = `${operation} aborted`;
|
||||
|
||||
lastError = true;
|
||||
|
||||
Dialog.alert(msg, {
|
||||
|
|
@ -85,4 +82,3 @@ module.exports = (options) => (emitter) => {
|
|||
|
||||
forEachKey(on, listeners);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
/* global DOM */
|
||||
|
||||
require('domtokenlist-shim');
|
||||
|
||||
const scrollIntoViewIfNeeded = require('scroll-into-view-if-needed').default;
|
||||
|
||||
DOM.scrollIntoViewIfNeeded = (el) => scrollIntoViewIfNeeded(el, {
|
||||
block: 'nearest',
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const mockRequire = require('mock-require');
|
||||
|
||||
const {stopAll} = mockRequire;
|
||||
|
|
@ -25,10 +23,9 @@ test('cloudcmd: client: polyfill: scrollIntoViewIfNeaded', (t) => {
|
|||
mockRequire.stop('scroll-into-view-if-neaded');
|
||||
global.DOM = DOM;
|
||||
|
||||
const args = [
|
||||
el, {
|
||||
block: 'nearest',
|
||||
}];
|
||||
const args = [el, {
|
||||
block: 'nearest',
|
||||
}];
|
||||
|
||||
stopAll();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, gritty */
|
||||
|
||||
const {promisify} = require('es6-promisify');
|
||||
const tryToCatch = require('try-to-catch');
|
||||
const fullstore = require('fullstore');
|
||||
|
|
@ -14,10 +13,7 @@ const DOM = require('../dom');
|
|||
const Images = require('../dom/images');
|
||||
|
||||
const {Dialog} = DOM;
|
||||
const {
|
||||
Key,
|
||||
config,
|
||||
} = CloudCmd;
|
||||
const {Key, config} = CloudCmd;
|
||||
|
||||
CloudCmd.TerminalRun = exports;
|
||||
|
||||
|
|
@ -152,4 +148,3 @@ function authCheck(spawn) {
|
|||
Dialog.alert('Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
/* global CloudCmd */
|
||||
/* global gritty */
|
||||
|
||||
const tryToCatch = require('try-to-catch');
|
||||
|
||||
require('../../css/terminal.css');
|
||||
|
|
@ -15,10 +14,7 @@ const Images = require('../dom/images');
|
|||
const loadParallel = load.parallel;
|
||||
|
||||
const {Dialog} = DOM;
|
||||
const {
|
||||
Key,
|
||||
config,
|
||||
} = CloudCmd;
|
||||
const {Key, config} = CloudCmd;
|
||||
|
||||
CloudCmd.Terminal = exports;
|
||||
|
||||
|
|
@ -123,4 +119,3 @@ function show() {
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,4 +66,3 @@ function afterShow() {
|
|||
uploadFiles(files);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,4 +8,3 @@ module.exports = (menuFn) => {
|
|||
|
||||
return module.exports;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,4 +18,3 @@ test('user-menu: getUserMenu', (t) => {
|
|||
t.equal(key, 'F2 - Rename file');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM */
|
||||
|
||||
require('../../../css/user-menu.css');
|
||||
|
||||
const currify = require('currify');
|
||||
|
|
@ -25,6 +24,7 @@ const loadCSS = load.css;
|
|||
const sourceStore = fullstore();
|
||||
|
||||
const Name = 'UserMenu';
|
||||
|
||||
CloudCmd[Name] = module.exports;
|
||||
|
||||
const {Key} = CloudCmd;
|
||||
|
|
@ -52,7 +52,10 @@ async function show() {
|
|||
Images.hide();
|
||||
|
||||
if (error)
|
||||
return Dialog.alert(getCodeFrame({error, source}));
|
||||
return Dialog.alert(getCodeFrame({
|
||||
error,
|
||||
source,
|
||||
}));
|
||||
|
||||
sourceStore(source);
|
||||
|
||||
|
|
@ -118,10 +121,7 @@ const onButtonClick = wraptile(async (items, {value}) => {
|
|||
});
|
||||
|
||||
const onKeyDown = currify(async ({keys, userMenu}, e) => {
|
||||
const {
|
||||
keyCode,
|
||||
target,
|
||||
} = e;
|
||||
const {keyCode, target} = e;
|
||||
|
||||
const keyName = e.key.toUpperCase();
|
||||
|
||||
|
|
@ -156,6 +156,7 @@ const runUserMenu = async (fn) => {
|
|||
return;
|
||||
|
||||
const source = sourceStore();
|
||||
|
||||
return Dialog.alert(getCodeFrame({
|
||||
error,
|
||||
source,
|
||||
|
|
@ -169,6 +170,7 @@ function getCodeFrame({error, source}) {
|
|||
return error.message;
|
||||
|
||||
const [line, column] = parseError(error);
|
||||
|
||||
const start = {
|
||||
line,
|
||||
column,
|
||||
|
|
@ -185,4 +187,3 @@ function getCodeFrame({error, source}) {
|
|||
|
||||
return `<pre>${frame}</pre>`;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,43 +16,42 @@ module.exports = (el, {key, keyCode}) => {
|
|||
if (isDigit(key)) {
|
||||
store(Number(key));
|
||||
}
|
||||
|
||||
|
||||
if (keyCode === DOWN || keyCode === J) {
|
||||
const count = store();
|
||||
store(1);
|
||||
|
||||
|
||||
return down(el, count);
|
||||
}
|
||||
|
||||
|
||||
if (keyCode === UP || keyCode === K) {
|
||||
const count = store();
|
||||
store(1);
|
||||
|
||||
|
||||
return up(el, count);
|
||||
}
|
||||
};
|
||||
|
||||
function down(el, count) {
|
||||
const {length} = el;
|
||||
|
||||
|
||||
if (el.selectedIndex === length - 1)
|
||||
el.selectedIndex = 0;
|
||||
else
|
||||
el.selectedIndex += count;
|
||||
|
||||
|
||||
if (el.selectedIndex < 0)
|
||||
el.selectedIndex = length - 1;
|
||||
}
|
||||
|
||||
function up(el, count) {
|
||||
const {length} = el;
|
||||
|
||||
|
||||
if (!el.selectedIndex)
|
||||
el.selectedIndex = length - 1;
|
||||
else
|
||||
el.selectedIndex -= count;
|
||||
|
||||
|
||||
if (el.selectedIndex < 0)
|
||||
el.selectedIndex = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ test('cloudcmd: user-menu: navigate: DOWN', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 0,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: DOWN,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 1);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -29,11 +29,11 @@ test('cloudcmd: user-menu: navigate: J', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 0,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: J,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 1);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -43,11 +43,11 @@ test('cloudcmd: user-menu: navigate: DOWN: bottom', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 2,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: DOWN,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 0);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -57,11 +57,11 @@ test('cloudcmd: user-menu: navigate: K', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 2,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: K,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 1);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -71,11 +71,11 @@ test('cloudcmd: user-menu: navigate: UP', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 2,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: UP,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 1);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -85,11 +85,11 @@ test('cloudcmd: user-menu: navigate: UP: top', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 0,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: UP,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 2);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -99,11 +99,11 @@ test('cloudcmd: user-menu: navigate', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 0,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: 0,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 0, 'should not change');
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -113,16 +113,16 @@ test('cloudcmd: user-menu: navigate: DOWN: count', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: 0,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: 53,
|
||||
key: '5',
|
||||
});
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: DOWN,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 5);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -132,16 +132,16 @@ test('cloudcmd: user-menu: navigate: J: count: to big', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: -Infinity,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: 53,
|
||||
key: '5',
|
||||
});
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: J,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 2);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -151,16 +151,16 @@ test('cloudcmd: user-menu: navigate: K: count: to small', (t) => {
|
|||
length: 3,
|
||||
selectedIndex: -Infinity,
|
||||
};
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: 53,
|
||||
key: '5',
|
||||
});
|
||||
|
||||
|
||||
navigate(el, {
|
||||
keyCode: K,
|
||||
});
|
||||
|
||||
|
||||
t.equal(el.selectedIndex, 0);
|
||||
t.end();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,17 +3,11 @@
|
|||
const isNumber = (a) => typeof a === 'number';
|
||||
|
||||
module.exports = (error) => {
|
||||
const {
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
} = error;
|
||||
const {lineNumber, columnNumber} = error;
|
||||
|
||||
// thank you firefox
|
||||
if (isNumber(lineNumber) && isNumber(columnNumber))
|
||||
return [
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
];
|
||||
return [lineNumber, columnNumber];
|
||||
|
||||
const before = error.stack.indexOf('>');
|
||||
const str = error.stack.slice(before + 1);
|
||||
|
|
@ -27,4 +21,3 @@ module.exports = (error) => {
|
|||
Number(column),
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ test('user-menu: parse-error: stack', (t) => {
|
|||
at AsyncFunction.show (index.js:67)
|
||||
`;
|
||||
|
||||
const result = parseError({stack});
|
||||
const result = parseError({
|
||||
stack,
|
||||
});
|
||||
const expected = [1, 2];
|
||||
|
||||
t.deepEqual(result, expected);
|
||||
|
|
|
|||
|
|
@ -32,4 +32,3 @@ module.exports = (userMenu) => {
|
|||
settings,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const parse = require('./parse-user-menu');
|
||||
|
||||
test('cloudcmd: user menu: parse', (t) => {
|
||||
|
|
@ -15,7 +13,10 @@ test('cloudcmd: user menu: parse', (t) => {
|
|||
'_f': fn,
|
||||
});
|
||||
|
||||
const names = ['F2 - Rename file'];
|
||||
const names = [
|
||||
'F2 - Rename file',
|
||||
];
|
||||
|
||||
const keys = {
|
||||
F2: fn,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,4 +5,3 @@ module.exports.runSelected = async (selectedItems, items, runUserMenu) => {
|
|||
await runUserMenu(items[selected]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
test,
|
||||
stub,
|
||||
} = require('supertape');
|
||||
const {test, stub} = require('supertape');
|
||||
|
||||
const {runSelected} = require('./run');
|
||||
|
||||
test('cloudcmd: client: user menu: run', async (t) => {
|
||||
const runUserMenu = stub();
|
||||
const fn = stub();
|
||||
const selected = [
|
||||
'hello',
|
||||
];
|
||||
const selected = ['hello'];
|
||||
|
||||
const items = {
|
||||
hello: fn,
|
||||
|
|
@ -22,4 +18,3 @@ test('cloudcmd: client: user menu: run', async (t) => {
|
|||
t.calledWith(runUserMenu, [fn]);
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM */
|
||||
|
||||
'use strict';
|
||||
|
||||
require('../../../css/view.css');
|
||||
|
||||
const rendy = require('rendy');
|
||||
|
|
@ -15,6 +15,7 @@ const createElement = require('@cloudcmd/create-element');
|
|||
|
||||
const {time} = require('../../../common/util');
|
||||
const {FS} = require('../../../common/cloudfunc');
|
||||
|
||||
const {
|
||||
isImage,
|
||||
isAudio,
|
||||
|
|
@ -49,6 +50,7 @@ module.exports.hide = hide;
|
|||
let Loading = false;
|
||||
|
||||
const Name = 'View';
|
||||
|
||||
CloudCmd[Name] = module.exports;
|
||||
|
||||
const Info = DOM.CurrentInfo;
|
||||
|
|
@ -64,84 +66,88 @@ const Config = {
|
|||
Images.hide();
|
||||
Key.unsetBind();
|
||||
},
|
||||
|
||||
|
||||
beforeClose: () => {
|
||||
Events.rmKey(listener);
|
||||
Key.setBind();
|
||||
},
|
||||
|
||||
|
||||
afterShow: () => {
|
||||
El.focus();
|
||||
},
|
||||
|
||||
|
||||
onOverlayClick,
|
||||
afterClose: noop,
|
||||
autoSize: false,
|
||||
|
||||
|
||||
helpers: {
|
||||
title: {},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports._Config = Config;
|
||||
|
||||
module.exports.init = async () => {
|
||||
await loadAll();
|
||||
|
||||
|
||||
const events = [
|
||||
'click',
|
||||
'contextmenu',
|
||||
];
|
||||
|
||||
events.forEach(addEvent(Overlay, onOverlayClick));
|
||||
|
||||
events.forEach(addEvent(
|
||||
Overlay,
|
||||
onOverlayClick,
|
||||
));
|
||||
};
|
||||
|
||||
async function show(data, options = {}) {
|
||||
const prefixURL = CloudCmd.prefixURL + FS;
|
||||
|
||||
|
||||
if (Loading)
|
||||
return;
|
||||
|
||||
|
||||
if (!options || options.bindKeys !== false)
|
||||
Events.addKey(listener);
|
||||
|
||||
|
||||
El = createElement('div', {
|
||||
className: 'view',
|
||||
notAppend: true,
|
||||
});
|
||||
|
||||
|
||||
El.tabIndex = 0;
|
||||
|
||||
|
||||
if (data) {
|
||||
if (isArray(data))
|
||||
El.append(...data);
|
||||
else
|
||||
El.append(data);
|
||||
|
||||
|
||||
modal.open(El, initConfig(options));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Images.show.load();
|
||||
|
||||
|
||||
const path = prefixURL + Info.path;
|
||||
const type = options.raw ? '' : await getType(path);
|
||||
|
||||
|
||||
switch(type) {
|
||||
default:
|
||||
return await viewFile();
|
||||
|
||||
|
||||
case 'markdown':
|
||||
return await CloudCmd.Markdown.show(Info.path);
|
||||
|
||||
|
||||
case 'html':
|
||||
return viewHtml(path);
|
||||
|
||||
|
||||
case 'image':
|
||||
return viewImage(Info.path, prefixURL);
|
||||
|
||||
|
||||
case 'media':
|
||||
return await viewMedia(path);
|
||||
|
||||
|
||||
case 'pdf':
|
||||
return viewPDF(path);
|
||||
}
|
||||
|
|
@ -154,11 +160,11 @@ function createIframe(src) {
|
|||
width: '100%',
|
||||
height: '100%',
|
||||
});
|
||||
|
||||
|
||||
element.addEventListener('load', () => {
|
||||
element.contentWindow.addEventListener('keydown', listener);
|
||||
});
|
||||
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
|
|
@ -169,21 +175,21 @@ function viewHtml(src) {
|
|||
|
||||
function viewPDF(src) {
|
||||
const element = createIframe(src);
|
||||
|
||||
|
||||
const options = assign({}, Config);
|
||||
|
||||
|
||||
if (CloudCmd.config('showFileName'))
|
||||
options.title = Info.name;
|
||||
|
||||
|
||||
modal.open(element, options);
|
||||
}
|
||||
|
||||
async function viewMedia(path) {
|
||||
const [e, element] = await getMediaElement(path);
|
||||
|
||||
|
||||
if (e)
|
||||
return alert(e);
|
||||
|
||||
|
||||
const allConfig = {
|
||||
...Config,
|
||||
...{
|
||||
|
|
@ -195,22 +201,22 @@ async function viewMedia(path) {
|
|||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
modal.open(element, allConfig);
|
||||
}
|
||||
|
||||
async function viewFile() {
|
||||
const [error, data] = await Info.getData();
|
||||
|
||||
|
||||
if (error)
|
||||
return Images.hide();
|
||||
|
||||
|
||||
const element = document.createTextNode(data);
|
||||
const options = Config;
|
||||
|
||||
|
||||
if (CloudCmd.config('showFileName'))
|
||||
options.title = Info.name;
|
||||
|
||||
|
||||
El.append(element);
|
||||
modal.open(El, options);
|
||||
}
|
||||
|
|
@ -220,25 +226,26 @@ const copy = (a) => assign({}, a);
|
|||
module.exports._initConfig = initConfig;
|
||||
function initConfig(options) {
|
||||
const config = copy(Config);
|
||||
|
||||
|
||||
if (!options)
|
||||
return config;
|
||||
|
||||
|
||||
const names = Object.keys(options);
|
||||
|
||||
|
||||
for (const name of names) {
|
||||
const isConfig = Boolean(config[name]);
|
||||
const item = options[name];
|
||||
|
||||
|
||||
if (!isFn(item) || !isConfig) {
|
||||
config[name] = options[name];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const fn = config[name];
|
||||
|
||||
config[name] = series(fn, item);
|
||||
}
|
||||
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
|
@ -252,59 +259,60 @@ function viewImage(path, prefixURL) {
|
|||
href: `${prefixURL}${path}`,
|
||||
title: encode(basename(path)),
|
||||
});
|
||||
|
||||
const names = Info.files
|
||||
|
||||
const names = Info
|
||||
.files
|
||||
.map(DOM.getCurrentPath)
|
||||
.filter(isSupportedImage);
|
||||
|
||||
const titles = names
|
||||
.map(makeTitle);
|
||||
|
||||
|
||||
const titles = names.map(makeTitle);
|
||||
|
||||
const index = names.indexOf(Info.path);
|
||||
|
||||
const imageConfig = {
|
||||
index,
|
||||
autoSize : true,
|
||||
arrows : true,
|
||||
keys : true,
|
||||
helpers : {
|
||||
title : {},
|
||||
autoSize: true,
|
||||
arrows: true,
|
||||
keys: true,
|
||||
helpers: {
|
||||
title: {},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
const config = {
|
||||
...Config,
|
||||
...imageConfig,
|
||||
};
|
||||
|
||||
|
||||
modal.open(titles, config);
|
||||
}
|
||||
|
||||
async function getMediaElement(src) {
|
||||
check(src);
|
||||
|
||||
|
||||
const [error, template] = await tryToCatch(Files.get, 'view/media-tmpl');
|
||||
|
||||
|
||||
if (error)
|
||||
return [error];
|
||||
|
||||
|
||||
const {name} = Info;
|
||||
|
||||
|
||||
if (!TemplateAudio)
|
||||
TemplateAudio = template;
|
||||
|
||||
|
||||
const is = isAudio(name);
|
||||
const type = is ? 'audio' : 'video';
|
||||
|
||||
|
||||
const innerHTML = rendy(TemplateAudio, {
|
||||
src,
|
||||
type,
|
||||
name,
|
||||
});
|
||||
|
||||
|
||||
const element = createElement('div', {
|
||||
innerHTML,
|
||||
});
|
||||
|
||||
|
||||
return [null, element];
|
||||
}
|
||||
|
||||
|
|
@ -319,9 +327,9 @@ function check(src) {
|
|||
*/
|
||||
async function loadAll() {
|
||||
const {DIR_DIST} = CloudCmd;
|
||||
|
||||
|
||||
time(`${Name} load`);
|
||||
|
||||
|
||||
Loading = true;
|
||||
await loadCSS(`${DIR_DIST}/view.css`);
|
||||
Loading = false;
|
||||
|
|
@ -332,32 +340,29 @@ function onOverlayClick(event) {
|
|||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
};
|
||||
|
||||
|
||||
setCurrentByPosition(position);
|
||||
}
|
||||
|
||||
function setCurrentByPosition(position) {
|
||||
const element = DOM.getCurrentByPosition(position);
|
||||
|
||||
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
const {
|
||||
files,
|
||||
filesPassive,
|
||||
} = Info;
|
||||
|
||||
|
||||
const {files, filesPassive} = Info;
|
||||
|
||||
const isFiles = files.includes(element);
|
||||
const isFilesPassive = filesPassive.includes(element);
|
||||
|
||||
|
||||
if (!isFiles && !isFilesPassive)
|
||||
return;
|
||||
|
||||
|
||||
const isCurrent = DOM.isCurrentFile(element);
|
||||
|
||||
|
||||
if (isCurrent)
|
||||
return;
|
||||
|
||||
|
||||
DOM.setCurrentFile(element);
|
||||
}
|
||||
|
||||
|
|
@ -365,4 +370,3 @@ function listener({keyCode}) {
|
|||
if (keyCode === Key.ESC)
|
||||
hide();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,12 +64,10 @@ test('cloudcmd: client: view: html', (t) => {
|
|||
open,
|
||||
});
|
||||
|
||||
const {
|
||||
_viewHtml,
|
||||
_Config,
|
||||
} = reRequire('.');
|
||||
const {_viewHtml, _Config} = reRequire('.');
|
||||
|
||||
const src = '/hello.html';
|
||||
|
||||
_viewHtml(src);
|
||||
|
||||
global.CloudCmd = CloudCmd;
|
||||
|
|
@ -89,6 +87,7 @@ test('cloudcmd: client: view: createIframe', (t) => {
|
|||
const el = {
|
||||
addEventListener,
|
||||
};
|
||||
|
||||
const createElement = stub().returns(el);
|
||||
|
||||
mockRequire('@cloudcmd/create-element', createElement);
|
||||
|
|
@ -114,6 +113,7 @@ test('cloudcmd: client: view: createIframe: returns', (t) => {
|
|||
const el = {
|
||||
addEventListener,
|
||||
};
|
||||
|
||||
const createElement = stub().returns(el);
|
||||
|
||||
mockRequire('@cloudcmd/create-element', createElement);
|
||||
|
|
|
|||
|
|
@ -69,9 +69,10 @@ async function detectType(path) {
|
|||
|
||||
for (const [name, value] of headers) {
|
||||
if (name === 'content-type')
|
||||
return `.${value.split('/').pop()}`;
|
||||
return `.${value
|
||||
.split('/')
|
||||
.pop()}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,15 +23,14 @@ test('cloudcmd: client: view: types: detectType', async (t) => {
|
|||
});
|
||||
|
||||
const originalFetch = global.fetch;
|
||||
|
||||
global.fetch = fetch;
|
||||
await _detectType('/hello');
|
||||
|
||||
global.fetch = originalFetch;
|
||||
const expected = [
|
||||
'/hello', {
|
||||
method: 'HEAD',
|
||||
},
|
||||
];
|
||||
const expected = ['/hello', {
|
||||
method: 'HEAD',
|
||||
}];
|
||||
|
||||
t.calledWith(fetch, expected);
|
||||
t.end();
|
||||
|
|
@ -39,6 +38,7 @@ test('cloudcmd: client: view: types: detectType', async (t) => {
|
|||
|
||||
test('cloudcmd: client: view: types: detectType: found', async (t) => {
|
||||
const originalFetch = global.fetch;
|
||||
|
||||
global.fetch = stub().returns({
|
||||
headers: [
|
||||
['content-type', 'image/png'],
|
||||
|
|
@ -51,4 +51,3 @@ test('cloudcmd: client: view: types: detectType: found', async (t) => {
|
|||
t.equal(result, '.png');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ const DOM = require('./dom');
|
|||
|
||||
const Info = DOM.CurrentInfo;
|
||||
|
||||
const {
|
||||
sort,
|
||||
order,
|
||||
} = CloudCmd;
|
||||
const {sort, order} = CloudCmd;
|
||||
|
||||
const position = DOM.getPanelPosition();
|
||||
|
||||
|
|
@ -17,10 +14,7 @@ let sortPrevious = sort[position];
|
|||
const {getPanel} = DOM;
|
||||
|
||||
CloudCmd.sortPanel = (name, panel = getPanel()) => {
|
||||
const position = panel
|
||||
.dataset
|
||||
.name
|
||||
.replace('js-', '');
|
||||
const position = panel.dataset.name.replace('js-', '');
|
||||
|
||||
if (name !== sortPrevious) {
|
||||
order[position] = 'asc';
|
||||
|
|
@ -40,4 +34,3 @@ CloudCmd.sortPanel = (name, panel = getPanel()) => {
|
|||
noCurrent,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ async function registerSW(prefix) {
|
|||
|
||||
if (e)
|
||||
return null;
|
||||
|
||||
|
||||
return sw;
|
||||
}
|
||||
|
||||
|
|
@ -33,4 +33,3 @@ async function unregisterSW(prefix) {
|
|||
const reg = await registerSW(prefix);
|
||||
reg?.unregister(prefix);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,4 +114,3 @@ test('sw: register: unregisterSW', async (t, {location, navigator}) => {
|
|||
t.calledWith(register, ['/hello/sw.js'], 'should call register');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ const createRequest = (a) => new Request(a, {
|
|||
const getRequest = (a, request) => {
|
||||
if (a !== '/')
|
||||
return request;
|
||||
|
||||
|
||||
return createRequest('/');
|
||||
};
|
||||
|
||||
|
|
@ -97,4 +97,3 @@ async function addToCache(request, response) {
|
|||
const cache = await caches.open(NAME);
|
||||
return cache.put(request, response);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
module.exports.btoa = (str) => {
|
||||
if (typeof btoa === 'function')
|
||||
return btoa(str);
|
||||
|
||||
|
||||
return Buffer
|
||||
.from(str)
|
||||
.toString('base64');
|
||||
|
|
@ -12,9 +12,8 @@ module.exports.btoa = (str) => {
|
|||
module.exports.atob = (str) => {
|
||||
if (typeof atob === 'function')
|
||||
return atob(str);
|
||||
|
||||
|
||||
return Buffer
|
||||
.from(str, 'base64')
|
||||
.toString('binary');
|
||||
};
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue