chore: lint

This commit is contained in:
coderaiser 2023-07-09 12:43:24 +03:00
parent f1279666b5
commit 4717e035ee
173 changed files with 1388 additions and 1627 deletions

6
.github/FUNDING.yml vendored
View file

@ -1,10 +1,4 @@
# These are supported funding model platforms
github: coderaiser github: coderaiser
patreon: coderaiser patreon: coderaiser
open_collective: cloudcmd open_collective: cloudcmd
ko_fi: coderaiser 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

View file

@ -48,6 +48,6 @@ jobs:
- name: Coverage - name: Coverage
run: redrun coverage coverage:report run: redrun coverage coverage:report
- name: Coveralls - name: Coveralls
uses: coverallsapp/github-action@master uses: coverallsapp/github-action@v2
with: with:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,7 +1,5 @@
{ {
"plugins": [ "plugins": ["cloudcmd"],
"cloudcmd"
],
"ignore": [ "ignore": [
"html", "html",
"fixture*", "fixture*",

View file

@ -37,11 +37,8 @@ const plugins = clean([
const rules = [{ const rules = [{
test: /\.css$/, test: /\.css$/,
exclude: /css\/(nojs|view|config|terminal|user-menu|columns.*)\.css/, exclude: /css\/(nojs|view|config|terminal|user-menu|columns.*)\.css/,
use: extractMain.extract([ use: extractMain.extract(['css-loader']),
'css-loader', }, ...cssPlugins.map(extract), {
]),
},
...cssPlugins.map(extract), {
test: /\.(png|gif|svg|woff|woff2|eot|ttf)$/, test: /\.(png|gif|svg|woff|woff2|eot|ttf)$/,
use: { use: {
loader: 'url-loader', loader: 'url-loader',
@ -63,7 +60,8 @@ function getCSSList(dir) {
const addDir = (name) => `${dir}/${name}`; const addDir = (name) => `${dir}/${name}`;
const rootDir = join(__dirname, '..'); const rootDir = join(__dirname, '..');
return fs.readdirSync(`${rootDir}/css/${dir}`) return fs
.readdirSync(`${rootDir}/css/${dir}`)
.map(base) .map(base)
.map(addDir); .map(addDir);
} }
@ -73,9 +71,6 @@ function extract(extractPlugin) {
return { return {
test: RegExp(`css/${filename}`), test: RegExp(`css/${filename}`),
use: extractPlugin.extract([ use: extractPlugin.extract(['css-loader']),
'css-loader',
]),
}; };
} }

View file

@ -19,25 +19,24 @@ module.exports = {
function getMinifyHtmlOptions() { function getMinifyHtmlOptions() {
return { return {
removeComments: true, removeComments: true,
removeCommentsFromCDATA: true, removeCommentsFromCDATA: true,
removeCDATASectionsFromCDATA: true, removeCDATASectionsFromCDATA: true,
collapseWhitespace: true, collapseWhitespace: true,
collapseBooleanAttributes: true, collapseBooleanAttributes: true,
removeAttributeQuotes: true, removeAttributeQuotes: true,
removeRedundantAttributes: true, removeRedundantAttributes: true,
useShortDoctype: true, useShortDoctype: true,
removeEmptyAttributes: true, removeEmptyAttributes: true,
/* оставляем, поскольку у нас /* оставляем, поскольку у нас
* в элемент fm генерируеться * в элемент fm генерируеться
* таблица файлов * таблица файлов
*/ */
removeEmptyElements: false, removeEmptyElements: false,
removeOptionalTags: true, removeOptionalTags: true,
removeScriptTypeAttributes: true, removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true, removeStyleLinkTypeAttributes: true,
minifyJS: true, minifyJS: true,
}; };
} }

View file

@ -44,18 +44,17 @@ const rules = clean([
exclude: /node_modules/, exclude: /node_modules/,
loader: 'babel-loader', loader: 'babel-loader',
options, options,
}]); },
]);
const plugins = [ const plugins = [
new EnvironmentPlugin({ new EnvironmentPlugin({
NODE_ENV, NODE_ENV,
}), }),
new ServiceWorkerWebpackPlugin({ new ServiceWorkerWebpackPlugin({
entry: join(__dirname, '..', 'client', 'sw', 'sw.js'), entry: join(__dirname, '..', 'client', 'sw', 'sw.js'),
excludes: ['*'], excludes: ['*'],
}), }),
new WebpackBar(), new WebpackBar(),
]; ];
@ -102,9 +101,7 @@ module.exports = {
devtoolModuleFilenameTemplate, devtoolModuleFilenameTemplate,
publicPath: '/dist/', publicPath: '/dist/',
}, },
externals: [ externals: [externals],
externals,
],
module: { module: {
rules, rules,
noParse, noParse,
@ -132,4 +129,3 @@ function devtoolModuleFilenameTemplate(info) {
const resource = info.absoluteResourcePath.replace(rootDir + sep, ''); const resource = info.absoluteResourcePath.replace(rootDir + sep, '');
return `file://cloudcmd/${resource}`; return `file://cloudcmd/${resource}`;
} }

101
HELP.md
View file

@ -374,50 +374,50 @@ Here's a description of all options:
```json ```json
{ {
"name" : "", // set tab name in web browser "name": "", // set tab name in web browser
"auth" : false, // enable http authentication "auth": false, // enable http authentication
"username" : "root", // username for authentication "username": "root", // username for authentication
"password" : "toor", // password hash for authentication "password": "toor", // password hash for authentication
"algo" : "sha512WithRSAEncryption", // cryptographic algorithm "algo": "sha512WithRSAEncryption", // cryptographic algorithm
"editor" : "edward", // default, could be "dword" or "edward" "editor": "edward", // default, could be "dword" or "edward"
"packer" : "tar", // default, could be "tar" or "zip" "packer": "tar", // default, could be "tar" or "zip"
"diff" : true, // when save - send patch, not whole file "diff": true, // when save - send patch, not whole file
"zip" : true, // zip text before send / unzip before save "zip": true, // zip text before send / unzip before save
"buffer" : true, // buffer for copying files "buffer": true, // buffer for copying files
"dirStorage" : true, // store directory listing "dirStorage": true, // store directory listing
"online" : false, // do not load js files from cdn "online": false, // do not load js files from cdn
"open" : true, // open web browser when server started "open": true, // open web browser when server started
"oneFilePanel" : false, // show one file panel "oneFilePanel": false, // show one file panel
"keysPanel" : true, // show classic panel with buttons of keys "keysPanel": true, // show classic panel with buttons of keys
"port" : 8000, // http port "port": 8000, // http port
"ip" : null, // ip or null(default) "ip": null, // ip or null(default)
"root" : "/", // root directory "root": "/", // root directory
"prefix" : "", // url prefix "prefix": "", // url prefix
"prefixSocket" : "", // prefix for socket connection "prefixSocket": "", // prefix for socket connection
"confirmCopy" : true, // confirm copy "confirmCopy": true, // confirm copy
"confirmMove" : true, // confirm move "confirmMove": true, // confirm move
"showConfig" : false, // show config at startup "showConfig": false, // show config at startup
"showFileName" : false, // do not show file name in view and edit "showFileName": false, // do not show file name in view and edit
"contact" : true, // enable contact "contact": true, // enable contact
"configDialog" : true, // enable config dialog "configDialog": true, // enable config dialog
"configAuth" : true, // enable auth change in config dialog "configAuth": true, // enable auth change in config dialog
"console" : true, // enable console "console": true, // enable console
"syncConsolePath" : false, // do not sync console path "syncConsolePath": false, // do not sync console path
"terminal" : false, // disable terminal "terminal": false, // disable terminal
"terminalPath" : "", // path of a terminal "terminalPath": "", // path of a terminal
"terminalCommand" : "", // set command to run in terminal "terminalCommand": "", // set command to run in terminal
"terminalAutoRestart" : true, // restart command on exit "terminalAutoRestart": true, // restart command on exit
"vim" : false, // disable vim hot keys "vim": false, // disable vim hot keys
"columns" : "name-size-date-owner-mode", // set visible columns "columns": "name-size-date-owner-mode", // set visible columns
"export" : false, // enable export of config through a server "export": false, // enable export of config through a server
"exportToken" : "root", // token used by export server "exportToken": "root", // token used by export server
"import" : false, // enable import of config "import": false, // enable import of config
"import-url" : "http://localhost:8000", // url of an export server "import-url": "http://localhost:8000", // url of an export server
"importToken" : "root", // token used to connect to export server "importToken": "root", // token used to connect to export server
"importListen" : false, // listen on config updates "importListen": false, // listen on config updates
"dropbox" : false, // disable dropbox integration "dropbox": false, // disable dropbox integration
"dropboxToken" : "", // unset dropbox token "dropboxToken": "", // unset dropbox token
"log" : true // logging "log": true // logging
} }
``` ```
@ -467,9 +467,7 @@ const RENAME_FILE = 'Rename file';
export default { export default {
'__settings': { '__settings': {
select: [ select: [RENAME_FILE],
RENAME_FILE,
],
run: false, run: false,
}, },
[`F2 - ${RENAME_FILE}`]: async ({DOM}) => { [`F2 - ${RENAME_FILE}`]: async ({DOM}) => {
@ -499,7 +497,9 @@ export default {
const path = `${dirPath}.cloudcmd.menu.js`; const path = `${dirPath}.cloudcmd.menu.js`;
const {prefix} = CloudCmd; const {prefix} = CloudCmd;
const data = await readDefaultMenu({prefix}); const data = await readDefaultMenu({
prefix,
});
await createDefaultMenu({ await createDefaultMenu({
path, path,
data, data,
@ -743,6 +743,7 @@ const socket2 = new Server(server, {
}); });
const configManager1 = createConfigManager(); const configManager1 = createConfigManager();
configManager1('name', '1'); configManager1('name', '1');
const configManager2 = createConfigManager(); const configManager2 = createConfigManager();
@ -765,8 +766,10 @@ If you want to enable authorization, you can pass credentials to Cloud Commander
```js ```js
import criton from 'criton'; import criton from 'criton';
const algo = 'sha512WithRSAEncryption'; // default
const algo = 'sha512WithRSAEncryption';
// default
// you can generate a hash dynamically // you can generate a hash dynamically
const password = criton('root', algo); const password = criton('root', algo);

View file

@ -5,13 +5,11 @@ import {promisify} from 'util';
import tryToCatch from 'try-to-catch'; import tryToCatch from 'try-to-catch';
import {createSimport} from 'simport'; import {createSimport} from 'simport';
import parse from 'yargs-parser'; import parse from 'yargs-parser';
import exit from '../server/exit.js'; import exit from '../server/exit.js';
import { import {
createConfig, createConfig,
configPath, configPath,
} from '../server/config.js'; } from '../server/config.js';
import env from '../server/env.js'; import env from '../server/env.js';
import prefixer from '../server/prefixer.js'; import prefixer from '../server/prefixer.js';
@ -26,7 +24,7 @@ const simport = createSimport(import.meta.url);
const choose = (a, b) => { const choose = (a, b) => {
if (a === undefined) if (a === undefined)
return b; return b;
return a; return a;
}; };
@ -39,7 +37,7 @@ const DIR_SERVER = '../server/';
const maybeRoot = (a) => { const maybeRoot = (a) => {
if (a === '.') if (a === '.')
return process.cwd(); return process.cwd();
return a; return a;
}; };
@ -100,29 +98,29 @@ const yargsOptions = {
'dropbox', 'dropbox',
], ],
default: { default: {
'server' : true, 'server': true,
'name' : choose(env('name'), config('name')), 'name': choose(env('name'), config('name')),
'auth' : choose(env.bool('auth'), config('auth')), 'auth': choose(env.bool('auth'), config('auth')),
'port' : config('port'), 'port': config('port'),
'online' : config('online'), 'online': config('online'),
'open' : choose(env.bool('open'), config('open')), 'open': choose(env.bool('open'), config('open')),
'editor' : env('editor') || config('editor'), 'editor': env('editor') || config('editor'),
'packer' : config('packer') || 'tar', 'packer': config('packer') || 'tar',
'zip' : config('zip'), 'zip': config('zip'),
'username' : env('username') || config('username'), 'username': env('username') || config('username'),
'root' : choose(env('root'), config('root')), 'root': choose(env('root'), config('root')),
'prefix' : choose(env('prefix'), config('prefix')), 'prefix': choose(env('prefix'), config('prefix')),
'console' : choose(env.bool('console'), config('console')), 'console': choose(env.bool('console'), config('console')),
'contact' : choose(env.bool('contact'), config('contact')), 'contact': choose(env.bool('contact'), config('contact')),
'terminal' : choose(env.bool('terminal'), config('terminal')), 'terminal': choose(env.bool('terminal'), config('terminal')),
'columns' : env('columns') || config('columns') || '', 'columns': env('columns') || config('columns') || '',
'vim' : choose(env.bool('vim'), config('vim')), 'vim': choose(env.bool('vim'), config('vim')),
'log' : config('log'), 'log': config('log'),
'import-url': env('import_url') || config('importUrl'), 'import-url': env('import_url') || config('importUrl'),
'import-listen': choose(env.bool('import_listen'), config('importListen')), 'import-listen': choose(env.bool('import_listen'), config('importListen')),
'import' : choose(env.bool('import'), config('import')), 'import': choose(env.bool('import'), config('import')),
'export' : choose(env.bool('export'), config('export')), 'export': choose(env.bool('export'), config('export')),
'prefix-socket': config('prefixSocket'), 'prefix-socket': config('prefixSocket'),
'show-file-name': choose(env.bool('show_file_name'), config('showFileName')), '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); console.log('%s %s', latest, current);
} }

View file

@ -1,7 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
import {promisify} from 'util'; import {promisify} from 'util';
import tryToCatch from 'try-to-catch'; import tryToCatch from 'try-to-catch';
import {createSimport} from 'simport'; import {createSimport} from 'simport';
import minor from 'minor'; import minor from 'minor';
@ -20,8 +19,9 @@ async function main() {
const history = '## Version history\n\n'; const history = '## Version history\n\n';
const link = '//github.com/coderaiser/cloudcmd/releases/tag/'; const link = '//github.com/coderaiser/cloudcmd/releases/tag/';
const template = '- *{{ date }}*, ' + const template = '- *{{ date }}*, ' +
'**[v{{ version }}]' + '**[v{{ version }}]' +
'(' + link + 'v{{ version }})**\n'; '(' + link +
'v{{ version }})**\n';
const {version} = Info; const {version} = Info;
@ -34,8 +34,8 @@ async function main() {
await replaceVersion('HELP.md', version, versionNew); await replaceVersion('HELP.md', version, versionNew);
const historyNew = history + rendy(template, { const historyNew = history + rendy(template, {
date : shortdate(), date: shortdate(),
version : versionNew, version: versionNew,
}); });
await replaceVersion('HELP.md', history, historyNew); await replaceVersion('HELP.md', history, historyNew);
@ -68,7 +68,6 @@ async function cl() {
function getVersionNew(last, match) { function getVersionNew(last, match) {
if (match) if (match)
return minor(match, Info.version); return minor(match, Info.version);
return last.substr(3); return last.substr(3);
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global DOM */ /* global DOM */
const Emitify = require('emitify'); const Emitify = require('emitify');
const inherits = require('inherits'); const inherits = require('inherits');
const rendy = require('rendy'); const rendy = require('rendy');
@ -16,6 +15,7 @@ const Images = require('./dom/images');
const {unregisterSW} = require('./sw/register'); const {unregisterSW} = require('./sw/register');
const getJsonFromFileTable = require('./get-json-from-file-table'); const getJsonFromFileTable = require('./get-json-from-file-table');
const Key = require('./key'); const Key = require('./key');
const { const {
apiURL, apiURL,
formatMsg, formatMsg,
@ -39,58 +39,60 @@ load.addErrorListener((e, src) => {
function CloudCmdProto(DOM) { function CloudCmdProto(DOM) {
let Listeners; let Listeners;
Emitify.call(this); Emitify.call(this);
const CloudCmd = this; const CloudCmd = this;
const Info = DOM.CurrentInfo; const Info = DOM.CurrentInfo;
const { const {Storage, Files} = DOM;
Storage,
Files,
} = DOM;
this.log = (...a) => { this.log = (...a) => {
if (!isDev) if (!isDev)
return; return;
console.log(...a); console.log(...a);
}; };
this.prefix = ''; this.prefix = '';
this.prefixSocket = ''; this.prefixSocket = '';
this.prefixURL = ''; this.prefixURL = '';
this.MIN_ONE_PANEL_WIDTH = 1155; this.MIN_ONE_PANEL_WIDTH = 1155;
this.HOST = location.origin || location.protocol + '//' + location.host; this.HOST = location.origin || location.protocol + '//' + location.host;
this.TITLE = 'Cloud Commander'; this.TITLE = 'Cloud Commander';
this.sort = { this.sort = {
left: 'name', left: 'name',
right: 'name', right: 'name',
}; };
this.order = { this.order = {
left: 'asc', left: 'asc',
right: '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; const refresh = isRefresh;
let panelChanged; let panelChanged;
if (!noCurrent && panel && panel !== Info.panel) { if (!noCurrent && panel && panel !== Info.panel) {
DOM.changePanel(); DOM.changePanel();
panelChanged = true; panelChanged = true;
} }
let imgPosition; let imgPosition;
if (panelChanged || refresh || !history) if (panelChanged || refresh || !history)
imgPosition = 'top'; imgPosition = 'top';
Images.show.load(imgPosition, panel); Images.show.load(imgPosition, panel);
/* загружаем содержимое каталога */ /* загружаем содержимое каталога */
await ajaxLoad(addSlashToEnd(path), { await ajaxLoad(addSlashToEnd(path), {
refresh, refresh,
@ -111,7 +113,7 @@ function CloudCmdProto(DOM) {
CloudCmd.prefixSocket = config.prefixSocket; CloudCmd.prefixSocket = config.prefixSocket;
CloudCmd.DIR_DIST = `${prefix}/dist`; CloudCmd.DIR_DIST = `${prefix}/dist`;
CloudCmd.DIR_MODULES = `${this.DIR_DIST}/modules`; CloudCmd.DIR_MODULES = `${this.DIR_DIST}/modules`;
CloudCmd.config = (key) => config[key]; CloudCmd.config = (key) => config[key];
CloudCmd.config.if = currify((key, fn, a) => config[key] && fn(a)); CloudCmd.config.if = currify((key, fn, a) => config[key] && fn(a));
CloudCmd._config = (key, value) => { CloudCmd._config = (key, value) => {
@ -119,61 +121,60 @@ function CloudCmdProto(DOM) {
* should be called from config.js only * should be called from config.js only
* after successful update on server * after successful update on server
*/ */
if (key === 'password') if (key === 'password')
return; return;
config[key] = value; config[key] = value;
}; };
if (config.oneFilePanel) if (config.oneFilePanel)
CloudCmd.MIN_ONE_PANEL_WIDTH = Infinity; CloudCmd.MIN_ONE_PANEL_WIDTH = Infinity;
if (!document.body.scrollIntoViewIfNeeded) if (!document.body.scrollIntoViewIfNeeded)
await load.js(`${CloudCmd.DIR_MODULES}/polyfill.js`); await load.js(`${CloudCmd.DIR_MODULES}/polyfill.js`);
await initModules(); await initModules();
await baseInit(); await baseInit();
await loadStyle(); await loadStyle();
CloudCmd.route(location.hash); CloudCmd.route(location.hash);
}; };
async function loadStyle() { async function loadStyle() {
const {prefix} = CloudCmd; const {prefix} = CloudCmd;
const name = `${prefix}/dist/cloudcmd.common.css`; const name = `${prefix}/dist/cloudcmd.common.css`;
await load.css(name); await load.css(name);
} }
this.route = (path) => { this.route = (path) => {
const query = path.split('/'); const query = path.split('/');
if (!path) if (!path)
return; return;
const [kebabModule] = query; const [kebabModule] = query;
const module = noJS(pascalCase(kebabModule.slice(1))); const module = noJS(pascalCase(kebabModule.slice(1)));
const file = query[1]; const file = query[1];
const current = DOM.getCurrentByName(file); const current = DOM.getCurrentByName(file);
if (file && !current) { if (file && !current) {
const msg = formatMsg('set current file', file, 'error'); const msg = formatMsg('set current file', file, 'error');
CloudCmd.log(msg); CloudCmd.log(msg);
return; return;
} }
DOM.setCurrentFile(current); DOM.setCurrentFile(current);
CloudCmd.execFromModule(module, 'show'); CloudCmd.execFromModule(module, 'show');
}; };
this.logOut = async () => { this.logOut = async () => {
const url = CloudCmd.prefix + '/logout'; const url = CloudCmd.prefix + '/logout';
const error = () => document.location.reload(); const error = () => document.location.reload();
const {prefix} = CloudCmd; const {prefix} = CloudCmd;
await DOM.Storage.clear(); await DOM.Storage.clear();
unregisterSW(prefix); unregisterSW(prefix);
DOM.load.ajax({ DOM.load.ajax({
@ -181,19 +182,19 @@ function CloudCmdProto(DOM) {
error, error,
}); });
}; };
const initModules = async () => { const initModules = async () => {
CloudCmd.Key = Key; CloudCmd.Key = Key;
CloudCmd.Key.bind(); CloudCmd.Key.bind();
const [, modules] = await tryToCatch(Files.get, 'modules'); const [, modules] = await tryToCatch(Files.get, 'modules');
const showLoad = Images.show.load; const showLoad = Images.show.load;
const doBefore = { const doBefore = {
edit: showLoad, edit: showLoad,
menu: showLoad, menu: showLoad,
}; };
const load = (name, path, dobefore) => { const load = (name, path, dobefore) => {
loadModule({ loadModule({
name, name,
@ -201,28 +202,28 @@ function CloudCmdProto(DOM) {
dobefore, dobefore,
}); });
}; };
if (!modules) if (!modules)
return; return;
for (const module of modules.local) { for (const module of modules.local) {
load(null, module, doBefore[module]); load(null, module, doBefore[module]);
} }
}; };
async function saveCurrentName(currentName) { async function saveCurrentName(currentName) {
await Storage.set('current-name', currentName); await Storage.set('current-name', currentName);
} }
async function baseInit() { async function baseInit() {
const files = DOM.getFiles(); const files = DOM.getFiles();
CloudCmd.on('current-file', DOM.updateCurrentInfo); CloudCmd.on('current-file', DOM.updateCurrentInfo);
CloudCmd.on('current-name', saveCurrentName); CloudCmd.on('current-name', saveCurrentName);
const name = await Storage.get('current-name'); const name = await Storage.get('current-name');
const currentFile = name && DOM.getCurrentByName(name) || files[0]; const currentFile = name && DOM.getCurrentByName(name) || files[0];
/* выделяем строку с первым файлом */ /* выделяем строку с первым файлом */
if (files) if (files)
DOM.setCurrentFile(currentFile, { DOM.setCurrentFile(currentFile, {
@ -231,31 +232,32 @@ function CloudCmdProto(DOM) {
// overwre otherwise // overwre otherwise
history: !location.hash, history: !location.hash,
}); });
const dirPath = DOM.getCurrentDirPath(); const dirPath = DOM.getCurrentDirPath();
Listeners = CloudCmd.Listeners; Listeners = CloudCmd.Listeners;
Listeners.init(); Listeners.init();
const panels = getPanels(); const panels = getPanels();
panels.forEach(Listeners.setOnPanel); panels.forEach(Listeners.setOnPanel);
Listeners.initKeysPanel(); Listeners.initKeysPanel();
if (!CloudCmd.config('dirStorage')) if (!CloudCmd.config('dirStorage'))
return; return;
const data = await Storage.get(dirPath); const data = await Storage.get(dirPath);
if (!data) if (!data)
await Storage.setJson(dirPath, getJsonFromFileTable()); await Storage.setJson(dirPath, getJsonFromFileTable());
} }
function getPanels() { function getPanels() {
const panels = ['left']; const panels = ['left'];
if (CloudCmd.config('oneFilePanel')) if (CloudCmd.config('oneFilePanel'))
return panels; return panels;
return [ return [
...panels, ...panels,
'right', 'right',
@ -264,23 +266,20 @@ function CloudCmdProto(DOM) {
this.execFromModule = async (moduleName, funcName, ...args) => { this.execFromModule = async (moduleName, funcName, ...args) => {
await CloudCmd[moduleName](); await CloudCmd[moduleName]();
const func = CloudCmd[moduleName][funcName]; const func = CloudCmd[moduleName][funcName];
func(...args); func(...args);
}; };
this.refresh = async (options = {}) => { this.refresh = async (options = {}) => {
const { const {panel = Info.panel, currentName} = options;
panel = Info.panel,
currentName,
} = options;
const path = DOM.getCurrentDirPath(panel); const path = DOM.getCurrentDirPath(panel);
const isRefresh = true; const isRefresh = true;
const history = false; const history = false;
const noCurrent = options ? options.noCurrent : false; const noCurrent = options ? options.noCurrent : false;
await CloudCmd.changeDir(path, { await CloudCmd.changeDir(path, {
isRefresh, isRefresh,
history, history,
@ -302,46 +301,43 @@ function CloudCmdProto(DOM) {
*/ */
async function ajaxLoad(path, options = {}, panel) { async function ajaxLoad(path, options = {}, panel) {
const {RESTful} = DOM; const {RESTful} = DOM;
CloudCmd.log(`reading dir: "${path}";`); CloudCmd.log(`reading dir: "${path}";`);
const dirStorage = CloudCmd.config('dirStorage'); const dirStorage = CloudCmd.config('dirStorage');
const json = dirStorage && await Storage.getJson(path); const json = dirStorage && await Storage.getJson(path);
const name = options.currentName || Info.name; const name = options.currentName || Info.name;
const { const {noCurrent, refresh} = options;
noCurrent,
refresh,
} = options;
if (!refresh && json) if (!refresh && json)
return await createFileTable(json, panel, options); return await createFileTable(json, panel, options);
const position = DOM.getPanelPosition(panel); const position = DOM.getPanelPosition(panel);
const sort = CloudCmd.sort[position]; const sort = CloudCmd.sort[position];
const order = CloudCmd.order[position]; const order = CloudCmd.order[position];
const query = rendy('?sort={{ sort }}&order={{ order }}', { const query = rendy('?sort={{ sort }}&order={{ order }}', {
sort, sort,
order, order,
}); });
const [, newObj] = await RESTful.read(path + query, 'json'); const [, newObj] = await RESTful.read(path + query, 'json');
if (!newObj) if (!newObj)
return; // that's OK, error handled by RESTful // that's OK, error handled by RESTful
return;
options.sort = sort; options.sort = sort;
options.order = order; options.order = order;
await createFileTable(newObj, panel, options); await createFileTable(newObj, panel, options);
if (refresh && !noCurrent) if (refresh && !noCurrent)
DOM.setCurrentByName(name); DOM.setCurrentByName(name);
if (!CloudCmd.config('dirStorage')) if (!CloudCmd.config('dirStorage'))
return; return;
Storage.setJson(path, newObj); Storage.setJson(path, newObj);
} }
@ -353,69 +349,60 @@ function CloudCmdProto(DOM) {
* @param callback * @param callback
*/ */
async function createFileTable(data, panelParam, options) { async function createFileTable(data, panelParam, options) {
const { const {history, noCurrent} = options;
history,
noCurrent,
} = options;
const names = [ const names = [
'file', 'file',
'path', 'path',
'link', 'link',
'pathLink', 'pathLink',
]; ];
const [ const [error, [file, path, link, pathLink]] = await tryToCatch(Files.get, names);
error,
[file, path, link, pathLink],
] = await tryToCatch(Files.get, names);
if (error) if (error)
return DOM.Dialog.alert(error.responseText); return DOM.Dialog.alert(error.responseText);
const panel = panelParam || DOM.getPanel(); const panel = panelParam || DOM.getPanel();
const {prefix} = CloudCmd; const {prefix} = CloudCmd;
const { const {dir, name} = Info;
dir,
name,
} = Info;
const {childNodes} = panel; const {childNodes} = panel;
let i = childNodes.length; let i = childNodes.length;
while (i--) while (i--)
panel.removeChild(panel.lastChild); panel.removeChild(panel.lastChild);
panel.innerHTML = buildFromJSON({ panel.innerHTML = buildFromJSON({
sort : options.sort, sort: options.sort,
order : options.order, order: options.order,
data, data,
id : panel.id, id: panel.id,
prefix, prefix,
template : { template: {
file, file,
path, path,
pathLink, pathLink,
link, link,
}, },
}); });
Listeners.setOnPanel(panel); Listeners.setOnPanel(panel);
if (!noCurrent) { if (!noCurrent) {
let current; let current;
if (name === '..' && dir !== '/') if (name === '..' && dir !== '/')
current = DOM.getCurrentByName(dir); current = DOM.getCurrentByName(dir);
if (!current) if (!current)
[current] = DOM.getFiles(panel); [current] = DOM.getFiles(panel);
DOM.setCurrentFile(current, { DOM.setCurrentFile(current, {
history, history,
}); });
CloudCmd.emit('active-dir', Info.dirPath); CloudCmd.emit('active-dir', Info.dirPath);
} }
} }
@ -427,20 +414,19 @@ function CloudCmdProto(DOM) {
parentDirPath, parentDirPath,
panel, panel,
} = Info; } = Info;
if (dirPath === parentDirPath) if (dirPath === parentDirPath)
return; return;
const path = parentDirPath; const path = parentDirPath;
await CloudCmd.changeDir(path); await CloudCmd.changeDir(path);
const current = DOM.getCurrentByName(dir); const current = DOM.getCurrentByName(dir);
const [first] = DOM.getFiles(panel); const [first] = DOM.getFiles(panel);
DOM.setCurrentFile(current || first, { DOM.setCurrentFile(current || first, {
history, history,
}); });
}; };
} }

View file

@ -8,10 +8,7 @@ require('../css/columns/name-size.css');
const wraptile = require('wraptile'); const wraptile = require('wraptile');
const load = require('load.js'); const load = require('load.js');
const { const {registerSW, listenSW} = require('./sw/register');
registerSW,
listenSW,
} = require('./sw/register');
const isDev = process.env.NODE_ENV === 'development'; const isDev = process.env.NODE_ENV === 'development';
@ -65,4 +62,3 @@ async function register(config) {
listenSW(sw, 'updatefound', onUpdateFound(config)); listenSW(sw, 'updatefound', onUpdateFound(config));
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const tryToPromiseAll = require('../../common/try-to-promise-all'); const tryToPromiseAll = require('../../common/try-to-promise-all');
const Storage = require('./storage'); const Storage = require('./storage');
const DOM = require('./'); const DOM = require('./');
@ -13,24 +12,25 @@ function BufferProto() {
const CLASS = 'cut-file'; const CLASS = 'cut-file';
const COPY = 'copy'; const COPY = 'copy';
const CUT = 'cut'; const CUT = 'cut';
const Buffer = { const Buffer = {
cut : callIfEnabled.bind(null, cut), cut: callIfEnabled.bind(null, cut),
copy : callIfEnabled.bind(null, copy), copy: callIfEnabled.bind(null, copy),
clear : callIfEnabled.bind(null, clear), clear: callIfEnabled.bind(null, clear),
paste : callIfEnabled.bind(null, paste), paste: callIfEnabled.bind(null, paste),
}; };
function showMessage(msg) { function showMessage(msg) {
DOM.Dialog.alert(msg); DOM.Dialog.alert(msg);
} }
function getNames() { function getNames() {
const files = DOM.getActiveFiles(); const files = DOM.getActiveFiles();
const names = DOM.getFilenames(files); const names = DOM.getFilenames(files);
return names; return names;
} }
function addCutClass() { function addCutClass() {
const files = DOM.getActiveFiles(); const files = DOM.getActiveFiles();
@ -38,7 +38,7 @@ function BufferProto() {
element.classList.add(CLASS); element.classList.add(CLASS);
} }
} }
function rmCutClass() { function rmCutClass() {
const files = DOM.getByClassAll(CLASS); const files = DOM.getByClassAll(CLASS);
@ -46,7 +46,7 @@ function BufferProto() {
element.classList.remove(CLASS); element.classList.remove(CLASS);
} }
} }
function callIfEnabled(callback) { function callIfEnabled(callback) {
const is = CloudCmd.config('buffer'); const is = CloudCmd.config('buffer');
@ -55,7 +55,7 @@ function BufferProto() {
showMessage('Buffer disabled in config!'); showMessage('Buffer disabled in config!');
} }
async function readBuffer() { async function readBuffer() {
const [e, cp, ct] = await tryToPromiseAll([ const [e, cp, ct] = await tryToPromiseAll([
Storage.getJson(COPY), Storage.getJson(COPY),
@ -68,7 +68,7 @@ function BufferProto() {
ct, ct,
]; ];
} }
async function copy() { async function copy() {
const names = getNames(); const names = getNames();
const from = Info.dirPath; const from = Info.dirPath;
@ -84,7 +84,7 @@ function BufferProto() {
names, names,
}); });
} }
async function cut() { async function cut() {
const names = getNames(); const names = getNames();
const from = Info.dirPath; const from = Info.dirPath;
@ -101,14 +101,14 @@ function BufferProto() {
names, names,
}); });
} }
async function clear() { async function clear() {
await Storage.remove(COPY); await Storage.remove(COPY);
await Storage.remove(CUT); await Storage.remove(CUT);
rmCutClass(); rmCutClass();
} }
async function paste() { async function paste() {
const [error, cp, ct] = await readBuffer(); const [error, cp, ct] = await readBuffer();
@ -131,7 +131,6 @@ function BufferProto() {
await clear(); await clear();
} }
return Buffer; return Buffer;
} }

View file

@ -2,19 +2,12 @@
/* global DOM */ /* global DOM */
/* global CloudCmd */ /* global CloudCmd */
const {atob, btoa} = require('../../common/base64'); const {atob, btoa} = require('../../common/base64');
const createElement = require('@cloudcmd/create-element'); const createElement = require('@cloudcmd/create-element');
const { const {encode, decode} = require('../../common/entity');
encode,
decode,
} = require('../../common/entity');
const { const {getTitle, FS} = require('../../common/cloudfunc');
getTitle,
FS,
} = require('../../common/cloudfunc');
let Title; let Title;
@ -23,7 +16,6 @@ const encodeNBSP = (a) => a?.replace('\xa0', ' ');
const decodeNBSP = (a) => a?.replace(' ', '\xa0'); const decodeNBSP = (a) => a?.replace(' ', '\xa0');
module.exports._CURRENT_FILE = CURRENT_FILE; module.exports._CURRENT_FILE = CURRENT_FILE;
/** /**
* set name from current (or param) file * set name from current (or param) file
* *
@ -85,8 +77,8 @@ const parseHrefAttribute = (prefix, attribute) => {
attribute = attribute.replace(RegExp('^' + prefix + FS), ''); attribute = attribute.replace(RegExp('^' + prefix + FS), '');
return decode(decodeNBSP(attribute)); return decode(decodeNBSP(attribute));
}; };
module.exports._parseHrefAttribute = parseHrefAttribute;
module.exports._parseHrefAttribute = parseHrefAttribute;
/** /**
* get current direcotory path * get current direcotory path
*/ */
@ -112,7 +104,8 @@ module.exports.getCurrentPath = (currentFile) => {
* get current direcotory name * get current direcotory name
*/ */
module.exports.getCurrentDirName = () => { module.exports.getCurrentDirName = () => {
const href = DOM.getCurrentDirPath() const href = DOM
.getCurrentDirPath()
.replace(/\/$/, ''); .replace(/\/$/, '');
const substr = href.substr(href, href.lastIndexOf('/')); const substr = href.substr(href, href.lastIndexOf('/'));
@ -158,7 +151,6 @@ module.exports.getCurrentFile = () => {
/** /**
* get current file by name * get current file by name
*/ */
module.exports.getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => { module.exports.getCurrentByName = (name, panel = DOM.CurrentInfo.panel) => {
const dataName = 'js-file-' + btoa(encodeURI(encodeNBSP(name))); const dataName = 'js-file-' + btoa(encodeURI(encodeNBSP(name)));
return DOM.getByDataName(dataName, panel); return DOM.getByDataName(dataName, panel);
@ -205,7 +197,7 @@ module.exports.setCurrentFile = (currentFile, options) => {
name, name,
path, path,
})); }));
/* history could be present /* history could be present
* but it should be false * but it should be false
* to prevent default behavior * to prevent default behavior
@ -274,7 +266,7 @@ module.exports.getCurrentByPosition = ({x, y}) => {
module.exports.isCurrentFile = (currentFile) => { module.exports.isCurrentFile = (currentFile) => {
if (!currentFile) if (!currentFile)
return false; return false;
return DOM.isContainClass(currentFile, CURRENT_FILE); return DOM.isContainClass(currentFile, CURRENT_FILE);
}; };
@ -283,7 +275,6 @@ module.exports.isCurrentFile = (currentFile) => {
* *
* @param name * @param name
*/ */
module.exports.setTitle = (name) => { module.exports.setTitle = (name) => {
if (!Title) if (!Title)
Title = DOM.getByTag('title')[0] || createElement('title', { Title = DOM.getByTag('title')[0] || createElement('title', {
@ -315,10 +306,10 @@ module.exports.isCurrentIsDir = (currentFile) => {
module.exports.getCurrentType = (currentFile) => { module.exports.getCurrentType = (currentFile) => {
const current = currentFile || DOM.getCurrentFile(); const current = currentFile || DOM.getCurrentFile();
const el = DOM.getByDataName('js-type', current); const el = DOM.getByDataName('js-type', current);
const type = el.className const type = el
.className
.split(' ') .split(' ')
.pop(); .pop();
return type; return type;
}; };

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const {create} = require('auto-globals'); const {create} = require('auto-globals');
const wraptile = require('wraptile'); const wraptile = require('wraptile');
const currentFile = require('./current-file'); const currentFile = require('./current-file');
@ -13,10 +11,7 @@ const returns = wraptile(id);
const {_CURRENT_FILE} = currentFile; const {_CURRENT_FILE} = currentFile;
test('current-file: setCurrentName: setAttribute', (t) => { test('current-file: setCurrentName: setAttribute', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM(); global.DOM = getDOM();
global.CloudCmd = getCloudCmd(); global.CloudCmd = getCloudCmd();
@ -35,10 +30,7 @@ test('current-file: setCurrentName: setAttribute', (t) => {
}); });
test('current-file: setCurrentName: setAttribute: cyrillic', (t) => { test('current-file: setCurrentName: setAttribute: cyrillic', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM(); global.DOM = getDOM();
global.CloudCmd = getCloudCmd(); global.CloudCmd = getCloudCmd();
@ -67,10 +59,7 @@ test('current-file: getCurrentName', (t) => {
}); });
test('current-file: emit', (t) => { test('current-file: emit', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
const emit = stub(); const emit = stub();
@ -92,10 +81,7 @@ test('current-file: emit', (t) => {
}); });
test('current-file: setCurrentName: return', (t) => { test('current-file: setCurrentName: return', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
const link = {}; const link = {};
@ -138,28 +124,22 @@ test('current-file: getParentDirPath: result', (t) => {
}); });
test('current-file: isCurrentFile: no', (t) => { test('current-file: isCurrentFile: no', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM(); global.DOM = getDOM();
global.CloudCmd = getCloudCmd(); global.CloudCmd = getCloudCmd();
const result = currentFile.isCurrentFile(); const result = currentFile.isCurrentFile();
global.DOM = DOM; global.DOM = DOM;
global.CloudCmd = CloudCmd; global.CloudCmd = CloudCmd;
t.notOk(result); t.notOk(result);
t.end(); t.end();
}); });
test('current-file: isCurrentFile', (t) => { test('current-file: isCurrentFile', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
const isContainClass = stub(); const isContainClass = stub();
@ -180,10 +160,7 @@ test('current-file: isCurrentFile', (t) => {
}); });
test('current-file: getCurrentType', (t) => { test('current-file: getCurrentType', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM(); global.DOM = getDOM();
global.CloudCmd = getCloudCmd(); global.CloudCmd = getCloudCmd();
@ -206,10 +183,7 @@ test('current-file: getCurrentType', (t) => {
}); });
test('current-file: isCurrentIsDir: getCurrentType', (t) => { test('current-file: isCurrentIsDir: getCurrentType', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM(); global.DOM = getDOM();
global.CloudCmd = getCloudCmd(); global.CloudCmd = getCloudCmd();
@ -228,10 +202,7 @@ test('current-file: isCurrentIsDir: getCurrentType', (t) => {
}); });
test('current-file: isCurrentIsDir: directory', (t) => { test('current-file: isCurrentIsDir: directory', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM({ global.DOM = getDOM({
getCurrentType: stub().returns('directory'), getCurrentType: stub().returns('directory'),
@ -251,10 +222,7 @@ test('current-file: isCurrentIsDir: directory', (t) => {
}); });
test('current-file: isCurrentIsDir: directory-link', (t) => { test('current-file: isCurrentIsDir: directory-link', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM({ global.DOM = getDOM({
getCurrentType: stub().returns('directory-link'), getCurrentType: stub().returns('directory-link'),
@ -274,10 +242,7 @@ test('current-file: isCurrentIsDir: directory-link', (t) => {
}); });
test('current-file: isCurrentIsDir: file', (t) => { test('current-file: isCurrentIsDir: file', (t) => {
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
global.DOM = getDOM({ global.DOM = getDOM({
getCurrentType: stub().returns('file'), getCurrentType: stub().returns('file'),
@ -320,15 +285,7 @@ test('current-file: parseHrefAttribute', (t) => {
t.end(); t.end();
}); });
function getDOM({ function getDOM({link = {}, getCurrentDirPath = stub(), getCurrentDirName = stub(), getByDataName = stub(), isContainClass = stub(), getCurrentType = stub(), getCurrentPath = stub()} = {}) {
link = {},
getCurrentDirPath = stub(),
getCurrentDirName = stub(),
getByDataName = stub(),
isContainClass = stub(),
getCurrentType = stub(),
getCurrentPath = stub(),
} = {}) {
return { return {
getCurrentDirPath, getCurrentDirPath,
getCurrentDirName, getCurrentDirName,
@ -342,4 +299,3 @@ function getDOM({
}, },
}; };
} }

View file

@ -24,4 +24,3 @@ module.exports.alert.noFiles = () => {
cancel: false, cancel: false,
}); });
}; };

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const philip = require('philip'); const philip = require('philip');
const Images = require('./images'); const Images = require('./images');
@ -15,11 +14,12 @@ module.exports = (items) => {
if (items.length) if (items.length)
Images.show('top'); 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 dirPath = getPathWhenRootEmpty();
const path = dirPath const path = dirPath.replace(/\/$/, '');
.replace(/\/$/, '');
const progress = Dialog.progress('Uploading...'); const progress = Dialog.progress('Uploading...');
@ -74,4 +74,3 @@ function uploadFile(url, data) {
function uploadDir(url) { function uploadDir(url) {
return DOM.load.put(`${url}?dir`); return DOM.load.put(`${url}?dir`);
} }

View file

@ -18,7 +18,10 @@ const isContainClass = (element, className) => {
throw Error('className could not be empty!'); throw Error('className could not be empty!');
if (Array.isArray(className)) if (Array.isArray(className))
return className.some(currify(isContainClass, element)); return className.some(currify(
isContainClass,
element,
));
const {classList} = element; const {classList} = element;
@ -26,7 +29,6 @@ const isContainClass = (element, className) => {
}; };
module.exports.isContainClass = isContainClass; module.exports.isContainClass = isContainClass;
/** /**
* Function search element by tag * Function search element by tag
* @param tag - className * @param tag - className
@ -79,4 +81,3 @@ module.exports.show = (element) => {
element.classList.remove('hidden'); element.classList.remove('hidden');
return DOM; return DOM;
}; };

View file

@ -36,13 +36,8 @@ test('dom: isContainClass: contains: array', (t) => {
const {contains} = el.classList; const {contains} = el.classList;
const className = 'hello'; const className = 'hello';
isContainClass(el, [ isContainClass(el, ['world', className, 'hello']);
'world',
className,
'hello',
]);
t.calledWith(contains, [className], 'should call contains'); t.calledWith(contains, [className], 'should call contains');
t.end(); t.end();
}); });

View file

@ -15,4 +15,3 @@ module.exports.clear = () => {
}; };
module.exports.get = () => list; module.exports.get = () => list;

View file

@ -10,8 +10,13 @@ test('event-store: get', (t) => {
eventStore.add(el, name, fn); eventStore.add(el, name, fn);
const result = eventStore.get(); const result = eventStore.get();
const expected = [ const expected = [
[el, name, fn], [
el,
name,
fn,
],
]; ];
t.deepEqual(result, expected); t.deepEqual(result, expected);

View file

@ -11,7 +11,7 @@ function EventsProto() {
const getEventOptions = (eventName) => { const getEventOptions = (eventName) => {
if (eventName !== 'touchstart') if (eventName !== 'touchstart')
return false; return false;
return { return {
passive: true, passive: true,
}; };
@ -35,12 +35,7 @@ function EventsProto() {
if (!type.endsWith('element')) if (!type.endsWith('element'))
throw Error(`unknown eventName: ${type}`); throw Error(`unknown eventName: ${type}`);
parseArgs( parseArgs(args[EVENT_NAME], args[ELEMENT], listener, callback);
args[EVENT_NAME],
args[ELEMENT],
listener,
callback,
);
break; break;
case 'string': case 'string':
@ -62,33 +57,25 @@ function EventsProto() {
break; break;
case 'array': case 'array':
for (const name of eventName) { for (const name of eventName) {
parseArgs( parseArgs(name, element, listener, callback);
name,
element,
listener,
callback,
);
} }
break; break;
case 'object': case 'object':
for (const name of Object.keys(eventName)) { for (const name of Object.keys(eventName)) {
const eventListener = eventName[name]; const eventListener = eventName[name];
parseArgs( parseArgs(name, element, eventListener, callback);
name,
element,
eventListener,
callback,
);
} }
break; break;
} }
} }
/** /**
* safe add event listener * safe add event listener
* *
@ -108,7 +95,7 @@ function EventsProto() {
return Events; return Events;
}; };
/** /**
* safe add event listener * safe add event listener
* *
@ -131,7 +118,7 @@ function EventsProto() {
return Events; return Events;
}; };
/** /**
* safe remove event listener * safe remove event listener
* *
@ -148,7 +135,7 @@ function EventsProto() {
return Events; return Events;
}; };
/** /**
* remove all added event listeners * remove all added event listeners
* *
@ -162,7 +149,7 @@ function EventsProto() {
EventStore.clear(); EventStore.clear();
}; };
/** /**
* safe add event keydown listener * safe add event keydown listener
* *
@ -170,11 +157,14 @@ function EventsProto() {
*/ */
this.addKey = function(...argsArr) { this.addKey = function(...argsArr) {
const name = 'keydown'; const name = 'keydown';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.add(...args); return Events.add(...args);
}; };
/** /**
* safe remove event click listener * safe remove event click listener
* *
@ -182,11 +172,14 @@ function EventsProto() {
*/ */
this.rmKey = function(...argsArr) { this.rmKey = function(...argsArr) {
const name = 'keydown'; const name = 'keydown';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.remove(...args); return Events.remove(...args);
}; };
/** /**
* safe add event click listener * safe add event click listener
* *
@ -194,11 +187,14 @@ function EventsProto() {
*/ */
this.addClick = function(...argsArr) { this.addClick = function(...argsArr) {
const name = 'click'; const name = 'click';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.add(...args); return Events.add(...args);
}; };
/** /**
* safe remove event click listener * safe remove event click listener
* *
@ -206,18 +202,24 @@ function EventsProto() {
*/ */
this.rmClick = function(...argsArr) { this.rmClick = function(...argsArr) {
const name = 'click'; const name = 'click';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.remove(...args); return Events.remove(...args);
}; };
this.addContextMenu = function(...argsArr) { this.addContextMenu = function(...argsArr) {
const name = 'contextmenu'; const name = 'contextmenu';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.add(...args); return Events.add(...args);
}; };
/** /**
* safe add event click listener * safe add event click listener
* *
@ -225,11 +227,14 @@ function EventsProto() {
*/ */
this.addError = function(...argsArr) { this.addError = function(...argsArr) {
const name = 'error'; const name = 'error';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.add(...args); return Events.add(...args);
}; };
/** /**
* safe add load click listener * safe add load click listener
* *
@ -237,7 +242,10 @@ function EventsProto() {
*/ */
this.addLoad = function(...argsArr) { this.addLoad = function(...argsArr) {
const name = 'load'; const name = 'load';
const args = [name, ...argsArr]; const args = [
name,
...argsArr,
];
return Events.add(...args); return Events.add(...args);
}; };
@ -247,4 +255,3 @@ function EventsProto() {
throw Error('type could not be empty!'); throw Error('type could not be empty!');
} }
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const itype = require('itype'); const itype = require('itype');
const {promisify} = require('es6-promisify'); const {promisify} = require('es6-promisify');
@ -49,6 +48,7 @@ function getModule(name) {
return getConfig(); return getConfig();
const path = getPath(name, isHTML, isJSON); const path = getPath(name, isHTML, isJSON);
return getSystemFile(path); return getSystemFile(path);
} }
@ -137,4 +137,3 @@ function getTimeoutOnce(time) {
}, time); }, time);
}; };
} }

View file

@ -15,7 +15,6 @@ function getLoadingType() {
} }
module.exports.get = getElement; module.exports.get = getElement;
/** /**
* check SVG SMIL animation support * check SVG SMIL animation support
*/ */
@ -69,7 +68,6 @@ module.exports.error = () => {
module.exports.show = show; module.exports.show = show;
module.exports.show.load = show; module.exports.show.load = show;
module.exports.show.error = error; module.exports.show.error = error;
/** /**
* Function shows loading spinner * Function shows loading spinner
* position = {top: true}; * position = {top: true};
@ -147,4 +145,3 @@ module.exports.clearProgress = () => {
return Images; return Images;
}; };

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const Util = require('../../common/util'); const Util = require('../../common/util');
const Images = require('./images'); const Images = require('./images');
@ -41,8 +40,8 @@ const selectByPattern = require('./select-by-pattern');
const SELECTED_FILE = 'selected-file'; const SELECTED_FILE = 'selected-file';
const TabPanel = { const TabPanel = {
'js-left' : null, 'js-left': null,
'js-right' : null, 'js-right': null,
}; };
module.exports.loadRemote = (name, options, callback) => { module.exports.loadRemote = (name, options, callback) => {
@ -52,7 +51,7 @@ module.exports.loadRemote = (name, options, callback) => {
module.exports.loadSocket = (callback) => { module.exports.loadSocket = (callback) => {
DOM.loadRemote('socket', { DOM.loadRemote('socket', {
name : 'io', name: 'io',
}, callback); }, callback);
return DOM; return DOM;
@ -80,6 +79,7 @@ async function promptNew(typeName) {
const {Dialog} = DOM; const {Dialog} = DOM;
const dir = DOM.getCurrentDirPath(); const dir = DOM.getCurrentDirPath();
const msg = `New ${typeName}` || 'File'; const msg = `New ${typeName}` || 'File';
const getName = () => { const getName = () => {
const name = DOM.getCurrentName(); const name = DOM.getCurrentName();
@ -111,11 +111,12 @@ async function promptNew(typeName) {
* get current direcotory name * get current direcotory name
*/ */
module.exports.getCurrentDirName = () => { module.exports.getCurrentDirName = () => {
const href = DOM.getCurrentDirPath() const href = DOM
.getCurrentDirPath()
.replace(/\/$/, ''); .replace(/\/$/, '');
const substr = href.substr(href, href.lastIndexOf('/')); const substr = href.substr(href, href.lastIndexOf('/'));
const ret = href.replace(`${substr}/`, '') || '/'; const ret = href.replace(`${substr}/`, '') || '/';
return ret; return ret;
}; };
@ -138,7 +139,9 @@ module.exports.getParentDirPath = (panel) => {
* get not current direcotory path * get not current direcotory path
*/ */
module.exports.getNotCurrentDirPath = () => { module.exports.getNotCurrentDirPath = () => {
const panel = DOM.getPanel({active: false}); const panel = DOM.getPanel({
active: false,
});
const path = DOM.getCurrentDirPath(panel); const path = DOM.getCurrentDirPath(panel);
return path; return path;
@ -162,7 +165,9 @@ module.exports.getSelectedFiles = () => {
module.exports.unselectFiles = (files) => { module.exports.unselectFiles = (files) => {
files = files || DOM.getSelectedFiles(); 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) => { module.exports.getCurrentDate = (currentFile) => {
const current = currentFile || DOM.getCurrentFile(); const current = currentFile || DOM.getCurrentFile();
const date = DOM const date = DOM.getByDataName('js-date', current).textContent;
.getByDataName('js-date', current)
.textContent;
return date; return date;
}; };
@ -196,8 +199,10 @@ module.exports.getCurrentDate = (currentFile) => {
*/ */
module.exports.getCurrentSize = (currentFile) => { module.exports.getCurrentSize = (currentFile) => {
const current = currentFile || DOM.getCurrentFile(); const current = currentFile || DOM.getCurrentFile();
/* если это папка - возвращаем слово dir вместо размера*/ /* если это папка - возвращаем слово dir вместо размера*/
const size = DOM.getByDataName('js-size', current) const size = DOM
.getByDataName('js-size', current)
.textContent .textContent
.replace(/^<|>$/g, ''); .replace(/^<|>$/g, '');
@ -237,6 +242,7 @@ module.exports.loadCurrentHash = async (currentFile) => {
const link = DOM.getCurrentPath(current); const link = DOM.getCurrentPath(current);
const [, data] = await RESTful.read(link + query); const [, data] = await RESTful.read(link + query);
return data; return data;
}; };
@ -285,7 +291,9 @@ module.exports.getCurrentData = async (currentFile) => {
if (Info.name === '..') { if (Info.name === '..') {
Dialog.alert.noFiles(); Dialog.alert.noFiles();
return [Error('No Files')]; return [
Error('No Files'),
];
} }
if (isDir) if (isDir)
@ -294,7 +302,9 @@ module.exports.getCurrentData = async (currentFile) => {
const [hashNew, hash] = await DOM.checkStorageHash(path); const [hashNew, hash] = await DOM.checkStorageHash(path);
if (!hashNew) if (!hashNew)
return [Error(`Can't get hash of a file`)]; return [
Error(`Can't get hash of a file`),
];
if (hash === hashNew) if (hash === hashNew)
return [null, await Storage.get(`${path}-data`)]; return [null, await Storage.get(`${path}-data`)];
@ -302,7 +312,10 @@ module.exports.getCurrentData = async (currentFile) => {
const [e, data] = await RESTful.read(path); const [e, data] = await RESTful.read(path);
if (e) if (e)
return [e, null]; return [
e,
null,
];
const ONE_MEGABYTE = 1024 ** 2 * 1024; const ONE_MEGABYTE = 1024 ** 2 * 1024;
const {length} = data; const {length} = data;
@ -353,13 +366,17 @@ module.exports.toggleSelectedFile = (currentFile) => {
}; };
module.exports.toggleAllSelectedFiles = () => { module.exports.toggleAllSelectedFiles = () => {
DOM.getAllFiles().map(DOM.toggleSelectedFile); DOM
.getAllFiles()
.map(DOM.toggleSelectedFile);
return Cmd; return Cmd;
}; };
module.exports.selectAllFiles = () => { module.exports.selectAllFiles = () => {
DOM.getAllFiles().map(DOM.selectFile); DOM
.getAllFiles()
.map(DOM.selectFile);
return Cmd; return Cmd;
}; };
@ -372,7 +389,9 @@ module.exports.getAllFiles = () => {
const from = (a) => a === '..' ? 1 : 0; const from = (a) => a === '..' ? 1 : 0;
const i = from(name); 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) => { module.exports.isSelected = (selected) => {
if (!selected) if (!selected)
return false; return false;
return DOM.isContainClass(selected, SELECTED_FILE); return DOM.isContainClass(selected, SELECTED_FILE);
}; };
@ -550,7 +569,9 @@ module.exports.getFiles = (element) => {
* shows panel right or left (or active) * shows panel right or left (or active)
*/ */
module.exports.showPanel = (active) => { module.exports.showPanel = (active) => {
const panel = DOM.getPanel({active}); const panel = DOM.getPanel({
active,
});
if (!panel) if (!panel)
return false; return false;
@ -627,7 +648,6 @@ module.exports.deleteSelected = (selected) => {
* @currentFile * @currentFile
*/ */
module.exports.renameCurrent = renameCurrent; module.exports.renameCurrent = renameCurrent;
/** /**
* unified way to scrollIntoViewIfNeeded * unified way to scrollIntoViewIfNeeded
* (native suporte by webkit only) * (native suporte by webkit only)
@ -702,7 +722,7 @@ module.exports.changePanel = () => {
module.exports.getPackerExt = (type) => { module.exports.getPackerExt = (type) => {
if (type === 'zip') if (type === 'zip')
return '.zip'; return '.zip';
return '.tar.gz'; return '.tar.gz';
}; };
@ -711,10 +731,7 @@ module.exports.goToDirectory = async () => {
const {Dialog} = DOM; const {Dialog} = DOM;
const {dirPath} = CurrentInfo; const {dirPath} = CurrentInfo;
const [ const [cancel, path = dirPath] = await Dialog.prompt(msg, dirPath);
cancel,
path = dirPath,
] = await Dialog.prompt(msg, dirPath);
if (cancel) if (cancel)
return; return;
@ -731,7 +748,7 @@ module.exports.duplicatePanel = async () => {
const getPath = (isDir) => { const getPath = (isDir) => {
if (isDir) if (isDir)
return Info.path; return Info.path;
return Info.dirPath; return Info.dirPath;
}; };
@ -790,26 +807,29 @@ module.exports.updateCurrentInfo = (currentFile) => {
const filesPassive = DOM.getFiles(panelPassive); const filesPassive = DOM.getFiles(panelPassive);
const name = DOM.getCurrentName(current); const name = DOM.getCurrentName(current);
info.dir = DOM.getCurrentDirName(); info.dir = DOM.getCurrentDirName();
info.dirPath = DOM.getCurrentDirPath(); info.dirPath = DOM.getCurrentDirPath();
info.parentDirPath = DOM.getParentDirPath(); info.parentDirPath = DOM.getParentDirPath();
info.element = current; info.element = current;
info.ext = Util.getExt(name); info.ext = Util.getExt(name);
info.files = Array.from(files.children); info.files = Array.from(files.children);
info.filesPassive = Array.from(filesPassive); info.filesPassive = Array.from(filesPassive);
info.first = files.firstChild; info.first = files.firstChild;
info.getData = DOM.getCurrentData; info.getData = DOM.getCurrentData;
info.last = files.lastChild; info.last = files.lastChild;
info.link = DOM.getCurrentLink(current); info.link = DOM.getCurrentLink(current);
info.mode = DOM.getCurrentMode(current); info.mode = DOM.getCurrentMode(current);
info.name = name; info.name = name;
info.path = DOM.getCurrentPath(current); info.path = DOM.getCurrentPath(current);
info.panel = files.parentElement || DOM.getPanel(); info.panel = files.parentElement || DOM.getPanel();
info.panelPassive = panelPassive; info.panelPassive = panelPassive;
info.size = DOM.getCurrentSize(current); info.size = DOM.getCurrentSize(current);
info.isDir = DOM.isCurrentIsDir(); info.isDir = DOM.isCurrentIsDir();
info.isSelected = DOM.isSelected(current); info.isSelected = DOM.isSelected(current);
info.panelPosition = DOM.getPanel().dataset.name.replace('js-', ''); info.panelPosition = DOM
info.isOnePanel = info.panel.getAttribute('data-name') === .getPanel()
info.panelPassive.getAttribute('data-name'); .dataset
.name
.replace('js-', '');
info.isOnePanel = info.panel.getAttribute('data-name') === info.panelPassive.getAttribute('data-name');
}; };

View file

@ -29,4 +29,3 @@ test('cloudcmd: client: dom: goToDirectory', async (t) => {
t.calledWith(changeDir, [path]); t.calledWith(changeDir, [path]);
t.end(); t.end();
}); });

View file

@ -9,10 +9,10 @@ const imgPosition = {
module.exports.delete = async (url, data) => { module.exports.delete = async (url, data) => {
return await sendRequest({ return await sendRequest({
method : 'DELETE', method: 'DELETE',
url : FS + url, url: FS + url,
data, data,
imgPosition : { imgPosition: {
top: Boolean(data), top: Boolean(data),
}, },
}); });
@ -149,4 +149,3 @@ module.exports.Markdown = {
}); });
}, },
}; };

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const mockRequire = require('mock-require'); const mockRequire = require('mock-require');
const {reRequire, stopAll} = mockRequire; const {reRequire, stopAll} = mockRequire;

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const {promisify} = require('es6-promisify'); const {promisify} = require('es6-promisify');
const Images = require('../images'); const Images = require('../images');
@ -17,17 +16,14 @@ module.exports = promisify((params, callback) => {
p.url = replaceHash(p.url); p.url = replaceHash(p.url);
load.ajax({ load.ajax({
method : p.method, method: p.method,
url : p.url, url: p.url,
data : p.data, data: p.data,
dataType : p.dataType, dataType: p.dataType,
error : (jqXHR) => { error: (jqXHR) => {
const response = jqXHR.responseText; const response = jqXHR.responseText;
const { const {statusText, status} = jqXHR;
statusText,
status,
} = jqXHR;
const text = status === 404 ? response : statusText; const text = status === 404 ? response : statusText;
@ -52,4 +48,3 @@ function replaceHash(url) {
*/ */
return url.replace(/#/g, '%23'); return url.replace(/#/g, '%23');
} }

View file

@ -11,4 +11,3 @@ test('cloudcmd: client: io: replaceHash', (t) => {
t.equal(result, expected); t.equal(result, expected);
t.end(); t.end();
}); });

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const rendy = require('rendy'); const rendy = require('rendy');
const itype = require('itype'); const itype = require('itype');
const load = require('load.js'); const load = require('load.js');
@ -18,41 +17,42 @@ module.exports = (name, options, callback = options) => {
if (o.name && window[o.name]) if (o.name && window[o.name])
return callback(); return callback();
Files.get('modules').then(async (modules) => { Files
const online = config('online') && navigator.onLine; .get('modules')
const module = findObjByNameInArr(modules.remote, name); .then(async (modules) => {
const online = config('online') && navigator.onLine;
const module = findObjByNameInArr(modules.remote, name);
const isArray = itype.array(module.local); const isArray = itype.array(module.local);
const {version} = module; const {version} = module;
let remoteTmpls; let remoteTmpls;
let local; let local;
if (isArray) { if (isArray) {
remoteTmpls = module.remote; remoteTmpls = module.remote;
local = module.local; local = module.local;
} else { } else {
remoteTmpls = [module.remote]; remoteTmpls = [module.remote];
local = [module.local]; local = [module.local];
} }
const localURL = local.map((url) => prefix + url); const localURL = local.map((url) => prefix + url);
const remoteURL = remoteTmpls.map((tmpl) => { const remoteURL = remoteTmpls.map((tmpl) => {
return rendy(tmpl, { return rendy(tmpl, {
version, version,
});
}); });
});
if (online) { if (online) {
const [e] = await tryToCatch(load.parallel, remoteURL); const [e] = await tryToCatch(load.parallel, remoteURL);
if (!e) if (!e)
return callback(); return callback();
} }
const [e] = await tryToCatch(load.parallel, localURL); const [e] = await tryToCatch(load.parallel, localURL);
callback(e); callback(e);
}); });
}; };

View file

@ -7,7 +7,6 @@ const exec = require('execon');
const Images = require('./images'); const Images = require('./images');
module.exports.getIdBySrc = getIdBySrc; module.exports.getIdBySrc = getIdBySrc;
/** /**
* Function gets id by src * Function gets id by src
* @param src * @param src
@ -25,6 +24,7 @@ function getIdBySrc(src) {
const num = src.lastIndexOf('/') + 1; const num = src.lastIndexOf('/') + 1;
const sub = src.substr(src, num); const sub = src.substr(src, num);
const id = src const id = src
.replace(sub, '') .replace(sub, '')
.replace(/\./g, '-'); .replace(/\./g, '-');
@ -43,9 +43,9 @@ module.exports.ajax = (params) => {
const isArray = itype.array(p.data); const isArray = itype.array(p.data);
const isArrayBuf = itype(p.data) === 'arraybuffer'; const isArrayBuf = itype(p.data) === 'arraybuffer';
const type = p.type || p.method || 'GET'; const type = p.type || p.method || 'GET';
const {
headers = {}, const {headers = {}} = p;
} = p;
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open(type, p.url, true); xhr.open(type, p.url, true);
@ -98,8 +98,7 @@ module.exports.put = (url, body) => {
const emitter = Emitify(); const emitter = Emitify();
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
url = encodeURI(url) url = encodeURI(url).replace(/#/g, '%23');
.replace(/#/g, '%23');
xhr.open('put', url, true); xhr.open('put', url, true);
@ -133,4 +132,3 @@ module.exports.put = (url, body) => {
return emitter; return emitter;
}; };

View file

@ -1,12 +1,12 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const capitalize = require('just-capitalize'); const capitalize = require('just-capitalize');
const Dialog = require('../dialog'); const Dialog = require('../dialog');
const Storage = require('../storage'); const Storage = require('../storage');
const RESTful = require('../rest'); const RESTful = require('../rest');
const { const {
isCurrentFile, isCurrentFile,
getCurrentName, getCurrentName,
@ -60,4 +60,3 @@ module.exports = async (current) => {
Storage.remove(dirPath); Storage.remove(dirPath);
CloudCmd.refresh(); CloudCmd.refresh();
}; };

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const mockRequire = require('mock-require'); const mockRequire = require('mock-require');
const {reRequire, stopAll} = mockRequire; const {reRequire, stopAll} = mockRequire;
@ -55,6 +53,7 @@ test('cloudcmd: client: dom: renameCurrent: file exist', async (t) => {
await renameCurrent(); await renameCurrent();
const expected = 'Directory "hello" already exists. Proceed?'; const expected = 'Directory "hello" already exists. Proceed?';
global.CloudCmd = CloudCmd; global.CloudCmd = CloudCmd;
stopAll(); stopAll();
@ -98,4 +97,3 @@ const stubCurrentFile = (fns = {}) => {
setCurrentName, setCurrentName,
}; };
}; };

View file

@ -42,4 +42,3 @@ module.exports.Markdown = {
read: handleError(IO.Markdown.read), read: handleError(IO.Markdown.read),
render: handleError(IO.Markdown.render), render: handleError(IO.Markdown.render),
}; };

View file

@ -3,10 +3,7 @@
let SelectType = '*.*'; let SelectType = '*.*';
const {getRegExp} = require('../../common/util'); const {getRegExp} = require('../../common/util');
const { const {alert, prompt} = require('./dialog');
alert,
prompt,
} = require('./dialog');
const DOM = require('.'); const DOM = require('.');
@ -15,8 +12,6 @@ module.exports = async (msg, files) => {
return; return;
const allMsg = `Specify file type for ${msg} selection`; const allMsg = `Specify file type for ${msg} selection`;
/* eslint require-atomic-updates: 0 */
const [cancel, type] = await prompt(allMsg, SelectType); const [cancel, type] = await prompt(allMsg, SelectType);
if (cancel) if (cancel)
@ -48,4 +43,3 @@ module.exports = async (msg, files) => {
if (!matches) if (!matches)
alert('No matches found!'); alert('No matches found!');
}; };

View file

@ -26,4 +26,3 @@ module.exports.clear = () => {
module.exports.remove = (item) => { module.exports.remove = (item) => {
localStorage.removeItem(item); localStorage.removeItem(item);
}; };

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const storage = require('./storage'); const storage = require('./storage');
const {stringify} = JSON; const {stringify} = JSON;
@ -32,6 +30,7 @@ test('cloudcmd: client: storage: get', async (t) => {
}; };
const result = await storage.get('hello'); const result = await storage.get('hello');
global.localStorage = localStorage; global.localStorage = localStorage;
t.equal(result, 'world'); t.equal(result, 'world');
@ -43,6 +42,7 @@ test('cloudcmd: client: storage: getJson', async (t) => {
const expected = { const expected = {
hello: 'world', hello: 'world',
}; };
const getItem = stub().returns(stringify(expected)); const getItem = stub().returns(stringify(expected));
global.localStorage = { global.localStorage = {
@ -50,6 +50,7 @@ test('cloudcmd: client: storage: getJson', async (t) => {
}; };
const result = await storage.getJson('hello'); const result = await storage.getJson('hello');
global.localStorage = localStorage; global.localStorage = localStorage;
t.deepEqual(result, expected); t.deepEqual(result, expected);
@ -105,4 +106,3 @@ test('cloudcmd: client: storage: clear', async (t) => {
t.ok(clear.calledWith(), 'should call clear'); t.ok(clear.calledWith(), 'should call clear');
t.end(); t.end();
}); });

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const {eachSeries} = require('execon'); const {eachSeries} = require('execon');
const wraptile = require('wraptile'); const wraptile = require('wraptile');
@ -55,13 +54,14 @@ function _loadFile(dir, n, file, callback) {
++i; ++i;
load.put(api + path, file) load
.put(api + path, file)
.on('error', showError) .on('error', showError)
.on('end', callback) .on('end', callback)
.on('progress', (count) => { .on('progress', (count) => {
const max = step(n); const max = step(n);
const value = (i - 1) * max + percent(count, 100, max); const value = (i - 1) * max + percent(count, 100, max);
Images.show.load('top'); Images.show.load('top');
Images.setProgress(Math.round(value)); Images.setProgress(Math.round(value));
}); });
@ -70,4 +70,3 @@ function _loadFile(dir, n, file, callback) {
function showError({message}) { function showError({message}) {
alert(message); alert(message);
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global DOM */ /* global DOM */
const Info = DOM.CurrentInfo; const Info = DOM.CurrentInfo;
/** /**
@ -46,4 +45,3 @@ module.exports = () => {
return fileTable; return fileTable;
}; };

View file

@ -15,4 +15,3 @@ module.exports.createBinder = () => {
}, },
}; };
}; };

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd, DOM */ /* global CloudCmd, DOM */
const clipboard = require('@cloudcmd/clipboard'); const clipboard = require('@cloudcmd/clipboard');
const Buffer = require('../dom/buffer'); const Buffer = require('../dom/buffer');
@ -32,6 +31,7 @@ Chars([]);
const {assign} = Object; const {assign} = Object;
const binder = createBinder(); const binder = createBinder();
module.exports = assign(binder, KEY); module.exports = assign(binder, KEY);
module.exports.bind = () => { module.exports.bind = () => {
Events.addKey(listener, true); Events.addKey(listener, true);
@ -45,13 +45,13 @@ function getChar(event) {
* event.keyIdentifier deprecated in chrome v51 * event.keyIdentifier deprecated in chrome v51
* but event.key is absent in chrome <= v51 * but event.key is absent in chrome <= v51
*/ */
const { const {
key, key,
shift, shift,
keyCode, keyCode,
keyIdentifier, keyIdentifier,
} = event; } = event;
const char = key || fromCharCode(keyIdentifier); const char = key || fromCharCode(keyIdentifier);
const symbol = getSymbol(shift, keyCode); const symbol = getSymbol(shift, keyCode);
@ -136,6 +136,7 @@ async function switchKey(event) {
changeDir, changeDir,
config, config,
} = CloudCmd; } = CloudCmd;
const {keyCode} = event; const {keyCode} = event;
const alt = event.altKey; const alt = event.altKey;
@ -156,12 +157,14 @@ async function switchKey(event) {
break; break;
case KEY.INSERT: case KEY.INSERT:
DOM .toggleSelectedFile(current) DOM
.toggleSelectedFile(current)
.setCurrentFile(next); .setCurrentFile(next);
break; break;
case KEY.INSERT_MAC: case KEY.INSERT_MAC:
DOM .toggleSelectedFile(current) DOM
.toggleSelectedFile(current)
.setCurrentFile(next); .setCurrentFile(next);
break; break;
@ -170,7 +173,7 @@ async function switchKey(event) {
Operation.show('delete:silent'); Operation.show('delete:silent');
else else
Operation.show('delete'); Operation.show('delete');
break; break;
case KEY.ASTERISK: case KEY.ASTERISK:
@ -305,7 +308,7 @@ async function switchKey(event) {
DOM.swapPanels(); DOM.swapPanels();
event.preventDefault(); event.preventDefault();
} }
break; break;
/* navigation on file table: * /* navigation on file table: *
@ -403,7 +406,7 @@ async function switchKey(event) {
await changeDir(path); await changeDir(path);
else else
CloudCmd.View.show(); CloudCmd.View.show();
break; break;
case KEY.BACKSPACE: case KEY.BACKSPACE:
@ -414,7 +417,7 @@ async function switchKey(event) {
case KEY.BACKSLASH: case KEY.BACKSLASH:
if (ctrlMeta) if (ctrlMeta)
await changeDir('/'); await changeDir('/');
break; break;
case KEY.A: case KEY.A:
@ -455,6 +458,7 @@ async function switchKey(event) {
.catch(CloudCmd.log); .catch(CloudCmd.log);
break; break;
/** /**
* обновляем страницу, * обновляем страницу,
* загружаем содержимое каталога * загружаем содержимое каталога
@ -468,31 +472,31 @@ async function switchKey(event) {
CloudCmd.refresh(); CloudCmd.refresh();
event.preventDefault(); event.preventDefault();
} }
break; break;
case KEY.C: case KEY.C:
if (ctrlMeta) if (ctrlMeta)
Buffer.copy(); Buffer.copy();
break; break;
case KEY.X: case KEY.X:
if (ctrlMeta) if (ctrlMeta)
Buffer.cut(); Buffer.cut();
break; break;
case KEY.V: case KEY.V:
if (ctrlMeta) if (ctrlMeta)
Buffer.paste(); Buffer.paste();
break; break;
case KEY.Z: case KEY.Z:
if (ctrlMeta) if (ctrlMeta)
Buffer.clear(); Buffer.clear();
break; break;
case KEY.COLON: case KEY.COLON:
@ -508,8 +512,7 @@ async function switchKey(event) {
CloudCmd.log('storage cleared'); CloudCmd.log('storage cleared');
event.preventDefault(); event.preventDefault();
} }
break; break;
} }
} }

View file

@ -4,10 +4,8 @@ const autoGlobals = require('auto-globals');
const stub = require('@cloudcmd/stub'); const stub = require('@cloudcmd/stub');
const mockRequire = require('mock-require'); const mockRequire = require('mock-require');
const {ESC} = require('./key'); const {ESC} = require('./key');
const {
getDOM, const {getDOM, getCloudCmd} = require('./vim/globals.fixture');
getCloudCmd,
} = require('./vim/globals.fixture');
const {reRequire, stopAll} = mockRequire; const {reRequire, stopAll} = mockRequire;
@ -66,4 +64,3 @@ test('cloudcmd: client: key: disable vim', async (t) => {
t.calledWith(_config, ['vim']); t.calledWith(_config, ['vim']);
t.end(); t.end();
}); });

View file

@ -1,81 +1,81 @@
'use strict'; 'use strict';
module.exports = { module.exports = {
BACKSPACE : 8, BACKSPACE: 8,
TAB : 9, TAB: 9,
ENTER : 13, ENTER: 13,
CAPSLOCK : 20, CAPSLOCK: 20,
ESC : 27, ESC: 27,
SPACE : 32, SPACE: 32,
PAGE_UP : 33, PAGE_UP: 33,
PAGE_DOWN : 34, PAGE_DOWN: 34,
END : 35, END: 35,
HOME : 36, HOME: 36,
LEFT : 37, LEFT: 37,
UP : 38, UP: 38,
RIGHT : 39, RIGHT: 39,
DOWN : 40, DOWN: 40,
INSERT : 45, INSERT: 45,
DELETE : 46, DELETE: 46,
ZERO : 48, ZERO: 48,
SEMICOLON : 52, SEMICOLON: 52,
A : 65, A: 65,
C : 67, C: 67,
D : 68, D: 68,
G : 71, G: 71,
J : 74, J: 74,
K : 75, K: 75,
M : 77, M: 77,
O : 79, O: 79,
P : 80, P: 80,
Q : 81, Q: 81,
R : 82, R: 82,
S : 83, S: 83,
T : 84, T: 84,
U : 85, U: 85,
V : 86, V: 86,
X : 88, X: 88,
Z : 90, Z: 90,
INSERT_MAC : 96, INSERT_MAC: 96,
ASTERISK : 106, ASTERISK: 106,
PLUS : 107, PLUS: 107,
MINUS : 109, MINUS: 109,
F1 : 112, F1: 112,
F2 : 113, F2: 113,
F3 : 114, F3: 114,
F4 : 115, F4: 115,
F5 : 116, F5: 116,
F6 : 117, F6: 117,
F7 : 118, F7: 118,
F8 : 119, F8: 119,
F9 : 120, F9: 120,
F10 : 121, F10: 121,
COLON : 186, COLON: 186,
EQUAL : 187, EQUAL: 187,
HYPHEN : 189, HYPHEN: 189,
DOT : 190, DOT: 190,
SLASH : 191, SLASH: 191,
TRA : 192, /* Typewritten Reverse Apostrophe (`) */ /* Typewritten Reverse Apostrophe (`) */
BACKSLASH : 220, TRA: 192,
BACKSLASH: 220,
BRACKET_CLOSE: 221, BRACKET_CLOSE: 221,
}; };

View file

@ -31,6 +31,7 @@ module.exports = function setCurrentByChar(char, charStore) {
const isTest = (a) => regExp.test(a); const isTest = (a) => regExp.test(a);
const isRoot = (a) => a === '..'; const isRoot = (a) => a === '..';
const not = (f) => (a) => !f(a); const not = (f) => (a) => !f(a);
const setCurrent = (name) => { const setCurrent = (name) => {
const byName = DOM.getCurrentByName(name); const byName = DOM.getCurrentByName(name);
@ -57,4 +58,3 @@ module.exports = function setCurrentByChar(char, charStore) {
charStore([char]); charStore([char]);
} }
}; };

View file

@ -37,14 +37,13 @@ module.exports._previous = previous;
function next(index, length) { function next(index, length) {
if (index === length - 1) if (index === length - 1)
return 0; return 0;
return ++index; return ++index;
} }
function previous(index, length) { function previous(index, length) {
if (!index) if (!index)
return length - 1; return length - 1;
return --index; return --index;
} }

View file

@ -7,10 +7,7 @@ const {getDOM} = require('./globals.fixture');
global.DOM = getDOM(); global.DOM = getDOM();
const { const {_next, _previous} = require(`${dir}find`);
_next,
_previous,
} = require(`${dir}find`);
test('cloudcmd: client: vim: _next', (t) => { test('cloudcmd: client: vim: _next', (t) => {
const result = _next(1, 2); const result = _next(1, 2);
@ -25,4 +22,3 @@ test('cloudcmd: client: vim: _previous', (t) => {
t.equal(result, 1, 'should return 1'); t.equal(result, 1, 'should return 1');
t.end(); t.end();
}); });

View file

@ -38,7 +38,7 @@ module.exports.getCloudCmd = () => {
const show = () => {}; const show = () => {};
return { return {
Operation: { Operation: {
show, show,
}, },
@ -46,4 +46,3 @@ module.exports.getCloudCmd = () => {
_config: noop, _config: noop,
}; };
}; };

View file

@ -2,7 +2,6 @@
/* global CloudCmd */ /* global CloudCmd */
/* global DOM */ /* global DOM */
const vim = require('./vim'); const vim = require('./vim');
const finder = require('./find'); const finder = require('./find');
@ -16,43 +15,43 @@ module.exports = async (key, event) => {
const getOperations = (event) => ({ const getOperations = (event) => ({
escape: DOM.unselectFiles, escape: DOM.unselectFiles,
remove: () => { remove: () => {
CloudCmd.Operation.show('delete'); CloudCmd.Operation.show('delete');
}, },
makeDirectory: () => { makeDirectory: () => {
event.stopImmediatePropagation(); event.stopImmediatePropagation();
event.preventDefault(); event.preventDefault();
DOM.promptNewDir(); DOM.promptNewDir();
}, },
makeFile: () => { makeFile: () => {
event.stopImmediatePropagation(); event.stopImmediatePropagation();
event.preventDefault(); event.preventDefault();
DOM.promptNewFile(); DOM.promptNewFile();
}, },
terminal: () => { terminal: () => {
CloudCmd.Terminal.show(); CloudCmd.Terminal.show();
}, },
edit: () => { edit: () => {
CloudCmd.EditFileVim.show(); CloudCmd.EditFileVim.show();
}, },
copy: () => { copy: () => {
DOM.Buffer.copy(); DOM.Buffer.copy();
DOM.unselectFiles(); DOM.unselectFiles();
}, },
select: () => { select: () => {
const current = Info.element; const current = Info.element;
DOM.toggleSelectedFile(current); DOM.toggleSelectedFile(current);
}, },
paste: DOM.Buffer.paste, paste: DOM.Buffer.paste,
moveNext: ({count, isVisual, isDelete}) => { moveNext: ({count, isVisual, isDelete}) => {
setCurrent('next', { setCurrent('next', {
count, count,
@ -60,7 +59,7 @@ const getOperations = (event) => ({
isDelete, isDelete,
}); });
}, },
movePrevious: ({count, isVisual, isDelete}) => { movePrevious: ({count, isVisual, isDelete}) => {
setCurrent('previous', { setCurrent('previous', {
count, count,
@ -68,25 +67,25 @@ const getOperations = (event) => ({
isDelete, isDelete,
}); });
}, },
find: async () => { find: async () => {
event.preventDefault(); event.preventDefault();
const [, value] = await Dialog.prompt('Find', ''); const [, value] = await Dialog.prompt('Find', '');
if (!value) if (!value)
return; return;
const names = Info.files.map(DOM.getCurrentName); const names = Info.files.map(DOM.getCurrentName);
const [result] = finder.find(value, names); const [result] = finder.find(value, names);
DOM.setCurrentByName(result); DOM.setCurrentByName(result);
}, },
findNext: () => { findNext: () => {
const name = finder.findNext(); const name = finder.findNext();
DOM.setCurrentByName(name); DOM.setCurrentByName(name);
}, },
findPrevious: () => { findPrevious: () => {
const name = finder.findPrevious(); const name = finder.findPrevious();
DOM.setCurrentByName(name); DOM.setCurrentByName(name);
@ -97,34 +96,33 @@ module.exports.selectFile = selectFile;
function selectFile(current) { function selectFile(current) {
const name = DOM.getCurrentName(current); const name = DOM.getCurrentName(current);
if (name === '..') if (name === '..')
return; return;
DOM.selectFile(current); DOM.selectFile(current);
} }
function setCurrent(sibling, {count, isVisual, isDelete}) { function setCurrent(sibling, {count, isVisual, isDelete}) {
let current = Info.element; let current = Info.element;
const select = isVisual ? selectFile : DOM.unselectFile; const select = isVisual ? selectFile : DOM.unselectFile;
select(current); select(current);
const position = `${sibling}Sibling`; const position = `${sibling}Sibling`;
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
const next = current[position]; const next = current[position];
if (!next) if (!next)
break; break;
current = next; current = next;
select(current); select(current);
} }
DOM.setCurrentFile(current); DOM.setCurrentFile(current);
if (isDelete) if (isDelete)
CloudCmd.Operation.show('delete'); CloudCmd.Operation.show('delete');
} }

View file

@ -2,20 +2,15 @@
const {join} = require('path'); const {join} = require('path');
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const mockRequire = require('mock-require'); const mockRequire = require('mock-require');
const dir = '../'; const dir = '../';
const pathVim = join(dir, 'vim'); const pathVim = join(dir, 'vim');
const { const {getDOM, getCloudCmd} = require('./globals.fixture');
getDOM,
getCloudCmd,
} = require('./globals.fixture');
global.DOM = getDOM(); global.DOM = getDOM();
global.CloudCmd = getCloudCmd(); global.CloudCmd = getCloudCmd();
@ -23,10 +18,7 @@ global.CloudCmd = getCloudCmd();
const vim = require(pathVim); const vim = require(pathVim);
const {assign} = Object; const {assign} = Object;
const { const {DOM, CloudCmd} = global;
DOM,
CloudCmd,
} = global;
const {Buffer} = DOM; const {Buffer} = DOM;
const pathFind = join(dir, 'vim', 'find'); const pathFind = join(dir, 'vim', 'find');
@ -34,14 +26,14 @@ const {reRequire, stopAll} = mockRequire;
test('cloudcmd: client: key: set next file: no', (t) => { test('cloudcmd: client: key: set next file: no', (t) => {
const element = {}; const element = {};
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('j', {}); vim('j', {});
t.calledWith(setCurrentFile, [element], 'should set next file'); t.calledWith(setCurrentFile, [element], 'should set next file');
t.end(); t.end();
}); });
@ -51,14 +43,14 @@ test('cloudcmd: client: key: set next file current: j', (t) => {
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('j', {}); vim('j', {});
t.calledWith(setCurrentFile, [nextSibling], 'should set next file'); t.calledWith(setCurrentFile, [nextSibling], 'should set next file');
t.end(); t.end();
}); });
@ -68,16 +60,16 @@ test('cloudcmd: client: key: set next file current: mjj', (t) => {
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('m', {}); vim('m', {});
vim('j', {}); vim('j', {});
vim('j', {}); vim('j', {});
t.calledWith(setCurrentFile, [nextSibling], 'should set next file'); t.calledWith(setCurrentFile, [nextSibling], 'should set next file');
t.end(); t.end();
}); });
@ -87,15 +79,15 @@ test('cloudcmd: client: key: set next file current: g', (t) => {
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('g', {}); vim('g', {});
vim('j', {}); vim('j', {});
t.calledWith(setCurrentFile, [nextSibling], 'should ignore g'); t.calledWith(setCurrentFile, [nextSibling], 'should ignore g');
t.end(); t.end();
}); });
@ -105,20 +97,21 @@ test('cloudcmd: client: key: set +2 file current', (t) => {
const nextSibling = { const nextSibling = {
nextSibling: last, nextSibling: last,
}; };
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
const event = {}; const event = {};
vim('2', event); vim('2', event);
vim('j', event); vim('j', event);
t.calledWith(setCurrentFile, [last], 'should set next file'); t.calledWith(setCurrentFile, [last], 'should set next file');
t.end(); t.end();
}); });
@ -128,24 +121,25 @@ test('cloudcmd: client: key: select +2 files from current before delete', (t) =>
const nextSibling = { const nextSibling = {
nextSibling: last, nextSibling: last,
}; };
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
global.DOM.selectFile = stub(); global.DOM.selectFile = stub();
global.DOM.getCurrentName = () => false; global.DOM.getCurrentName = () => false;
global.CloudCmd.Operation.show = stub(); global.CloudCmd.Operation.show = stub();
const event = {}; const event = {};
vim('d', event); vim('d', event);
vim('2', event); vim('2', event);
vim('j', event); vim('j', event);
t.calledWith(setCurrentFile, [last], 'should set next file'); t.calledWith(setCurrentFile, [last], 'should set next file');
t.end(); t.end();
}); });
@ -155,25 +149,26 @@ test('cloudcmd: client: key: delete +2 files from current', (t) => {
const nextSibling = { const nextSibling = {
nextSibling: last, nextSibling: last,
}; };
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
const show = stub(); const show = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
global.DOM.selectFile = stub(); global.DOM.selectFile = stub();
global.DOM.getCurrentName = () => false; global.DOM.getCurrentName = () => false;
global.CloudCmd.Operation.show = show; global.CloudCmd.Operation.show = show;
const event = {}; const event = {};
vim('d', event); vim('d', event);
vim('2', event); vim('2', event);
vim('j', event); vim('j', event);
t.calledWith(show, ['delete'], 'should call delete'); t.calledWith(show, ['delete'], 'should call delete');
t.end(); t.end();
}); });
@ -183,87 +178,87 @@ test('cloudcmd: client: key: set previous file current', (t) => {
const element = { const element = {
previousSibling, previousSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('k', {}); vim('k', {});
t.calledWith(setCurrentFile, [previousSibling], 'should set previous file'); t.calledWith(setCurrentFile, [previousSibling], 'should set previous file');
t.end(); t.end();
}); });
test('cloudcmd: client: key: copy: no', (t) => { test('cloudcmd: client: key: copy: no', (t) => {
const copy = stub(); const copy = stub();
Buffer.copy = copy; Buffer.copy = copy;
vim('y', {}); vim('y', {});
t.notOk(copy.called, 'should not copy files'); t.notOk(copy.called, 'should not copy files');
t.end(); t.end();
}); });
test('cloudcmd: client: key: copy', (t) => { test('cloudcmd: client: key: copy', (t) => {
const copy = stub(); const copy = stub();
Buffer.copy = copy; Buffer.copy = copy;
vim('v', {}); vim('v', {});
vim('y', {}); vim('y', {});
t.ok(copy.calledWith(), 'should copy files'); t.ok(copy.calledWith(), 'should copy files');
t.end(); t.end();
}); });
test('cloudcmd: client: key: copy: unselectFiles', (t) => { test('cloudcmd: client: key: copy: unselectFiles', (t) => {
const unselectFiles = stub(); const unselectFiles = stub();
DOM.unselectFiles = unselectFiles; DOM.unselectFiles = unselectFiles;
vim('v', {}); vim('v', {});
vim('y', {}); vim('y', {});
t.ok(unselectFiles.calledWith(), 'should unselect files'); t.ok(unselectFiles.calledWith(), 'should unselect files');
t.end(); t.end();
}); });
test('cloudcmd: client: key: paste', (t) => { test('cloudcmd: client: key: paste', (t) => {
const paste = stub(); const paste = stub();
Buffer.paste = paste; Buffer.paste = paste;
vim('p', {}); vim('p', {});
t.ok(paste.calledWith(), 'should paste files'); t.ok(paste.calledWith(), 'should paste files');
t.end(); t.end();
}); });
test('cloudcmd: client: key: selectFile: ..', (t) => { test('cloudcmd: client: key: selectFile: ..', (t) => {
const getCurrentName = stub(); const getCurrentName = stub();
DOM.selectFile = stub(); DOM.selectFile = stub();
DOM.getCurrentName = () => '..'; DOM.getCurrentName = () => '..';
const current = {}; const current = {};
vim.selectFile(current); vim.selectFile(current);
t.notOk(getCurrentName.called, 'should not call selectFile'); t.notOk(getCurrentName.called, 'should not call selectFile');
t.end(); t.end();
}); });
test('cloudcmd: client: key: selectFile', (t) => { test('cloudcmd: client: key: selectFile', (t) => {
const selectFile = stub(); const selectFile = stub();
DOM.selectFile = selectFile; DOM.selectFile = selectFile;
DOM.getCurrentName = (a) => a.name; DOM.getCurrentName = (a) => a.name;
const current = {}; const current = {};
vim.selectFile(current); vim.selectFile(current);
t.calledWith(selectFile, [current], 'should call selectFile'); t.calledWith(selectFile, [current], 'should call selectFile');
t.end(); t.end();
}); });
@ -273,17 +268,18 @@ test('cloudcmd: client: key: set last file current: shift + g', (t) => {
const nextSibling = { const nextSibling = {
nextSibling: last, nextSibling: last,
}; };
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('G', {}); vim('G', {});
t.calledWith(setCurrentFile, [last], 'should set last file'); t.calledWith(setCurrentFile, [last], 'should set last file');
t.end(); t.end();
}); });
@ -293,17 +289,18 @@ test('cloudcmd: client: key: set last file current: $', (t) => {
const nextSibling = { const nextSibling = {
nextSibling: last, nextSibling: last,
}; };
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('$', {}); vim('$', {});
t.calledWith(setCurrentFile, [last], 'should set last file'); t.calledWith(setCurrentFile, [last], 'should set last file');
t.end(); t.end();
}); });
@ -313,19 +310,19 @@ test('cloudcmd: client: key: set first file current: gg', (t) => {
const previousSibling = { const previousSibling = {
previousSibling: first, previousSibling: first,
}; };
const element = { const element = {
previousSibling, previousSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('g', {}); vim('g', {});
vim('g', {}); vim('g', {});
t.calledWith(setCurrentFile, [first], 'should set first file'); t.calledWith(setCurrentFile, [first], 'should set first file');
t.end(); t.end();
}); });
@ -335,46 +332,46 @@ test('cloudcmd: client: key: set first file current: ^', (t) => {
const previousSibling = { const previousSibling = {
previousSibling: first, previousSibling: first,
}; };
const element = { const element = {
previousSibling, previousSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.setCurrentFile = setCurrentFile; global.DOM.setCurrentFile = setCurrentFile;
vim('^', {}); vim('^', {});
t.calledWith(setCurrentFile, [first], 'should set first file'); t.calledWith(setCurrentFile, [first], 'should set first file');
t.end(); t.end();
}); });
test('cloudcmd: client: key: visual', (t) => { test('cloudcmd: client: key: visual', (t) => {
const element = {}; const element = {};
const toggleSelectedFile = stub(); const toggleSelectedFile = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.toggleSelectedFile = toggleSelectedFile; global.DOM.toggleSelectedFile = toggleSelectedFile;
vim('v', {}); vim('v', {});
t.calledWith(toggleSelectedFile, [element], 'should toggle selection'); t.calledWith(toggleSelectedFile, [element], 'should toggle selection');
t.end(); t.end();
}); });
test('cloudcmd: client: key: ESC', (t) => { test('cloudcmd: client: key: ESC', (t) => {
const element = {}; const element = {};
const unselectFiles = stub(); const unselectFiles = stub();
global.DOM.CurrentInfo.element = element; global.DOM.CurrentInfo.element = element;
global.DOM.unselectFiles = unselectFiles ; global.DOM.unselectFiles = unselectFiles;
vim('Escape'); vim('Escape');
t.ok(unselectFiles.calledWith(), 'should toggle selection'); t.ok(unselectFiles.calledWith(), 'should toggle selection');
t.end(); t.end();
}); });
@ -384,16 +381,16 @@ test('cloudcmd: client: key: Enter', (t) => {
const element = { const element = {
nextSibling, nextSibling,
}; };
const setCurrentFile = stub(); const setCurrentFile = stub();
DOM.CurrentInfo.element = element; DOM.CurrentInfo.element = element;
DOM.setCurrentFile = setCurrentFile; DOM.setCurrentFile = setCurrentFile;
vim('Enter'); vim('Enter');
vim('j'); vim('j');
t.calledWith(setCurrentFile, [nextSibling], 'should set next file'); t.calledWith(setCurrentFile, [nextSibling], 'should set next file');
t.end(); t.end();
}); });
@ -401,14 +398,14 @@ test('cloudcmd: client: key: Enter', (t) => {
test('cloudcmd: client: key: /', (t) => { test('cloudcmd: client: key: /', (t) => {
const preventDefault = stub(); const preventDefault = stub();
const element = {}; const element = {};
DOM.CurrentInfo.element = element; DOM.CurrentInfo.element = element;
DOM.getCurrentName = () => ''; DOM.getCurrentName = () => '';
vim('/', { vim('/', {
preventDefault, preventDefault,
}); });
t.calledWithNoArgs(preventDefault, 'should call preventDefault'); t.calledWithNoArgs(preventDefault, 'should call preventDefault');
t.end(); t.end();
}); });
@ -417,94 +414,97 @@ test('cloudcmd: client: find', (t) => {
assign(DOM.Dialog, { assign(DOM.Dialog, {
prompt: stub().returns([]), prompt: stub().returns([]),
}); });
const setCurrentByName = stub(); const setCurrentByName = stub();
assign(DOM, { assign(DOM, {
setCurrentByName, setCurrentByName,
}); });
const vim = reRequire(pathVim); const vim = reRequire(pathVim);
const event = { const event = {
preventDefault: stub(), preventDefault: stub(),
}; };
vim('/', event); vim('/', event);
stopAll(); stopAll();
t.notCalled(setCurrentByName); t.notCalled(setCurrentByName);
t.end(); t.end();
}); });
test('cloudcmd: client: key: n', (t) => { test('cloudcmd: client: key: n', (t) => {
const findNext = stub(); const findNext = stub();
mockRequire(pathFind, { mockRequire(pathFind, {
findNext, findNext,
}); });
const vim = reRequire(pathVim); const vim = reRequire(pathVim);
const event = {}; const event = {};
vim('n', event); vim('n', event);
stopAll(); stopAll();
t.ok(findNext.calledWith(), 'should call findNext'); t.ok(findNext.calledWith(), 'should call findNext');
t.end(); t.end();
}); });
test('cloudcmd: client: key: N', (t) => { test('cloudcmd: client: key: N', (t) => {
const findPrevious = stub(); const findPrevious = stub();
mockRequire(pathFind, { mockRequire(pathFind, {
findPrevious, findPrevious,
}); });
const vim = reRequire(`${dir}vim`); const vim = reRequire(`${dir}vim`);
const event = {}; const event = {};
vim('N', event); vim('N', event);
stopAll(); stopAll();
t.ok(findPrevious.calledWith(), 'should call findPrevious'); t.ok(findPrevious.calledWith(), 'should call findPrevious');
t.end(); t.end();
}); });
test('cloudcmd: client: key: make directory', (t) => { test('cloudcmd: client: key: make directory', (t) => {
const vim = reRequire(pathVim); const vim = reRequire(pathVim);
assign(DOM, { assign(DOM, {
promptNewDir: stub(), promptNewDir: stub(),
}); });
const event = { const event = {
stopImmediatePropagation: stub(), stopImmediatePropagation: stub(),
preventDefault: stub(), preventDefault: stub(),
}; };
vim('m', event); vim('m', event);
vim('d', event); vim('d', event);
t.calledWithNoArgs(DOM.promptNewDir); t.calledWithNoArgs(DOM.promptNewDir);
t.end(); t.end();
}); });
test('cloudcmd: client: key: make file', (t) => { test('cloudcmd: client: key: make file', (t) => {
const vim = reRequire(pathVim); const vim = reRequire(pathVim);
assign(DOM, { assign(DOM, {
promptNewFile: stub(), promptNewFile: stub(),
}); });
const event = { const event = {
stopImmediatePropagation: stub(), stopImmediatePropagation: stub(),
preventDefault: stub(), preventDefault: stub(),
}; };
vim('m', event); vim('m', event);
vim('f', event); vim('f', event);
t.calledWithNoArgs(DOM.promptNewDir); t.calledWithNoArgs(DOM.promptNewDir);
t.end(); t.end();
}); });
@ -515,12 +515,12 @@ test('cloudcmd: client: vim: terminal', (t) => {
show: stub(), show: stub(),
}, },
}); });
const event = { const event = {};
};
vim('t', event); vim('t', event);
vim('t', event); vim('t', event);
t.calledWithNoArgs(CloudCmd.Terminal.show); t.calledWithNoArgs(CloudCmd.Terminal.show);
t.end(); t.end();
}); });
@ -531,12 +531,11 @@ test('cloudcmd: client: vim: edit', (t) => {
show: stub(), show: stub(),
}, },
}); });
const event = { const event = {};
};
vim('e', event); vim('e', event);
t.calledWithNoArgs(CloudCmd.EditFileVim.show); t.calledWithNoArgs(CloudCmd.EditFileVim.show);
t.end(); t.end();
}); });

View file

@ -25,6 +25,7 @@ module.exports = (key, operations) => {
const prevStore = store(); const prevStore = store();
const isVisual = visual(); const isVisual = visual();
const value = store(prevStore.concat(key)); const value = store(prevStore.concat(key));
const { const {
escape = noop, escape = noop,
moveNext = noop, moveNext = noop,
@ -41,132 +42,129 @@ module.exports = (key, operations) => {
terminal = noop, terminal = noop,
edit = noop, edit = noop,
} = operations; } = operations;
if (key === 'Enter') if (key === 'Enter')
return end(); return end();
if (key === 'Escape') { if (key === 'Escape') {
visual(false); visual(false);
escape(); escape();
return end(); return end();
} }
if (key === 'j' || key === 'w') { if (key === 'j' || key === 'w') {
const { const {
count, count,
isDelete, isDelete,
isVisual, isVisual,
} = handleDelete(prevStore); } = handleDelete(prevStore);
!isNaN(count) && moveNext({ !isNaN(count) && moveNext({
count, count,
isVisual, isVisual,
isDelete, isDelete,
}); });
return end(); return end();
} }
if (key === 'k' || key === 'b') { if (key === 'k' || key === 'b') {
const { const {
count, count,
isDelete, isDelete,
isVisual, isVisual,
} = handleDelete(prevStore); } = handleDelete(prevStore);
!isNaN(count) && movePrevious({ !isNaN(count) && movePrevious({
count, count,
isVisual, isVisual,
isDelete, isDelete,
}); });
return end(); return end();
} }
if (value === 'gg' || key === '^') { if (value === 'gg' || key === '^') {
const { const {isDelete, isVisual} = handleDelete(prevStore);
isDelete,
isVisual,
} = handleDelete(prevStore);
movePrevious({ movePrevious({
count: Infinity, count: Infinity,
isVisual, isVisual,
isDelete, isDelete,
}); });
return end(); return end();
} }
if (value === 'md') { if (value === 'md') {
makeDirectory(); makeDirectory();
return end(); return end();
} }
if (value === 'tt') { if (value === 'tt') {
terminal(); terminal();
return end(); return end();
} }
if (value === 'e') { if (value === 'e') {
edit(); edit();
return end(); return end();
} }
if (value === 'mf') { if (value === 'mf') {
makeFile(); makeFile();
return end(); return end();
} }
if (key === 'd' && (visual() || prevStore === 'd')) { if (key === 'd' && (visual() || prevStore === 'd')) {
stopVisual(); stopVisual();
remove(); remove();
return end(); return end();
} }
if (key === 'G' || key === '$') { if (key === 'G' || key === '$') {
moveNext({ moveNext({
count: Infinity, count: Infinity,
isVisual, isVisual,
}); });
return end(); return end();
} }
if (key === 'y') { if (key === 'y') {
if (!visual()) if (!visual())
return end(); return end();
stopVisual(); stopVisual();
copy(); copy();
return end(); return end();
} }
if (/^p$/i.test(key)) { if (/^p$/i.test(key)) {
paste(); paste();
return end(); return end();
} }
if (/^v$/i.test(key)) { if (/^v$/i.test(key)) {
visual(!visual()); visual(!visual());
select(); select();
return end(); return end();
} }
if (key === '/') { if (key === '/') {
find(); find();
return end(); return end();
} }
if (key === 'n') { if (key === 'n') {
findNext(); findNext();
return end(); return end();
} }
if (key === 'N') { if (key === 'N') {
findPrevious(); findPrevious();
return end(); return end();
@ -175,15 +173,15 @@ module.exports = (key, operations) => {
function handleDelete(prevStore) { function handleDelete(prevStore) {
const isDelete = prevStore[0] === 'd'; const isDelete = prevStore[0] === 'd';
if (isDelete) { if (isDelete) {
visual(true); visual(true);
prevStore = rmFirst(prevStore); prevStore = rmFirst(prevStore);
} }
const count = getNumber(prevStore); const count = getNumber(prevStore);
const isVisual = visual(); const isVisual = visual();
return { return {
count, count,
isDelete, isDelete,
@ -194,10 +192,9 @@ function handleDelete(prevStore) {
function getNumber(value) { function getNumber(value) {
if (!value) if (!value)
return 1; return 1;
if (value === 'g') if (value === 'g')
return 1; return 1;
return parseInt(value); return parseInt(value);
} }

View file

@ -1,9 +1,6 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const vim = require('./vim'); const vim = require('./vim');
@ -64,4 +61,3 @@ test('vim: b', (t) => {
t.calledWith(movePrevious, [expected], 'should call movePrevious'); t.calledWith(movePrevious, [expected], 'should call movePrevious');
t.end(); t.end();
}); });

View file

@ -8,4 +8,3 @@ module.exports = (array, item) => {
return index; return index;
}; };

View file

@ -9,4 +9,3 @@ module.exports = (indexFrom, indexTo, files) => {
return [files[indexFrom]]; return [files[indexFrom]];
}; };

View file

@ -52,12 +52,10 @@ const execAll = currify((funcs, event) => {
const Info = DOM.CurrentInfo; const Info = DOM.CurrentInfo;
const {Events} = DOM; const {Events} = DOM;
const EventsFiles = { const EventsFiles = {
mousedown: exec.with(execIfNotUL, setCurrentFileByEvent), mousedown: exec.with(execIfNotUL, setCurrentFileByEvent),
click: execAll([ click: execAll([onClick, unselect]),
onClick,
unselect,
]),
dragstart: exec.with(execIfNotUL, onDragStart), dragstart: exec.with(execIfNotUL, onDragStart),
dblclick: exec.with(execIfNotUL, onDblClick), dblclick: exec.with(execIfNotUL, onDblClick),
touchstart: exec.with(execIfNotUL, onTouch), touchstart: exec.with(execIfNotUL, onTouch),
@ -79,8 +77,7 @@ function header() {
if (parent.dataset.name !== 'js-fm-header') if (parent.dataset.name !== 'js-fm-header')
return; return;
const name = (el.dataset.name || '') const name = (el.dataset.name || '').replace('js-', '');
.replace('js-', '');
if (!/^(name|size|date)$/.test(name)) if (!/^(name|size|date)$/.test(name))
return; return;
@ -97,7 +94,7 @@ function header() {
function getPath(el, path = []) { function getPath(el, path = []) {
if (!el) if (!el)
return path; return path;
return getPath(el.parentElement, path.concat(el)); return getPath(el.parentElement, path.concat(el));
} }
@ -124,19 +121,19 @@ module.exports.initKeysPanel = () => {
}; };
const clickFuncs = { const clickFuncs = {
'f1' : CloudCmd.Help.show, 'f1': CloudCmd.Help.show,
'f2' : CloudCmd.UserMenu.show, 'f2': CloudCmd.UserMenu.show,
'f3' : CloudCmd.View.show, 'f3': CloudCmd.View.show,
'f4' : CloudCmd.EditFile.show, 'f4': CloudCmd.EditFile.show,
'f5' : operation('copy'), 'f5': operation('copy'),
'f6' : operation('move'), 'f6': operation('move'),
'f7' : DOM.promptNewDir, 'f7': DOM.promptNewDir,
'f8' : operation('delete'), 'f8': operation('delete'),
'f9' : CloudCmd.Menu.show, 'f9': CloudCmd.Menu.show,
'f10' : CloudCmd.Config.show, 'f10': CloudCmd.Config.show,
'~' : CloudCmd.Konsole.show, '~': CloudCmd.Konsole.show,
'shift~' : CloudCmd.Terminal.show, 'shift~': CloudCmd.Terminal.show,
'contact' : CloudCmd.Contact.show, 'contact': CloudCmd.Contact.show,
}; };
exec(clickFuncs[id]); exec(clickFuncs[id]);
@ -146,7 +143,7 @@ module.exports.initKeysPanel = () => {
const getPanel = (side) => { const getPanel = (side) => {
if (!itype.string(side)) if (!itype.string(side))
return side; return side;
return DOM.getByDataName(`js-${side}`); return DOM.getByDataName(`js-${side}`);
}; };
@ -182,10 +179,8 @@ function decodePath(path) {
const {prefix} = CloudCmd; const {prefix} = CloudCmd;
const prefixReg = RegExp('^' + prefix + FS); const prefixReg = RegExp('^' + prefix + FS);
return decodeURI(path) return decodeURI(path).replace(url, '')
.replace(url, '') .replace(prefixReg, '') // browser doesn't replace % -> %25% do it for him
.replace(prefixReg, '')
// browser doesn't replace % -> %25% do it for him
.replace('%%', '%25%') .replace('%%', '%25%')
.replace(NBSP_REG, SPACE) || '/'; .replace(NBSP_REG, SPACE) || '/';
} }
@ -219,8 +214,12 @@ async function onPathElementClick(panel, event) {
} }
function copyPath(el) { function copyPath(el) {
clipboard.writeText(el.parentElement.title) clipboard
.then(CloudCmd.log) .writeText(el
.parentElement
.title)
.then(CloudCmd
.log)
.catch(CloudCmd.log); .catch(CloudCmd.log);
} }
@ -308,12 +307,8 @@ function onDragStart(event) {
link.href = prefixURL + '/pack' + Info.path + EXT; link.href = prefixURL + '/pack' + Info.path + EXT;
} }
event.dataTransfer.setData( event.dataTransfer.setData('DownloadURL', 'application/octet-stream' + ':' + name +
'DownloadURL', ':' + link);
'application/octet-stream' + ':' +
name + ':' +
link,
);
} }
function getLIElement(element) { function getLIElement(element) {
@ -397,10 +392,7 @@ function dragndrop() {
}; };
const onDrop = (event) => { const onDrop = (event) => {
const { const {files, items} = event.dataTransfer;
files,
items,
} = event.dataTransfer;
const {length: filesCount} = files; const {length: filesCount} = files;
@ -410,7 +402,9 @@ function dragndrop() {
return uploadFiles(files); return uploadFiles(files);
const isFile = (item) => item.kind === 'file'; const isFile = (item) => item.kind === 'file';
const dirFiles = Array.from(items).filter(isFile); const dirFiles = Array
.from(items)
.filter(isFile);
if (dirFiles.length) if (dirFiles.length)
return DOM.uploadDirectory(dirFiles); return DOM.uploadDirectory(dirFiles);
@ -467,6 +461,7 @@ function pop() {
return CloudCmd.route(location.hash); return CloudCmd.route(location.hash);
const history = false; const history = false;
await CloudCmd.changeDir(path, { await CloudCmd.changeDir(path, {
history, history,
}); });
@ -495,4 +490,3 @@ function resize() {
DOM.changePanel(); DOM.changePanel();
}); });
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
const exec = require('execon'); const exec = require('execon');
const tryToCatch = require('try-to-catch'); const tryToCatch = require('try-to-catch');
const loadJS = require('load.js').js; const loadJS = require('load.js').js;
@ -16,45 +15,44 @@ const noJS = (a) => a.replace(/.js$/, '');
module.exports = function loadModule(params) { module.exports = function loadModule(params) {
if (!params) if (!params)
return; return;
const {path} = params; const {path} = params;
const name = path && noJS(pascalCase(path)); const name = path && noJS(pascalCase(path));
const doBefore = params.dobefore; const doBefore = params.dobefore;
if (CloudCmd[name]) if (CloudCmd[name])
return; return;
CloudCmd[name] = async () => { CloudCmd[name] = async () => {
exec(doBefore); exec(doBefore);
const {DIR_MODULES} = CloudCmd; const {DIR_MODULES} = CloudCmd;
const pathFull = `${DIR_MODULES}/${path}.js`; const pathFull = `${DIR_MODULES}/${path}.js`;
await loadJS(pathFull); await loadJS(pathFull);
const newModule = async (f) => f && f(); const newModule = async (f) => f && f();
const module = CloudCmd[name]; const module = CloudCmd[name];
Object.assign(newModule, module); Object.assign(newModule, module);
CloudCmd[name] = newModule; CloudCmd[name] = newModule;
CloudCmd.log('init', name); CloudCmd.log('init', name);
await module.init(); await module.init();
return newModule; return newModule;
}; };
CloudCmd[name].show = async (...args) => { CloudCmd[name].show = async (...args) => {
CloudCmd.log('show', name, args); CloudCmd.log('show', name, args);
const m = CloudCmd[name]; const m = CloudCmd[name];
const [e, a] = await tryToCatch(m); const [e, a] = await tryToCatch(m);
if (e) if (e)
return console.error(e); return console.error(e);
return await a.show(...args); return await a.show(...args);
}; };
}; };

View file

@ -15,6 +15,7 @@ const {log} = CloudCmd;
const upload = currify(_upload); const upload = currify(_upload);
const Name = 'Cloud'; const Name = 'Cloud';
CloudCmd[Name] = module.exports; CloudCmd[Name] = module.exports;
module.exports.init = async () => { module.exports.init = async () => {
@ -41,10 +42,7 @@ module.exports.saveFile = (callback) => {
}; };
function _upload(callback, file) { function _upload(callback, file) {
const { const {url, filename} = file;
url,
filename,
} = file;
const responseType = 'arraybuffer'; const responseType = 'arraybuffer';
const success = exec.with(callback, filename); const success = exec.with(callback, filename);
@ -64,4 +62,3 @@ function loadFiles() {
load.js(js), load.js(js),
]); ]);
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
CloudCmd.CommandLine = exports; CloudCmd.CommandLine = exports;
const Dialog = require('../dom/dialog'); const Dialog = require('../dom/dialog');
@ -34,6 +33,4 @@ async function show() {
} }
} }
function hide() { function hide() {}
}

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd, DOM, io */ /* global CloudCmd, DOM, io */
require('../../../css/config.css'); require('../../../css/config.css');
const rendy = require('rendy'); const rendy = require('rendy');
@ -22,6 +21,7 @@ const {getTitle} = require('../../../common/cloudfunc');
const {Dialog, setTitle} = DOM; const {Dialog, setTitle} = DOM;
const Name = 'Config'; const Name = 'Config';
CloudCmd[Name] = module.exports; CloudCmd[Name] = module.exports;
const loadSocket = promisify(DOM.loadSocket); const loadSocket = promisify(DOM.loadSocket);
@ -64,10 +64,7 @@ module.exports.init = async () => {
initSocket(); initSocket();
}; };
const { const {config, Key} = CloudCmd;
config,
Key,
} = CloudCmd;
let Element; let Element;
@ -77,6 +74,7 @@ function getHost() {
origin, origin,
protocol, protocol,
} = location; } = location;
const href = origin || `${protocol}//${host}`; const href = origin || `${protocol}//${host}`;
return href; return href;
@ -84,10 +82,7 @@ function getHost() {
function initSocket() { function initSocket() {
const href = getHost(); const href = getHost();
const { const {prefixSocket, prefix} = CloudCmd;
prefixSocket,
prefix,
} = CloudCmd;
const ONE_MINUTE = 60 * 1000; const ONE_MINUTE = 60 * 1000;
@ -156,7 +151,7 @@ async function fillTemplate() {
const innerHTML = rendy(Template, obj); const innerHTML = rendy(Template, obj);
Element = createElement('form', { Element = createElement('form', {
className : 'config', className: 'config',
innerHTML, innerHTML,
}); });
@ -173,11 +168,13 @@ async function fillTemplate() {
const getTarget = ({target}) => target; const getTarget = ({target}) => target;
const handleChange = squad(onChange, getTarget); const handleChange = squad(onChange, getTarget);
Array.from(inputs) Array
.from(inputs)
.map(addKey(onKey)) .map(addKey(onKey))
.map(addChange(handleChange)); .map(addChange(handleChange));
const autoSize = true; const autoSize = true;
CloudCmd.View.show(Element, { CloudCmd.View.show(Element, {
autoSize, autoSize,
afterShow, afterShow,
@ -246,4 +243,3 @@ async function onKey({keyCode, target}) {
return await onChange(target); return await onChange(target);
} }
} }

View file

@ -11,8 +11,7 @@ module.exports.getElementByName = getElementByName;
function getElementByName(selector, element) { function getElementByName(selector, element) {
const str = `[data-name="js-${selector}"]`; const str = `[data-name="js-${selector}"]`;
return element return element.querySelector(str);
.querySelector(str);
} }
module.exports.getName = (element) => { module.exports.getName = (element) => {
@ -40,7 +39,7 @@ module.exports.convert = (config) => {
function setState(state) { function setState(state) {
if (state) if (state)
return ' checked'; return ' checked';
return ''; return '';
} }
@ -74,4 +73,3 @@ module.exports.setValue = (name, value, element) => {
break; break;
} }
}; };

View file

@ -39,4 +39,3 @@ function onKey({keyCode}) {
if (keyCode === Key.ESC) if (keyCode === Key.ESC)
hide(); hide();
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
CloudCmd.EditFileVim = exports; CloudCmd.EditFileVim = exports;
const Events = require('../dom/events'); const Events = require('../dom/events');
@ -23,8 +22,7 @@ module.exports.init = async () => {
module.exports.show = async () => { module.exports.show = async () => {
Events.addKey(listener); Events.addKey(listener);
const editFile = await CloudCmd.EditFile const editFile = await CloudCmd.EditFile.show(ConfigView);
.show(ConfigView);
editFile editFile
.getEditor() .getEditor()
@ -38,14 +36,10 @@ function hide() {
} }
function listener(event) { function listener(event) {
const { const {keyCode, shiftKey} = event;
keyCode,
shiftKey,
} = event;
if (shiftKey && keyCode === Key.ESC) { if (shiftKey && keyCode === Key.ESC) {
event.preventDefault(); event.preventDefault();
hide(); hide();
} }
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd, DOM*/ /* global CloudCmd, DOM*/
CloudCmd.EditFile = exports; CloudCmd.EditFile = exports;
const Format = require('format-io'); const Format = require('format-io');
@ -11,10 +10,7 @@ const supermenu = require('supermenu');
const Info = DOM.CurrentInfo; const Info = DOM.CurrentInfo;
const { const {Dialog, Images} = DOM;
Dialog,
Images,
} = DOM;
const {config} = CloudCmd; const {config} = CloudCmd;
@ -65,7 +61,8 @@ module.exports.show = async (options) => {
Images.show.load(); Images.show.load();
CloudCmd.Edit CloudCmd
.Edit
.getEditor() .getEditor()
.setOption('keyMap', 'default'); .setOption('keyMap', 'default');
@ -81,7 +78,8 @@ module.exports.show = async (options) => {
setMsgChanged(name); setMsgChanged(name);
CloudCmd.Edit CloudCmd
.Edit
.getEditor() .getEditor()
.setValueFirst(path, data) .setValueFirst(path, data)
.setModeForPath(name) .setModeForPath(name)
@ -133,7 +131,8 @@ function setMenu(event) {
}, },
afterClick: () => { afterClick: () => {
CloudCmd.Edit CloudCmd
.Edit
.getEditor() .getEditor()
.focus(); .focus();
}, },
@ -151,28 +150,28 @@ function getMenuData() {
const editor = CloudCmd.Edit.getEditor(); const editor = CloudCmd.Edit.getEditor();
return { return {
'Save Ctrl+S' : () => { 'Save Ctrl+S': () => {
editor.save(); editor.save();
}, },
'Go To Line Ctrl+G' : () => { 'Go To Line Ctrl+G': () => {
editor.goToLine(); editor.goToLine();
}, },
'Cut Ctrl+X' : () => { 'Cut Ctrl+X': () => {
editor.cutToClipboard(); editor.cutToClipboard();
}, },
'Copy Ctrl+C' : () => { 'Copy Ctrl+C': () => {
editor.copyToClipboard(); editor.copyToClipboard();
}, },
'Paste Ctrl+V' : () => { 'Paste Ctrl+V': () => {
editor.pasteFromClipboard(); editor.pasteFromClipboard();
}, },
'Delete Del' : () => { 'Delete Del': () => {
editor.remove('right'); editor.remove('right');
}, },
'Select All Ctrl+A' : () => { 'Select All Ctrl+A': () => {
editor.selectAll(); editor.selectAll();
}, },
'Close Esc' : hide, 'Close Esc': hide,
}; };
} }
@ -196,4 +195,3 @@ async function isChanged() {
editor.save(); editor.save();
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
CloudCmd.EditNamesVim = exports; CloudCmd.EditNamesVim = exports;
const Events = require('../dom/events'); const Events = require('../dom/events');
@ -22,7 +21,8 @@ module.exports.init = async () => {
module.exports.show = () => { module.exports.show = () => {
Events.addKey(listener); Events.addKey(listener);
CloudCmd.EditNames CloudCmd
.EditNames
.show(ConfigView) .show(ConfigView)
.getEditor() .getEditor()
.setKeyMap('vim'); .setKeyMap('vim');
@ -35,14 +35,10 @@ function hide() {
} }
function listener(event) { function listener(event) {
const { const {keyCode, shiftKey} = event;
keyCode,
shiftKey,
} = event;
if (shiftKey && keyCode === Key.ESC) { if (shiftKey && keyCode === Key.ESC) {
event.preventDefault(); event.preventDefault();
hide(); hide();
} }
} }

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd, DOM */ /* global CloudCmd, DOM */
CloudCmd.EditNames = exports; CloudCmd.EditNames = exports;
const currify = require('currify'); const currify = require('currify');
@ -45,7 +44,8 @@ module.exports.show = (options) => {
DOM.Events.addKey(keyListener); DOM.Events.addKey(keyListener);
CloudCmd.Edit CloudCmd
.Edit
.getEditor() .getEditor()
.setValueFirst('edit-names', names) .setValueFirst('edit-names', names)
.setMode() .setMode()
@ -65,7 +65,6 @@ async function keyListener(event) {
if (ctrlMeta && event.keyCode === Key.S) if (ctrlMeta && event.keyCode === Key.S)
hide(); hide();
else if (ctrlMeta && event.keyCode === Key.P) { else if (ctrlMeta && event.keyCode === Key.P) {
const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]'); const [, pattern] = await Dialog.prompt('Apply pattern:', '[n][e]');
pattern && applyPattern(pattern); pattern && applyPattern(pattern);
@ -107,7 +106,8 @@ function applyNames() {
const root = CloudCmd.config('root'); const root = CloudCmd.config('root');
Promise.resolve(root) Promise
.resolve(root)
.then(rename(dir, from, to)) .then(rename(dir, from, to))
.then(refresh(to, nameIndex)) .then(refresh(to, nameIndex))
.catch(alert); .catch(alert);
@ -115,7 +115,9 @@ function applyNames() {
function _refresh(to, nameIndex, res) { function _refresh(to, nameIndex, res) {
if (res.status === 404) if (res.status === 404)
return res.text().then(reject); return res
.text()
.then(reject);
const currentName = to[nameIndex]; const currentName = to[nameIndex];
@ -127,7 +129,7 @@ function _refresh(to, nameIndex, res) {
function getDir(root, dir) { function getDir(root, dir) {
if (root === '/') if (root === '/')
return dir; return dir;
return root + dir; return root + dir;
} }
@ -158,6 +160,7 @@ function setMenu(event) {
return; return;
const editor = CloudCmd.Edit.getEditor(); const editor = CloudCmd.Edit.getEditor();
const options = { const options = {
beforeShow: (params) => { beforeShow: (params) => {
params.x -= 18; params.x -= 18;
@ -170,29 +173,29 @@ function setMenu(event) {
}; };
const menuData = { const menuData = {
'Save Ctrl+S' : () => { 'Save Ctrl+S': () => {
applyNames(); applyNames();
hide(); hide();
}, },
'Go To Line Ctrl+G' : () => { 'Go To Line Ctrl+G': () => {
editor.goToLine(); editor.goToLine();
}, },
'Cut Ctrl+X' : () => { 'Cut Ctrl+X': () => {
editor.cutToClipboard(); editor.cutToClipboard();
}, },
'Copy Ctrl+C' : () => { 'Copy Ctrl+C': () => {
editor.copyToClipboard(); editor.copyToClipboard();
}, },
'Paste Ctrl+V' : () => { 'Paste Ctrl+V': () => {
editor.pasteFromClipboard(); editor.pasteFromClipboard();
}, },
'Delete Del' : () => { 'Delete Del': () => {
editor.remove('right'); editor.remove('right');
}, },
'Select All Ctrl+A' : () => { 'Select All Ctrl+A': () => {
editor.selectAll(); editor.selectAll();
}, },
'Close Esc' : hide, 'Close Esc': hide,
}; };
const element = CloudCmd.Edit.getElement(); const element = CloudCmd.Edit.getElement();
@ -215,4 +218,3 @@ async function isChanged() {
const [, names] = await Dialog.confirm(msg); const [, names] = await Dialog.confirm(msg);
names && applyNames(); names && applyNames();
} }

View file

@ -33,7 +33,7 @@ const ConfigView = {
module.exports.init = async () => { module.exports.init = async () => {
const element = create(); const element = create();
await CloudCmd.View(); await CloudCmd.View();
await loadFiles(element); await loadFiles(element);
}; };
@ -47,9 +47,9 @@ function create() {
`, `,
notAppend: true, notAppend: true,
}); });
Element = element; Element = element;
return element; return element;
} }
@ -63,30 +63,29 @@ function initConfig(options = {}) {
...options, ...options,
...ConfigView, ...ConfigView,
}; };
if (!options.afterShow) if (!options.afterShow)
return config; return config;
checkFn('options.afterShow', options.afterShow); checkFn('options.afterShow', options.afterShow);
config.afterShow = () => { config.afterShow = () => {
ConfigView.afterShow(); ConfigView.afterShow();
options.afterShow(); options.afterShow();
}; };
return config; return config;
} }
module.exports.show = (options) => { module.exports.show = (options) => {
if (Loading) if (Loading)
return; return;
CloudCmd.View.show(Element, initConfig(options)); CloudCmd.View.show(Element, initConfig(options));
getEditor() getEditor().setOptions({
.setOptions({ fontSize: 16,
fontSize: 16, });
});
}; };
module.exports.getEditor = getEditor; module.exports.getEditor = getEditor;
@ -106,11 +105,11 @@ const loadFiles = async (element) => {
const socketPath = CloudCmd.prefix; const socketPath = CloudCmd.prefix;
const prefixSocket = `${CloudCmd.prefixSocket}/${EditorName}`; const prefixSocket = `${CloudCmd.prefixSocket}/${EditorName}`;
const url = `${prefix}/${EditorName}.js`; const url = `${prefix}/${EditorName}.js`;
time(`${Name} load`); time(`${Name} load`);
await loadJS(url); await loadJS(url);
const word = promisify(window[EditorName]); const word = promisify(window[EditorName]);
const [ed] = await tryToCatch(word, element, { const [ed] = await tryToCatch(word, element, {
maxSize, maxSize,
@ -118,9 +117,8 @@ const loadFiles = async (element) => {
prefixSocket, prefixSocket,
socketPath, socketPath,
}); });
timeEnd(`${Name} load`); timeEnd(`${Name} load`);
editor = ed; editor = ed;
Loading = false; Loading = false;
}; };

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
CloudCmd.Help = exports; CloudCmd.Help = exports;
const Images = require('../dom/images'); const Images = require('../dom/images');
@ -17,15 +16,12 @@ function show() {
const positionLoad = 'top'; const positionLoad = 'top';
const relative = true; const relative = true;
CloudCmd CloudCmd.Markdown.show('/HELP.md', {
.Markdown positionLoad,
.show('/HELP.md', { relative,
positionLoad, });
relative,
});
} }
function hide() { function hide() {
CloudCmd.View.hide(); CloudCmd.View.hide();
} }

View file

@ -4,7 +4,6 @@
/* global Util */ /* global Util */
/* global DOM */ /* global DOM */
/* global Console */ /* global Console */
CloudCmd.Konsole = exports; CloudCmd.Konsole = exports;
const exec = require('execon'); const exec = require('execon');
@ -14,10 +13,7 @@ const loadJS = require('load.js').js;
const createElement = require('@cloudcmd/create-element'); const createElement = require('@cloudcmd/create-element');
const Images = require('../dom/images'); const Images = require('../dom/images');
const { const {Dialog, CurrentInfo: Info} = DOM;
Dialog,
CurrentInfo:Info,
} = DOM;
const rmLastSlash = (a) => a.replace(/\/$/, '') || '/'; const rmLastSlash = (a) => a.replace(/\/$/, '') || '/';
@ -147,4 +143,3 @@ const load = async () => {
cancel: false, cancel: false,
}); });
}; };

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd */ /* global CloudCmd */
CloudCmd.Markdown = exports; CloudCmd.Markdown = exports;
const createElement = require('@cloudcmd/create-element'); const createElement = require('@cloudcmd/create-element');
@ -22,10 +21,7 @@ module.exports.hide = () => {
}; };
async function show(name, options = {}) { async function show(name, options = {}) {
const { const {positionLoad, relative} = options;
positionLoad,
relative,
} = options;
Images.show.load(positionLoad); Images.show.load(positionLoad);
@ -41,6 +37,7 @@ async function show(name, options = {}) {
}); });
const className = 'help'; const className = 'help';
const div = createElement('div', { const div = createElement('div', {
className, className,
innerHTML, innerHTML,
@ -48,4 +45,3 @@ async function show(name, options = {}) {
CloudCmd.View.show(div); CloudCmd.View.show(div);
} }

View file

@ -11,10 +11,7 @@ const {FS} = require('../../common/cloudfunc');
const {getIdBySrc} = require('../dom/load'); const {getIdBySrc} = require('../dom/load');
const RESTful = require('../dom/rest'); const RESTful = require('../dom/rest');
const { const {config, Key} = CloudCmd;
config,
Key,
} = CloudCmd;
const { const {
Buffer, Buffer,
@ -36,15 +33,16 @@ module.exports.ENABLED = false;
CloudCmd.Menu = exports; CloudCmd.Menu = exports;
module.exports.init = () => { module.exports.init = () => {
const { const {isAuth, menuDataFile} = getFileMenuData();
isAuth,
menuDataFile,
} = getFileMenuData();
const fm = DOM.getFM(); const fm = DOM.getFM();
const menuData = getMenuData(isAuth); const menuData = getMenuData(isAuth);
const options = getOptions({type: 'context'}); const options = getOptions({
const optionsFile = getOptions({type: 'file'}); type: 'context',
});
const optionsFile = getOptions({
type: 'file',
});
MenuContext = supermenu(fm, options, menuData); MenuContext = supermenu(fm, options, menuData);
MenuContextFile = supermenu(fm, optionsFile, menuDataFile); MenuContextFile = supermenu(fm, optionsFile, menuDataFile);
@ -77,7 +75,7 @@ function getPosition(position) {
x: position.x, x: position.x,
y: position.y, y: position.y,
}; };
return getCurrentPosition(); return getCurrentPosition();
} }
@ -105,9 +103,9 @@ function getOptions({type}) {
} }
const options = { const options = {
icon : true, icon: true,
beforeClose : Key.setBind, beforeClose: Key.setBind,
beforeShow : exec.with(beforeShow, func), beforeShow: exec.with(beforeShow, func),
beforeClick, beforeClick,
name, name,
}; };
@ -252,7 +250,9 @@ function uploadFromCloud() {
if (e) if (e)
return; return;
await CloudCmd.refresh({currentName}); await CloudCmd.refresh({
currentName,
});
}); });
} }
@ -292,7 +292,7 @@ function download(type) {
src = prefixURL + FS + encodedPath + '?download'; src = prefixURL + FS + encodedPath + '?download';
const element = createElement('iframe', { const element = createElement('iframe', {
id : id + '-' + date, id: id + '-' + date,
async: false, async: false,
className: 'hidden', className: 'hidden',
src, src,
@ -321,10 +321,7 @@ function getCurrentPosition() {
} }
function listener(event) { function listener(event) {
const { const {F9, ESC} = Key;
F9,
ESC,
} = Key;
const key = event.keyCode; const key = event.keyCode;
const isBind = Key.isBind(); const isBind = Key.isBind();

View file

@ -3,7 +3,6 @@
module.exports = (operation, from, to) => { module.exports = (operation, from, to) => {
if (!to) if (!to)
return `${operation} ${from}`; return `${operation} ${from}`;
return `${operation} ${from} -> ${to}`; return `${operation} ${from} -> ${to}`;
}; };

View file

@ -16,4 +16,3 @@ module.exports = (currentName, names, removedNames) => {
return nextNames[length - 1]; return nextNames[length - 1];
}; };

View file

@ -20,6 +20,7 @@ const getNextCurrentName = require('./get-next-current-name');
const removeQuery = (a) => a.replace(/\?.*/, ''); const removeQuery = (a) => a.replace(/\?.*/, '');
const Name = 'Operation'; const Name = 'Operation';
CloudCmd[Name] = exports; CloudCmd[Name] = exports;
const {config} = CloudCmd; const {config} = CloudCmd;
@ -61,10 +62,7 @@ module.exports.init = promisify((callback) => {
if (config('dropbox')) if (config('dropbox'))
return callback(); return callback();
const { const {prefix, prefixSocket} = CloudCmd;
prefix,
prefixSocket,
} = CloudCmd;
await loadAll(); await loadAll();
await initOperations(prefix, prefixSocket, callback); await initOperations(prefix, prefixSocket, callback);
@ -94,7 +92,10 @@ const onConnect = currify((fn, operator) => {
async function initOperations(prefix, socketPrefix, fn) { async function initOperations(prefix, socketPrefix, fn) {
socketPrefix = `${socketPrefix}/fileop`; socketPrefix = `${socketPrefix}/fileop`;
const operator = await fileop({prefix, socketPrefix}); const operator = await fileop({
prefix,
socketPrefix,
});
operator.on('connect', authCheck(operator, onConnect(fn))); operator.on('connect', authCheck(operator, onConnect(fn)));
} }
@ -109,7 +110,8 @@ function setOperations(operator) {
to, to,
}); });
operator.tar(from, to, names) operator
.tar(from, to, names)
.then(listen); .then(listen);
}; };
@ -123,7 +125,8 @@ function setOperations(operator) {
to, to,
}); });
operator.zip(from, to, names) operator
.zip(from, to, names)
.then(listen); .then(listen);
}; };
@ -137,7 +140,8 @@ function setOperations(operator) {
from, from,
}); });
operator.remove(from, files) operator
.remove(from, files)
.then(listen); .then(listen);
}; };
@ -151,7 +155,8 @@ function setOperations(operator) {
names, names,
}); });
operator.copy(from, to, names) operator
.copy(from, to, names)
.then(listen); .then(listen);
}; };
@ -164,7 +169,8 @@ function setOperations(operator) {
to, to,
}); });
operator.move(from, to, names) operator
.move(from, to, names)
.then(listen); .then(listen);
}; };
@ -178,7 +184,8 @@ function setOperations(operator) {
to, to,
}); });
operator.extract(from, to) operator
.extract(from, to)
.then(listen); .then(listen);
}; };
} }
@ -186,7 +193,7 @@ function setOperations(operator) {
function getPacker(type) { function getPacker(type) {
if (type === 'zip') if (type === 'zip')
return packZipFn; return packZipFn;
return packTarFn; return packTarFn;
} }
@ -274,6 +281,7 @@ async function promptDelete() {
const type = getType(isDir) + ' '; const type = getType(isDir) + ' ';
const name = DOM.getCurrentName(current); const name = DOM.getCurrentName(current);
msg = msgAsk + msgSel + type + name + '?'; msg = msgAsk + msgSel + type + name + '?';
} }
@ -333,20 +341,19 @@ async function _processFiles(options, data) {
let names = []; let names = [];
/* eslint no-multi-spaces: 0 */
if (data) { if (data) {
from = data.from; from = data.from;
to = data.to; to = data.to;
names = data.names; names = data.names;
panel = Info.panel; panel = Info.panel;
} else { } else {
from = Info.dirPath; from = Info.dirPath;
to = DOM.getNotCurrentDirPath(); to = DOM.getNotCurrentDirPath();
selFiles = DOM.getSelectedFiles(); selFiles = DOM.getSelectedFiles();
names = DOM.getFilenames(selFiles); names = DOM.getFilenames(selFiles);
data = {}; data = {};
shouldAsk = true; shouldAsk = true;
panel = Info.panelPassive; panel = Info.panelPassive;
} }
if (!names.length) if (!names.length)
@ -383,10 +390,14 @@ async function _processFiles(options, data) {
if (ok && !shouldAsk || !sameName) if (ok && !shouldAsk || !sameName)
return go(); return go();
const str = `"${ name }" already exist. Overwrite?`; const str = `"${name}" already exist. Overwrite?`;
const cancel = false; const cancel = false;
Dialog.confirm(str, {cancel}).then(go); Dialog
.confirm(str, {
cancel,
})
.then(go);
function go() { function go() {
showLoad(); showLoad();
@ -400,10 +411,7 @@ async function _processFiles(options, data) {
operation(files, async () => { operation(files, async () => {
await DOM.Storage.remove(from); await DOM.Storage.remove(from);
const { const {panel, panelPassive} = Info;
panel,
panelPassive,
} = Info;
if (!Info.isOnePanel) if (!Info.isOnePanel)
CloudCmd.refresh({ CloudCmd.refresh({
@ -429,10 +437,7 @@ function twopack(operation, type) {
let fileFrom; let fileFrom;
let currentName = Info.name; let currentName = Info.name;
const { const {path, dirPath} = Info;
path,
dirPath,
} = Info;
const activeFiles = DOM.getActiveFiles(); const activeFiles = DOM.getActiveFiles();
const names = DOM.getFilenames(activeFiles); const names = DOM.getFilenames(activeFiles);
@ -446,7 +451,7 @@ function twopack(operation, type) {
case 'extract': case 'extract':
op = extractFn; op = extractFn;
fileFrom = { fileFrom = {
from: path, from: path,
to: dirPath, to: dirPath,
}; };
@ -459,7 +464,7 @@ function twopack(operation, type) {
op = getPacker(type); op = getPacker(type);
if (names.length > 1) if (names.length > 1)
currentName = Info.dir; currentName = Info.dir;
currentName += DOM.getPackerExt(type); currentName += DOM.getPackerExt(type);
@ -487,9 +492,9 @@ async function prompt(msg, to, names) {
msg += ' '; msg += ' ';
if (names.length > 1) if (names.length > 1)
msg += `${n} file(s)`; msg += `${n} file(s)`;
else else
msg += `"${name}"`; msg += `"${name}"`;
msg += ' to'; msg += ' to';
@ -507,4 +512,3 @@ async function loadAll() {
Loaded = true; Loaded = true;
} }

View file

@ -17,4 +17,3 @@ function getExtension(name) {
return getExt(name); return getExt(name);
} }

View file

@ -26,4 +26,3 @@ test('cloudcmd: client: modules: operation: removeExtension: .bz2', (t) => {
t.equal(removeExtension(fullName), name, 'should remove .bz2'); t.equal(removeExtension(fullName), name, 'should remove .bz2');
t.end(); t.end();
}); });

View file

@ -1,16 +1,12 @@
'use strict'; 'use strict';
/* global DOM */ /* global DOM */
const forEachKey = require('for-each-key'); const forEachKey = require('for-each-key');
const wraptile = require('wraptile'); const wraptile = require('wraptile');
const format = require('./format'); const format = require('./format');
const { const {Dialog, Images} = DOM;
Dialog,
Images,
} = DOM;
module.exports = (options) => (emitter) => { module.exports = (options) => (emitter) => {
const { const {
@ -28,6 +24,7 @@ module.exports = (options) => (emitter) => {
emitter.abort(); emitter.abort();
const msg = `${operation} aborted`; const msg = `${operation} aborted`;
lastError = true; lastError = true;
Dialog.alert(msg, { Dialog.alert(msg, {
@ -85,4 +82,3 @@ module.exports = (options) => (emitter) => {
forEachKey(on, listeners); forEachKey(on, listeners);
}; };

View file

@ -1,11 +1,10 @@
'use strict'; 'use strict';
/* global DOM */ /* global DOM */
require('domtokenlist-shim'); require('domtokenlist-shim');
const scrollIntoViewIfNeeded = require('scroll-into-view-if-needed').default; const scrollIntoViewIfNeeded = require('scroll-into-view-if-needed').default;
DOM.scrollIntoViewIfNeeded = (el) => scrollIntoViewIfNeeded(el, { DOM.scrollIntoViewIfNeeded = (el) => scrollIntoViewIfNeeded(el, {
block: 'nearest', block: 'nearest',
}); });

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const mockRequire = require('mock-require'); const mockRequire = require('mock-require');
const {stopAll} = mockRequire; const {stopAll} = mockRequire;
@ -25,10 +23,9 @@ test('cloudcmd: client: polyfill: scrollIntoViewIfNeaded', (t) => {
mockRequire.stop('scroll-into-view-if-neaded'); mockRequire.stop('scroll-into-view-if-neaded');
global.DOM = DOM; global.DOM = DOM;
const args = [ const args = [el, {
el, { block: 'nearest',
block: 'nearest', }];
}];
stopAll(); stopAll();

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd, gritty */ /* global CloudCmd, gritty */
const {promisify} = require('es6-promisify'); const {promisify} = require('es6-promisify');
const tryToCatch = require('try-to-catch'); const tryToCatch = require('try-to-catch');
const fullstore = require('fullstore'); const fullstore = require('fullstore');
@ -14,10 +13,7 @@ const DOM = require('../dom');
const Images = require('../dom/images'); const Images = require('../dom/images');
const {Dialog} = DOM; const {Dialog} = DOM;
const { const {Key, config} = CloudCmd;
Key,
config,
} = CloudCmd;
CloudCmd.TerminalRun = exports; CloudCmd.TerminalRun = exports;
@ -152,4 +148,3 @@ function authCheck(spawn) {
Dialog.alert('Wrong credentials!'); Dialog.alert('Wrong credentials!');
}); });
} }

View file

@ -2,7 +2,6 @@
/* global CloudCmd */ /* global CloudCmd */
/* global gritty */ /* global gritty */
const tryToCatch = require('try-to-catch'); const tryToCatch = require('try-to-catch');
require('../../css/terminal.css'); require('../../css/terminal.css');
@ -15,10 +14,7 @@ const Images = require('../dom/images');
const loadParallel = load.parallel; const loadParallel = load.parallel;
const {Dialog} = DOM; const {Dialog} = DOM;
const { const {Key, config} = CloudCmd;
Key,
config,
} = CloudCmd;
CloudCmd.Terminal = exports; CloudCmd.Terminal = exports;
@ -123,4 +119,3 @@ function show() {
}, },
}); });
} }

View file

@ -66,4 +66,3 @@ function afterShow() {
uploadFiles(files); uploadFiles(files);
}); });
} }

View file

@ -8,4 +8,3 @@ module.exports = (menuFn) => {
return module.exports; return module.exports;
}; };

View file

@ -18,4 +18,3 @@ test('user-menu: getUserMenu', (t) => {
t.equal(key, 'F2 - Rename file'); t.equal(key, 'F2 - Rename file');
t.end(); t.end();
}); });

View file

@ -1,7 +1,6 @@
'use strict'; 'use strict';
/* global CloudCmd, DOM */ /* global CloudCmd, DOM */
require('../../../css/user-menu.css'); require('../../../css/user-menu.css');
const currify = require('currify'); const currify = require('currify');
@ -25,6 +24,7 @@ const loadCSS = load.css;
const sourceStore = fullstore(); const sourceStore = fullstore();
const Name = 'UserMenu'; const Name = 'UserMenu';
CloudCmd[Name] = module.exports; CloudCmd[Name] = module.exports;
const {Key} = CloudCmd; const {Key} = CloudCmd;
@ -52,7 +52,10 @@ async function show() {
Images.hide(); Images.hide();
if (error) if (error)
return Dialog.alert(getCodeFrame({error, source})); return Dialog.alert(getCodeFrame({
error,
source,
}));
sourceStore(source); sourceStore(source);
@ -118,10 +121,7 @@ const onButtonClick = wraptile(async (items, {value}) => {
}); });
const onKeyDown = currify(async ({keys, userMenu}, e) => { const onKeyDown = currify(async ({keys, userMenu}, e) => {
const { const {keyCode, target} = e;
keyCode,
target,
} = e;
const keyName = e.key.toUpperCase(); const keyName = e.key.toUpperCase();
@ -156,6 +156,7 @@ const runUserMenu = async (fn) => {
return; return;
const source = sourceStore(); const source = sourceStore();
return Dialog.alert(getCodeFrame({ return Dialog.alert(getCodeFrame({
error, error,
source, source,
@ -169,6 +170,7 @@ function getCodeFrame({error, source}) {
return error.message; return error.message;
const [line, column] = parseError(error); const [line, column] = parseError(error);
const start = { const start = {
line, line,
column, column,
@ -185,4 +187,3 @@ function getCodeFrame({error, source}) {
return `<pre>${frame}</pre>`; return `<pre>${frame}</pre>`;
} }

View file

@ -16,43 +16,42 @@ module.exports = (el, {key, keyCode}) => {
if (isDigit(key)) { if (isDigit(key)) {
store(Number(key)); store(Number(key));
} }
if (keyCode === DOWN || keyCode === J) { if (keyCode === DOWN || keyCode === J) {
const count = store(); const count = store();
store(1); store(1);
return down(el, count); return down(el, count);
} }
if (keyCode === UP || keyCode === K) { if (keyCode === UP || keyCode === K) {
const count = store(); const count = store();
store(1); store(1);
return up(el, count); return up(el, count);
} }
}; };
function down(el, count) { function down(el, count) {
const {length} = el; const {length} = el;
if (el.selectedIndex === length - 1) if (el.selectedIndex === length - 1)
el.selectedIndex = 0; el.selectedIndex = 0;
else else
el.selectedIndex += count; el.selectedIndex += count;
if (el.selectedIndex < 0) if (el.selectedIndex < 0)
el.selectedIndex = length - 1; el.selectedIndex = length - 1;
} }
function up(el, count) { function up(el, count) {
const {length} = el; const {length} = el;
if (!el.selectedIndex) if (!el.selectedIndex)
el.selectedIndex = length - 1; el.selectedIndex = length - 1;
else else
el.selectedIndex -= count; el.selectedIndex -= count;
if (el.selectedIndex < 0) if (el.selectedIndex < 0)
el.selectedIndex = 0; el.selectedIndex = 0;
} }

View file

@ -15,11 +15,11 @@ test('cloudcmd: user-menu: navigate: DOWN', (t) => {
length: 3, length: 3,
selectedIndex: 0, selectedIndex: 0,
}; };
navigate(el, { navigate(el, {
keyCode: DOWN, keyCode: DOWN,
}); });
t.equal(el.selectedIndex, 1); t.equal(el.selectedIndex, 1);
t.end(); t.end();
}); });
@ -29,11 +29,11 @@ test('cloudcmd: user-menu: navigate: J', (t) => {
length: 3, length: 3,
selectedIndex: 0, selectedIndex: 0,
}; };
navigate(el, { navigate(el, {
keyCode: J, keyCode: J,
}); });
t.equal(el.selectedIndex, 1); t.equal(el.selectedIndex, 1);
t.end(); t.end();
}); });
@ -43,11 +43,11 @@ test('cloudcmd: user-menu: navigate: DOWN: bottom', (t) => {
length: 3, length: 3,
selectedIndex: 2, selectedIndex: 2,
}; };
navigate(el, { navigate(el, {
keyCode: DOWN, keyCode: DOWN,
}); });
t.equal(el.selectedIndex, 0); t.equal(el.selectedIndex, 0);
t.end(); t.end();
}); });
@ -57,11 +57,11 @@ test('cloudcmd: user-menu: navigate: K', (t) => {
length: 3, length: 3,
selectedIndex: 2, selectedIndex: 2,
}; };
navigate(el, { navigate(el, {
keyCode: K, keyCode: K,
}); });
t.equal(el.selectedIndex, 1); t.equal(el.selectedIndex, 1);
t.end(); t.end();
}); });
@ -71,11 +71,11 @@ test('cloudcmd: user-menu: navigate: UP', (t) => {
length: 3, length: 3,
selectedIndex: 2, selectedIndex: 2,
}; };
navigate(el, { navigate(el, {
keyCode: UP, keyCode: UP,
}); });
t.equal(el.selectedIndex, 1); t.equal(el.selectedIndex, 1);
t.end(); t.end();
}); });
@ -85,11 +85,11 @@ test('cloudcmd: user-menu: navigate: UP: top', (t) => {
length: 3, length: 3,
selectedIndex: 0, selectedIndex: 0,
}; };
navigate(el, { navigate(el, {
keyCode: UP, keyCode: UP,
}); });
t.equal(el.selectedIndex, 2); t.equal(el.selectedIndex, 2);
t.end(); t.end();
}); });
@ -99,11 +99,11 @@ test('cloudcmd: user-menu: navigate', (t) => {
length: 3, length: 3,
selectedIndex: 0, selectedIndex: 0,
}; };
navigate(el, { navigate(el, {
keyCode: 0, keyCode: 0,
}); });
t.equal(el.selectedIndex, 0, 'should not change'); t.equal(el.selectedIndex, 0, 'should not change');
t.end(); t.end();
}); });
@ -113,16 +113,16 @@ test('cloudcmd: user-menu: navigate: DOWN: count', (t) => {
length: 3, length: 3,
selectedIndex: 0, selectedIndex: 0,
}; };
navigate(el, { navigate(el, {
keyCode: 53, keyCode: 53,
key: '5', key: '5',
}); });
navigate(el, { navigate(el, {
keyCode: DOWN, keyCode: DOWN,
}); });
t.equal(el.selectedIndex, 5); t.equal(el.selectedIndex, 5);
t.end(); t.end();
}); });
@ -132,16 +132,16 @@ test('cloudcmd: user-menu: navigate: J: count: to big', (t) => {
length: 3, length: 3,
selectedIndex: -Infinity, selectedIndex: -Infinity,
}; };
navigate(el, { navigate(el, {
keyCode: 53, keyCode: 53,
key: '5', key: '5',
}); });
navigate(el, { navigate(el, {
keyCode: J, keyCode: J,
}); });
t.equal(el.selectedIndex, 2); t.equal(el.selectedIndex, 2);
t.end(); t.end();
}); });
@ -151,16 +151,16 @@ test('cloudcmd: user-menu: navigate: K: count: to small', (t) => {
length: 3, length: 3,
selectedIndex: -Infinity, selectedIndex: -Infinity,
}; };
navigate(el, { navigate(el, {
keyCode: 53, keyCode: 53,
key: '5', key: '5',
}); });
navigate(el, { navigate(el, {
keyCode: K, keyCode: K,
}); });
t.equal(el.selectedIndex, 0); t.equal(el.selectedIndex, 0);
t.end(); t.end();
}); });

View file

@ -3,17 +3,11 @@
const isNumber = (a) => typeof a === 'number'; const isNumber = (a) => typeof a === 'number';
module.exports = (error) => { module.exports = (error) => {
const { const {lineNumber, columnNumber} = error;
lineNumber,
columnNumber,
} = error;
// thank you firefox // thank you firefox
if (isNumber(lineNumber) && isNumber(columnNumber)) if (isNumber(lineNumber) && isNumber(columnNumber))
return [ return [lineNumber, columnNumber];
lineNumber,
columnNumber,
];
const before = error.stack.indexOf('>'); const before = error.stack.indexOf('>');
const str = error.stack.slice(before + 1); const str = error.stack.slice(before + 1);
@ -27,4 +21,3 @@ module.exports = (error) => {
Number(column), Number(column),
]; ];
}; };

View file

@ -24,7 +24,9 @@ test('user-menu: parse-error: stack', (t) => {
at AsyncFunction.show (index.js:67) at AsyncFunction.show (index.js:67)
`; `;
const result = parseError({stack}); const result = parseError({
stack,
});
const expected = [1, 2]; const expected = [1, 2];
t.deepEqual(result, expected); t.deepEqual(result, expected);

View file

@ -32,4 +32,3 @@ module.exports = (userMenu) => {
settings, settings,
}; };
}; };

View file

@ -1,9 +1,7 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const parse = require('./parse-user-menu'); const parse = require('./parse-user-menu');
test('cloudcmd: user menu: parse', (t) => { test('cloudcmd: user menu: parse', (t) => {
@ -15,7 +13,10 @@ test('cloudcmd: user menu: parse', (t) => {
'_f': fn, '_f': fn,
}); });
const names = ['F2 - Rename file']; const names = [
'F2 - Rename file',
];
const keys = { const keys = {
F2: fn, F2: fn,
}; };

View file

@ -5,4 +5,3 @@ module.exports.runSelected = async (selectedItems, items, runUserMenu) => {
await runUserMenu(items[selected]); await runUserMenu(items[selected]);
} }
}; };

View file

@ -1,17 +1,13 @@
'use strict'; 'use strict';
const { const {test, stub} = require('supertape');
test,
stub,
} = require('supertape');
const {runSelected} = require('./run'); const {runSelected} = require('./run');
test('cloudcmd: client: user menu: run', async (t) => { test('cloudcmd: client: user menu: run', async (t) => {
const runUserMenu = stub(); const runUserMenu = stub();
const fn = stub(); const fn = stub();
const selected = [ const selected = ['hello'];
'hello',
];
const items = { const items = {
hello: fn, hello: fn,
@ -22,4 +18,3 @@ test('cloudcmd: client: user menu: run', async (t) => {
t.calledWith(runUserMenu, [fn]); t.calledWith(runUserMenu, [fn]);
t.end(); t.end();
}); });

View file

@ -1,7 +1,7 @@
'use strict';
/* global CloudCmd, DOM */ /* global CloudCmd, DOM */
'use strict';
require('../../../css/view.css'); require('../../../css/view.css');
const rendy = require('rendy'); const rendy = require('rendy');
@ -15,6 +15,7 @@ const createElement = require('@cloudcmd/create-element');
const {time} = require('../../../common/util'); const {time} = require('../../../common/util');
const {FS} = require('../../../common/cloudfunc'); const {FS} = require('../../../common/cloudfunc');
const { const {
isImage, isImage,
isAudio, isAudio,
@ -49,6 +50,7 @@ module.exports.hide = hide;
let Loading = false; let Loading = false;
const Name = 'View'; const Name = 'View';
CloudCmd[Name] = module.exports; CloudCmd[Name] = module.exports;
const Info = DOM.CurrentInfo; const Info = DOM.CurrentInfo;
@ -64,84 +66,88 @@ const Config = {
Images.hide(); Images.hide();
Key.unsetBind(); Key.unsetBind();
}, },
beforeClose: () => { beforeClose: () => {
Events.rmKey(listener); Events.rmKey(listener);
Key.setBind(); Key.setBind();
}, },
afterShow: () => { afterShow: () => {
El.focus(); El.focus();
}, },
onOverlayClick, onOverlayClick,
afterClose: noop, afterClose: noop,
autoSize: false, autoSize: false,
helpers: { helpers: {
title: {}, title: {},
}, },
}; };
module.exports._Config = Config; module.exports._Config = Config;
module.exports.init = async () => { module.exports.init = async () => {
await loadAll(); await loadAll();
const events = [ const events = [
'click', 'click',
'contextmenu', 'contextmenu',
]; ];
events.forEach(addEvent(Overlay, onOverlayClick)); events.forEach(addEvent(
Overlay,
onOverlayClick,
));
}; };
async function show(data, options = {}) { async function show(data, options = {}) {
const prefixURL = CloudCmd.prefixURL + FS; const prefixURL = CloudCmd.prefixURL + FS;
if (Loading) if (Loading)
return; return;
if (!options || options.bindKeys !== false) if (!options || options.bindKeys !== false)
Events.addKey(listener); Events.addKey(listener);
El = createElement('div', { El = createElement('div', {
className: 'view', className: 'view',
notAppend: true, notAppend: true,
}); });
El.tabIndex = 0; El.tabIndex = 0;
if (data) { if (data) {
if (isArray(data)) if (isArray(data))
El.append(...data); El.append(...data);
else else
El.append(data); El.append(data);
modal.open(El, initConfig(options)); modal.open(El, initConfig(options));
return; return;
} }
Images.show.load(); Images.show.load();
const path = prefixURL + Info.path; const path = prefixURL + Info.path;
const type = options.raw ? '' : await getType(path); const type = options.raw ? '' : await getType(path);
switch(type) { switch(type) {
default: default:
return await viewFile(); return await viewFile();
case 'markdown': case 'markdown':
return await CloudCmd.Markdown.show(Info.path); return await CloudCmd.Markdown.show(Info.path);
case 'html': case 'html':
return viewHtml(path); return viewHtml(path);
case 'image': case 'image':
return viewImage(Info.path, prefixURL); return viewImage(Info.path, prefixURL);
case 'media': case 'media':
return await viewMedia(path); return await viewMedia(path);
case 'pdf': case 'pdf':
return viewPDF(path); return viewPDF(path);
} }
@ -154,11 +160,11 @@ function createIframe(src) {
width: '100%', width: '100%',
height: '100%', height: '100%',
}); });
element.addEventListener('load', () => { element.addEventListener('load', () => {
element.contentWindow.addEventListener('keydown', listener); element.contentWindow.addEventListener('keydown', listener);
}); });
return element; return element;
} }
@ -169,21 +175,21 @@ function viewHtml(src) {
function viewPDF(src) { function viewPDF(src) {
const element = createIframe(src); const element = createIframe(src);
const options = assign({}, Config); const options = assign({}, Config);
if (CloudCmd.config('showFileName')) if (CloudCmd.config('showFileName'))
options.title = Info.name; options.title = Info.name;
modal.open(element, options); modal.open(element, options);
} }
async function viewMedia(path) { async function viewMedia(path) {
const [e, element] = await getMediaElement(path); const [e, element] = await getMediaElement(path);
if (e) if (e)
return alert(e); return alert(e);
const allConfig = { const allConfig = {
...Config, ...Config,
...{ ...{
@ -195,22 +201,22 @@ async function viewMedia(path) {
}, },
}, },
}; };
modal.open(element, allConfig); modal.open(element, allConfig);
} }
async function viewFile() { async function viewFile() {
const [error, data] = await Info.getData(); const [error, data] = await Info.getData();
if (error) if (error)
return Images.hide(); return Images.hide();
const element = document.createTextNode(data); const element = document.createTextNode(data);
const options = Config; const options = Config;
if (CloudCmd.config('showFileName')) if (CloudCmd.config('showFileName'))
options.title = Info.name; options.title = Info.name;
El.append(element); El.append(element);
modal.open(El, options); modal.open(El, options);
} }
@ -220,25 +226,26 @@ const copy = (a) => assign({}, a);
module.exports._initConfig = initConfig; module.exports._initConfig = initConfig;
function initConfig(options) { function initConfig(options) {
const config = copy(Config); const config = copy(Config);
if (!options) if (!options)
return config; return config;
const names = Object.keys(options); const names = Object.keys(options);
for (const name of names) { for (const name of names) {
const isConfig = Boolean(config[name]); const isConfig = Boolean(config[name]);
const item = options[name]; const item = options[name];
if (!isFn(item) || !isConfig) { if (!isFn(item) || !isConfig) {
config[name] = options[name]; config[name] = options[name];
continue; continue;
} }
const fn = config[name]; const fn = config[name];
config[name] = series(fn, item); config[name] = series(fn, item);
} }
return config; return config;
} }
@ -252,59 +259,60 @@ function viewImage(path, prefixURL) {
href: `${prefixURL}${path}`, href: `${prefixURL}${path}`,
title: encode(basename(path)), title: encode(basename(path)),
}); });
const names = Info.files const names = Info
.files
.map(DOM.getCurrentPath) .map(DOM.getCurrentPath)
.filter(isSupportedImage); .filter(isSupportedImage);
const titles = names const titles = names.map(makeTitle);
.map(makeTitle);
const index = names.indexOf(Info.path); const index = names.indexOf(Info.path);
const imageConfig = { const imageConfig = {
index, index,
autoSize : true, autoSize: true,
arrows : true, arrows: true,
keys : true, keys: true,
helpers : { helpers: {
title : {}, title: {},
}, },
}; };
const config = { const config = {
...Config, ...Config,
...imageConfig, ...imageConfig,
}; };
modal.open(titles, config); modal.open(titles, config);
} }
async function getMediaElement(src) { async function getMediaElement(src) {
check(src); check(src);
const [error, template] = await tryToCatch(Files.get, 'view/media-tmpl'); const [error, template] = await tryToCatch(Files.get, 'view/media-tmpl');
if (error) if (error)
return [error]; return [error];
const {name} = Info; const {name} = Info;
if (!TemplateAudio) if (!TemplateAudio)
TemplateAudio = template; TemplateAudio = template;
const is = isAudio(name); const is = isAudio(name);
const type = is ? 'audio' : 'video'; const type = is ? 'audio' : 'video';
const innerHTML = rendy(TemplateAudio, { const innerHTML = rendy(TemplateAudio, {
src, src,
type, type,
name, name,
}); });
const element = createElement('div', { const element = createElement('div', {
innerHTML, innerHTML,
}); });
return [null, element]; return [null, element];
} }
@ -319,9 +327,9 @@ function check(src) {
*/ */
async function loadAll() { async function loadAll() {
const {DIR_DIST} = CloudCmd; const {DIR_DIST} = CloudCmd;
time(`${Name} load`); time(`${Name} load`);
Loading = true; Loading = true;
await loadCSS(`${DIR_DIST}/view.css`); await loadCSS(`${DIR_DIST}/view.css`);
Loading = false; Loading = false;
@ -332,32 +340,29 @@ function onOverlayClick(event) {
x: event.clientX, x: event.clientX,
y: event.clientY, y: event.clientY,
}; };
setCurrentByPosition(position); setCurrentByPosition(position);
} }
function setCurrentByPosition(position) { function setCurrentByPosition(position) {
const element = DOM.getCurrentByPosition(position); const element = DOM.getCurrentByPosition(position);
if (!element) if (!element)
return; return;
const { const {files, filesPassive} = Info;
files,
filesPassive,
} = Info;
const isFiles = files.includes(element); const isFiles = files.includes(element);
const isFilesPassive = filesPassive.includes(element); const isFilesPassive = filesPassive.includes(element);
if (!isFiles && !isFilesPassive) if (!isFiles && !isFilesPassive)
return; return;
const isCurrent = DOM.isCurrentFile(element); const isCurrent = DOM.isCurrentFile(element);
if (isCurrent) if (isCurrent)
return; return;
DOM.setCurrentFile(element); DOM.setCurrentFile(element);
} }
@ -365,4 +370,3 @@ function listener({keyCode}) {
if (keyCode === Key.ESC) if (keyCode === Key.ESC)
hide(); hide();
} }

View file

@ -64,12 +64,10 @@ test('cloudcmd: client: view: html', (t) => {
open, open,
}); });
const { const {_viewHtml, _Config} = reRequire('.');
_viewHtml,
_Config,
} = reRequire('.');
const src = '/hello.html'; const src = '/hello.html';
_viewHtml(src); _viewHtml(src);
global.CloudCmd = CloudCmd; global.CloudCmd = CloudCmd;
@ -89,6 +87,7 @@ test('cloudcmd: client: view: createIframe', (t) => {
const el = { const el = {
addEventListener, addEventListener,
}; };
const createElement = stub().returns(el); const createElement = stub().returns(el);
mockRequire('@cloudcmd/create-element', createElement); mockRequire('@cloudcmd/create-element', createElement);
@ -114,6 +113,7 @@ test('cloudcmd: client: view: createIframe: returns', (t) => {
const el = { const el = {
addEventListener, addEventListener,
}; };
const createElement = stub().returns(el); const createElement = stub().returns(el);
mockRequire('@cloudcmd/create-element', createElement); mockRequire('@cloudcmd/create-element', createElement);

View file

@ -69,9 +69,10 @@ async function detectType(path) {
for (const [name, value] of headers) { for (const [name, value] of headers) {
if (name === 'content-type') if (name === 'content-type')
return `.${value.split('/').pop()}`; return `.${value
.split('/')
.pop()}`;
} }
return ''; return '';
} }

View file

@ -23,15 +23,14 @@ test('cloudcmd: client: view: types: detectType', async (t) => {
}); });
const originalFetch = global.fetch; const originalFetch = global.fetch;
global.fetch = fetch; global.fetch = fetch;
await _detectType('/hello'); await _detectType('/hello');
global.fetch = originalFetch; global.fetch = originalFetch;
const expected = [ const expected = ['/hello', {
'/hello', { method: 'HEAD',
method: 'HEAD', }];
},
];
t.calledWith(fetch, expected); t.calledWith(fetch, expected);
t.end(); t.end();
@ -39,6 +38,7 @@ test('cloudcmd: client: view: types: detectType', async (t) => {
test('cloudcmd: client: view: types: detectType: found', async (t) => { test('cloudcmd: client: view: types: detectType: found', async (t) => {
const originalFetch = global.fetch; const originalFetch = global.fetch;
global.fetch = stub().returns({ global.fetch = stub().returns({
headers: [ headers: [
['content-type', 'image/png'], ['content-type', 'image/png'],
@ -51,4 +51,3 @@ test('cloudcmd: client: view: types: detectType: found', async (t) => {
t.equal(result, '.png'); t.equal(result, '.png');
t.end(); t.end();
}); });

View file

@ -5,10 +5,7 @@ const DOM = require('./dom');
const Info = DOM.CurrentInfo; const Info = DOM.CurrentInfo;
const { const {sort, order} = CloudCmd;
sort,
order,
} = CloudCmd;
const position = DOM.getPanelPosition(); const position = DOM.getPanelPosition();
@ -17,10 +14,7 @@ let sortPrevious = sort[position];
const {getPanel} = DOM; const {getPanel} = DOM;
CloudCmd.sortPanel = (name, panel = getPanel()) => { CloudCmd.sortPanel = (name, panel = getPanel()) => {
const position = panel const position = panel.dataset.name.replace('js-', '');
.dataset
.name
.replace('js-', '');
if (name !== sortPrevious) { if (name !== sortPrevious) {
order[position] = 'asc'; order[position] = 'asc';
@ -40,4 +34,3 @@ CloudCmd.sortPanel = (name, panel = getPanel()) => {
noCurrent, noCurrent,
}); });
}; };

View file

@ -25,7 +25,7 @@ async function registerSW(prefix) {
if (e) if (e)
return null; return null;
return sw; return sw;
} }
@ -33,4 +33,3 @@ async function unregisterSW(prefix) {
const reg = await registerSW(prefix); const reg = await registerSW(prefix);
reg?.unregister(prefix); reg?.unregister(prefix);
} }

View file

@ -114,4 +114,3 @@ test('sw: register: unregisterSW', async (t, {location, navigator}) => {
t.calledWith(register, ['/hello/sw.js'], 'should call register'); t.calledWith(register, ['/hello/sw.js'], 'should call register');
t.end(); t.end();
}); });

View file

@ -45,7 +45,7 @@ const createRequest = (a) => new Request(a, {
const getRequest = (a, request) => { const getRequest = (a, request) => {
if (a !== '/') if (a !== '/')
return request; return request;
return createRequest('/'); return createRequest('/');
}; };
@ -97,4 +97,3 @@ async function addToCache(request, response) {
const cache = await caches.open(NAME); const cache = await caches.open(NAME);
return cache.put(request, response); return cache.put(request, response);
} }

View file

@ -3,7 +3,7 @@
module.exports.btoa = (str) => { module.exports.btoa = (str) => {
if (typeof btoa === 'function') if (typeof btoa === 'function')
return btoa(str); return btoa(str);
return Buffer return Buffer
.from(str) .from(str)
.toString('base64'); .toString('base64');
@ -12,9 +12,8 @@ module.exports.btoa = (str) => {
module.exports.atob = (str) => { module.exports.atob = (str) => {
if (typeof atob === 'function') if (typeof atob === 'function')
return atob(str); return atob(str);
return Buffer return Buffer
.from(str, 'base64') .from(str, 'base64')
.toString('binary'); .toString('binary');
}; };

Some files were not shown because too many files have changed in this diff Show more