65
ChangeLog
|
|
@ -1,10 +1,71 @@
|
|||
2013.02.13, v0.8.1
|
||||
2014.03.03, v0.8.2
|
||||
|
||||
fix:
|
||||
- (style) .loading: spinner size
|
||||
- (server) createRedirect: add sslPort
|
||||
- (server) http -> procol
|
||||
- (server) start: http -> HTTP
|
||||
- (dom) promptDeleteSelected: pCurrentFile -> current
|
||||
- (rest) onDelete: func(null, body) -> func
|
||||
- (rest) onStat: add var
|
||||
- (cloudcmd) change index path
|
||||
- (server) start: url -> URL
|
||||
- (server) start: SSLPort -> sslPort
|
||||
- (server) start: Port -> port
|
||||
- (dom) getCurrentDirPath: "," -> ";"
|
||||
- (dom) renameCurrent: rm dir listing from Storage
|
||||
- (client) loadDir: do not change dir after fail load
|
||||
- (cloudcmd) route: add name
|
||||
- (style) .files height: 95% -> 85%
|
||||
- (dom) setCurrent: set id of li to
|
||||
- (client) ajaxLoad: do not save path to history if content not load
|
||||
- (path) #js-path -> .js-path: 2 pathes on a page
|
||||
|
||||
feature:
|
||||
- (package) rm pty.js
|
||||
- (view) rm spinner from doBefore, add to view
|
||||
- (package) add pty.js
|
||||
- (package) minify: v0.2.5 -> 0.2.6
|
||||
- (client) initModules doBefore: add filepicker
|
||||
- (menu) DOM.Images -> Images, "From Cloud" -> "From FilePicker"
|
||||
- (index) change favicon
|
||||
- (favicon) add
|
||||
- (ext) .ico: vnd.microsoft.icon -> x-icon
|
||||
- (index) hide .path-icon when no js
|
||||
- (style) .loading top: 1px -> 2px
|
||||
- (storage) get: ret -> this
|
||||
- (favicon) optimize img
|
||||
- (cloudcmd) optimize image
|
||||
- (deleteSelected) rm param notSet
|
||||
- (fs) add fs folder
|
||||
- (style) height < 800px: .fm height: 74%
|
||||
- (style) set bigger font for width < 600px
|
||||
- (style)if height < 800px: .fm height 85%
|
||||
- (css) html: change height
|
||||
- (style) show only part of name is to long
|
||||
- (index) add style for no js: hide keys, show one panel
|
||||
- (style) .cmd-button: height: 30px
|
||||
- (polyfill) rm localStorage
|
||||
- (refactor) .js-left -> [data=js-left]
|
||||
- (rest) add onFSPut
|
||||
- (style) change .fm height to 75% on small screen heights
|
||||
- (style) change name color on small screens
|
||||
- (style) rm duplicate .fm-header
|
||||
- (edit) add save on F2
|
||||
- (storage) change to async
|
||||
- (storage) add
|
||||
- (dom) add storage
|
||||
- (listeners) change touchend
|
||||
- (key) setCurrentByLatter: add numbers
|
||||
|
||||
|
||||
2014.02.13, v0.8.1
|
||||
|
||||
fix:
|
||||
- (commander) changeUIDToName: doesn't work on win
|
||||
|
||||
|
||||
2013.02.13, v0.8.0
|
||||
2014.02.13, v0.8.0
|
||||
|
||||
fix:
|
||||
- (test) template
|
||||
|
|
|
|||
65
HELP.md
|
|
@ -1,15 +1,17 @@
|
|||
Cloud Commander v0.8.1 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL]
|
||||
Cloud Commander v0.8.2 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![License][LicenseIMGURL]][LicenseURL] [![Flattr][FlattrIMGURL]][FlattrURL]
|
||||
===============
|
||||
###[Main][MainURL] [Blog][BlogURL] Live(![IO][IO_LIVE_IMG] [IO][IOURL], ![JitSu][JitSu_LIVE_IMG] [JitSu][JitSuURL], ![Heroku][Heroku_LIVE_IMG] [Heroku][HerokuURL])
|
||||
[NPMIMGURL]: https://badge.fury.io/js/cloudcmd.png
|
||||
[BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master
|
||||
[NPMIMGURL]: https://img.shields.io/npm/v/cloudcmd.svg
|
||||
[BuildStatusIMGURL]: https://api.travis-ci.org/coderaiser/cloudcmd.png?branch=dev
|
||||
[DependencyStatusIMGURL]: https://gemnasium.com/coderaiser/cloudcmd.png
|
||||
[FlattrIMGURL]: https://api.flattr.com/button/flattr-badge-large.png
|
||||
[NPM_INFO_IMG]: https://nodei.co/npm/cloudcmd.png
|
||||
[FlattrIMGURL]: https://img.shields.io/badge/flattr-donate-317BF9.svg
|
||||
[LicenseIMGURL]: https://img.shields.io/badge/license-MIT-317BF9.svg
|
||||
[NPM_INFO_IMG]: http://nodei.co/npm/cloudcmd.png
|
||||
[NPMURL]: https://npmjs.org/package/cloudcmd "npm"
|
||||
[BuildStatusURL]: http://travis-ci.org/coderaiser/cloudcmd "Build Status"
|
||||
[BuildStatusURL]: https://travis-ci.org/coderaiser/cloudcmd "Build Status"
|
||||
[DependencyStatusURL]: https://gemnasium.com/coderaiser/cloudcmd "Dependency Status"
|
||||
[FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software "flattr"
|
||||
[LicenseURL]: https://tldrlegal.com/license/mit-license "MIT License"
|
||||
[MainURL]: http://cloudcmd.io "Main"
|
||||
[BlogURL]: http://blog.cloudcmd.io "Blog"
|
||||
[IOURL]: http://io.cloudcmd.io "IO"
|
||||
|
|
@ -19,53 +21,32 @@ Cloud Commander v0.8.1 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status]
|
|||
[JitSu_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.jit.su/fs?json "JitSu"
|
||||
[HEROKU_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.herokuapp.com/fs?json "Heroku"
|
||||
|
||||
**Cloud Commander** - cloud file manager with console and editor.
|
||||
**Cloud Commander** - cloud file manager with console and editor. Will help you: **create**, **edit**, **move** and **delete files** and **folders** in your favorite browser from any computer. File manager has two parts:
|
||||
- **client** (with nice and simple interface)
|
||||
- **server** (based on Node.js).
|
||||
|
||||

|
||||
|
||||
[![Flattr][FlattrIMGURL]][FlattrURL]
|
||||
|
||||
Benefits
|
||||
---------------
|
||||
|
||||
- Open Source.
|
||||
- Open Source (**MIT License**).
|
||||
- Has 2 classic ortodox panels.
|
||||
- Works on Windows, Linux and Mac OS.
|
||||
- Could be used local or remotly.
|
||||
- Has nice console and editor.
|
||||
- Wrote on JavaScript/Node.js.
|
||||
- Works in browser.
|
||||
|
||||
Install
|
||||
---------------
|
||||
[![NPM_INFO][NPM_INFO_IMG]][NPMURL]
|
||||
|
||||
Installing **Cloud Commander** is very simple.
|
||||
All you need is
|
||||
The installation of file manager is very simple.
|
||||
|
||||
- install [node.js](http://nodejs.org/ "node.js")
|
||||
- [download](https://github.com/coderaiser/cloudcmd/archive/master.zip)
|
||||
and unpack or just clone repository from github:
|
||||
- install [node.js](http://nodejs.org/ "node.js") if you still have not.
|
||||
- install ```cloudcmd``` via ```npm``` with one simple command.
|
||||
|
||||
```
|
||||
git clone git://github.com/coderaiser/cloudcmd.git
|
||||
cd cloudcmd
|
||||
npm install
|
||||
node cloudcmd
|
||||
```
|
||||
or install in npm:
|
||||
|
||||
```
|
||||
npm install cloudcmd -g
|
||||
cloudcmd
|
||||
```
|
||||
|
||||
Additional modules
|
||||
---------------
|
||||
**Cloud Commander** could work without any modules installed.
|
||||
But for console, minification, file system operations etc, recommended
|
||||
install additional modules with next commnad (type in **Cloud Commander**'s directory):
|
||||
|
||||
npm install
|
||||
![NPM_INFO][NPM_INFO_IMG]
|
||||
|
||||
Hot keys
|
||||
---------------
|
||||
|
|
@ -77,7 +58,7 @@ Hot keys
|
|||
- **F5** - copy
|
||||
- **F6** - rename/move
|
||||
- **F7** - new dir
|
||||
- **F7** + **shift** = new file
|
||||
- **F7** + **shift** - new file
|
||||
- **F8, Delete** - remove current file
|
||||
- **F9** - menu
|
||||
- **F10** - config
|
||||
|
|
@ -97,7 +78,8 @@ Hot keys
|
|||
- **Home** - to begin of list
|
||||
- **End** - to end of list
|
||||
- **Shift + Delete** - remove without prompt
|
||||
- **Insert** - select current file
|
||||
- **Space** - select current file (and show size of directory)
|
||||
- **Insert** - select current file (and move to next)
|
||||
- **Shift + F10** - context menu
|
||||
- **~** - console
|
||||
- **Ctrl + Click** - open file on new tab
|
||||
|
|
@ -340,6 +322,7 @@ Additional modules list
|
|||
To extend capabilities of file manager next modules used:
|
||||
|
||||
- [Ace] [AceURL]
|
||||
- [Minify] [MinifyURL]
|
||||
- [FancyBox] [FancyBoxURL]
|
||||
- [jQuery-contextMenu] [jQuery-contextMenuURL]
|
||||
- [jq-console] [jq-consoleURL]
|
||||
|
|
@ -351,6 +334,7 @@ To extend capabilities of file manager next modules used:
|
|||
- [fs-extra] [fs-extraURL]
|
||||
|
||||
[AceURL]: http://ace.ajax.org/ "Ace"
|
||||
[MinifyURL]: http://coderaiser.github.io/minify "Minify"
|
||||
[FancyBoxURL]: //github.com/fancyapps/fancyBox "FancyBox"
|
||||
[jQuery-contextMenuURL]: //github.com/medialize/jQuery-contextMenu "jQuery-contextMenu"
|
||||
[jq-consoleURL]: //github.com/replit/jq-console "jq-console"
|
||||
|
|
@ -379,6 +363,7 @@ so to get it you should type a couple more commands:
|
|||
|
||||
Version history
|
||||
---------------
|
||||
- *2014.03.03*, **[v0.8.2](//github.com/cloudcmd/archive/raw/master/cloudcmd-v0.8.2.zip)**
|
||||
- *2014.02.13*, **[v0.8.1](//github.com/cloudcmd/archive/raw/master/cloudcmd-v0.8.1.zip)**
|
||||
- *2014.02.13*, **[v0.8.0](//github.com/cloudcmd/archive/raw/master/cloudcmd-v0.8.0.zip)**
|
||||
- *2013.12.09*, **[v0.7.0](//github.com/cloudcmd/archive/raw/master/cloudcmd-v0.7.0.zip)**
|
||||
|
|
@ -398,10 +383,6 @@ Version history
|
|||
- *2012.07.11*, **[v0.1.1](//github.com/cloudcmd/archive/raw/master/cloudcmd-v0.1.1.zip)**
|
||||
- *2012.07.09*, **[v0.1.0](//github.com/cloudcmd/archive/raw/master/cloudcmd-v0.1.0.zip)**
|
||||
|
||||
License
|
||||
---------------
|
||||
MIT [license](LICENSE "license").
|
||||
|
||||
Special Thanks
|
||||
---------------
|
||||
|
||||
|
|
|
|||
18
README.md
|
|
@ -1,15 +1,17 @@
|
|||
Cloud Commander v0.8.1 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL]
|
||||
Cloud Commander v0.8.2 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![License][LicenseIMGURL]][LicenseURL] [![Flattr][FlattrIMGURL]][FlattrURL]
|
||||
===============
|
||||
###[Main][MainURL] [Blog][BlogURL] Live(![IO][IO_LIVE_IMG] [IO][IOURL], ![JitSu][JitSu_LIVE_IMG] [JitSu][JitSuURL], ![Heroku][Heroku_LIVE_IMG] [Heroku][HerokuURL])
|
||||
[NPMIMGURL]: https://badge.fury.io/js/cloudcmd.png
|
||||
[BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master
|
||||
[NPMIMGURL]: https://img.shields.io/npm/v/cloudcmd.svg
|
||||
[BuildStatusIMGURL]: https://api.travis-ci.org/coderaiser/cloudcmd.png?branch=dev
|
||||
[DependencyStatusIMGURL]: https://gemnasium.com/coderaiser/cloudcmd.png
|
||||
[FlattrIMGURL]: http://api.flattr.com/button/flattr-badge-large.png
|
||||
[NPM_INFO_IMG]: https://nodei.co/npm/cloudcmd.png?downloads=true&&stars
|
||||
[FlattrIMGURL]: https://img.shields.io/badge/flattr-donate-317BF9.svg
|
||||
[LicenseIMGURL]: https://img.shields.io/badge/license-MIT-317BF9.svg
|
||||
[NPM_INFO_IMG]: https://nodei.co/npm/cloudcmd.png
|
||||
[NPMURL]: https://npmjs.org/package/cloudcmd "npm"
|
||||
[BuildStatusURL]: http://travis-ci.org/coderaiser/cloudcmd "Build Status"
|
||||
[BuildStatusURL]: https://travis-ci.org/coderaiser/cloudcmd "Build Status"
|
||||
[DependencyStatusURL]: https://gemnasium.com/coderaiser/cloudcmd "Dependency Status"
|
||||
[FlattrURL]: https://flattr.com/submit/auto?user_id=coderaiser&url=github.com/coderaiser/cloudcmd&title=cloudcmd&language=&tags=github&category=software "flattr"
|
||||
[LicenseURL]: https://tldrlegal.com/license/mit-license "MIT License"
|
||||
[MainURL]: http://cloudcmd.io "Main"
|
||||
[BlogURL]: http://blog.cloudcmd.io "Blog"
|
||||
[IOURL]: http://io.cloudcmd.io "IO"
|
||||
|
|
@ -21,6 +23,4 @@ Cloud Commander v0.8.1 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status]
|
|||
|
||||
**Cloud Commander** - cloud file manager with console and editor.
|
||||
|
||||

|
||||
|
||||
[![Flattr][FlattrIMGURL]][FlattrURL]
|
||||

|
||||
|
|
|
|||
205
cloudcmd.js
|
|
@ -22,16 +22,17 @@
|
|||
Minify = main.minify,
|
||||
Config = main.config,
|
||||
|
||||
INDEX_PATH = HTMLDIR + 'index.html',
|
||||
CONFIG_PATH = JSONDIR + 'config.json',
|
||||
|
||||
KEY = DIR + 'ssl/ssl.key',
|
||||
KEY = DIR + 'ssl/ssl.key',
|
||||
CERT = DIR + 'ssl/ssl.crt',
|
||||
|
||||
FILE_TMPL = HTMLDIR + 'file.html',
|
||||
PANEL_TMPL = HTMLDIR + 'panel.html',
|
||||
PATH_TMPL = HTMLDIR + 'path.html',
|
||||
LINK_TMPL = HTMLDIR + 'link.html',
|
||||
HTML_FS_DIR = HTMLDIR + 'fs/',
|
||||
INDEX_PATH = HTML_FS_DIR + 'index.html',
|
||||
FILE_TMPL = HTML_FS_DIR + 'file.html',
|
||||
PANEL_TMPL = HTML_FS_DIR + 'panel.html',
|
||||
PATH_TMPL = HTML_FS_DIR + 'path.html',
|
||||
LINK_TMPL = HTML_FS_DIR + 'link.html',
|
||||
|
||||
FileTemplate, PanelTemplate, PathTemplate, LinkTemplate,
|
||||
|
||||
|
|
@ -83,29 +84,29 @@
|
|||
});
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* init and process of appcache if it allowed in config
|
||||
*/
|
||||
function appCacheProcessing() {
|
||||
var lFONT_REMOTE = '//themes.googleusercontent.com/static/fonts/droidsansmono/v4/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff',
|
||||
lFONT_LOCAL = './font/DroidSansMono.woff',
|
||||
lJQUERY_REMOTE = '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js',
|
||||
lJQUERY_LOCAL = './lib/client/jquery.js',
|
||||
lFiles = [{}, {}];
|
||||
var FONT_REMOTE = '//themes.googleusercontent.com/static/fonts/droidsansmono/v4/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff',
|
||||
FONT_LOCAL = './font/DroidSansMono.woff',
|
||||
JQUERY_REMOTE = '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js',
|
||||
JQUERY_LOCAL = './lib/client/jquery.js',
|
||||
files = [{}, {}];
|
||||
|
||||
lFiles[0][lFONT_REMOTE] = lFONT_LOCAL;
|
||||
lFiles[1][lJQUERY_REMOTE] = lJQUERY_LOCAL;
|
||||
files[0][FONT_REMOTE] = FONT_LOCAL;
|
||||
files[1][JQUERY_REMOTE] = JQUERY_LOCAL;
|
||||
|
||||
AppCache.addFiles(lFiles);
|
||||
AppCache.addFiles(files);
|
||||
AppCache.createManifest();
|
||||
}
|
||||
|
||||
|
||||
function init() {
|
||||
var lServerDir, lArg, lParams, lFiles;
|
||||
var serverDir, params, filesList, isContain, argvFirst,
|
||||
argv = process.argv;
|
||||
|
||||
if (update)
|
||||
update.get();
|
||||
|
|
@ -115,80 +116,80 @@
|
|||
* (usually /) to it.
|
||||
* argv[1] - is always script name
|
||||
*/
|
||||
lServerDir = path.dirname(process.argv[1]) + '/';
|
||||
serverDir = path.dirname(argv[1]) + '/';
|
||||
|
||||
if (DIR !== lServerDir) {
|
||||
if (DIR !== serverDir) {
|
||||
Util.log('current dir: ' + DIR);
|
||||
process.chdir(lServerDir);
|
||||
process.chdir(serverDir);
|
||||
}
|
||||
|
||||
Util.log('server dir: ' + lServerDir);
|
||||
Util.log('server dir: ' + serverDir);
|
||||
|
||||
/* if command line parameter testing resolved
|
||||
* setting config to testing, so server
|
||||
* not created, just init and
|
||||
* all logs writed to screen */
|
||||
lArg = process.argv;
|
||||
lArg = lArg[lArg.length - 1];
|
||||
argvFirst = argv[argv.length - 1];
|
||||
isContain = Util.isContainStr(argvFirst, 'test');
|
||||
|
||||
if ( lArg === 'test' || lArg === 'test\r') {
|
||||
Util.log(process.argv);
|
||||
if (isContain) {
|
||||
Util.log(argv);
|
||||
Config.server = false;
|
||||
}
|
||||
|
||||
if (Config.logs) {
|
||||
Util.log('log param setted up in config.json\n' +
|
||||
'from now all logs will be writed to log.txt');
|
||||
|
||||
writeLogsToFile();
|
||||
}
|
||||
|
||||
lParams = {
|
||||
params = {
|
||||
appcache : appCacheProcessing,
|
||||
rest : main.rest,
|
||||
route : route
|
||||
},
|
||||
};
|
||||
|
||||
lFiles = [FILE_TMPL, PANEL_TMPL, PATH_TMPL, LINK_TMPL];
|
||||
filesList = [FILE_TMPL, PANEL_TMPL, PATH_TMPL, LINK_TMPL];
|
||||
|
||||
if (Config.ssl)
|
||||
lFiles.push(KEY, CERT);
|
||||
filesList.push(KEY, CERT);
|
||||
|
||||
files.read(lFiles, 'utf-8', function(pErrors, pFiles) {
|
||||
if (pErrors)
|
||||
Util.log(pErrors);
|
||||
files.read(filesList, 'utf-8', function(errors, files) {
|
||||
if (errors)
|
||||
Util.log(errors);
|
||||
else {
|
||||
FileTemplate = pFiles[FILE_TMPL];
|
||||
PanelTemplate = pFiles[PANEL_TMPL];
|
||||
PathTemplate = pFiles[PATH_TMPL];
|
||||
LinkTemplate = pFiles[LINK_TMPL];
|
||||
FileTemplate = files[FILE_TMPL];
|
||||
PanelTemplate = files[PANEL_TMPL];
|
||||
PathTemplate = files[PATH_TMPL];
|
||||
LinkTemplate = files[LINK_TMPL];
|
||||
|
||||
if (Config.ssl)
|
||||
lParams.ssl = {
|
||||
key : pFiles[KEY],
|
||||
cert : pFiles[CERT]
|
||||
params.ssl = {
|
||||
key : files[KEY],
|
||||
cert : files[CERT]
|
||||
};
|
||||
|
||||
server.start(lParams);
|
||||
server.start(params);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function readConfig(callback) {
|
||||
fs.readFile(CONFIG_PATH, 'utf8', function(error, data) {
|
||||
var msg, status, readed;
|
||||
var status, json, msg;
|
||||
|
||||
if (error)
|
||||
status = 'error';
|
||||
status = 'error';
|
||||
else {
|
||||
status = 'ok';
|
||||
readed = Util.parseJSON(data);
|
||||
|
||||
main.config = Config = readed;
|
||||
status = 'ok';
|
||||
json = Util.parseJSON(data);
|
||||
main.config = Config = json;
|
||||
}
|
||||
|
||||
msg = CloudFunc.formatMsg('read', 'config', status);
|
||||
Util.log(msg);
|
||||
|
||||
msg = CloudFunc.formatMsg('read', 'config', status);
|
||||
|
||||
Util.log(msg);
|
||||
Util.exec(callback);
|
||||
});
|
||||
}
|
||||
|
|
@ -197,7 +198,7 @@
|
|||
* routing of server queries
|
||||
*/
|
||||
function route(request, response, callback) {
|
||||
var ret, name, params, isAuth, isFS;
|
||||
var ret, name, params, isAuth, isFS, query;
|
||||
|
||||
if (request && response) {
|
||||
ret = true;
|
||||
|
|
@ -216,9 +217,20 @@
|
|||
|
||||
params.name = main.HTMLDIR + name + '.html';
|
||||
main.sendFile(params);
|
||||
} else if (isFS)
|
||||
sendContent(params);
|
||||
else {
|
||||
} else if (isFS) {
|
||||
query = main.getQuery(params.request),
|
||||
sendContent(name, query, function(name, error, data, isFile) {
|
||||
if (error)
|
||||
main.sendError(params, error);
|
||||
else if (isFile) {
|
||||
params.name = name;
|
||||
main.sendFile(params);
|
||||
} else {
|
||||
params.name = name;
|
||||
main.sendResponse(params, data, true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ret = false;
|
||||
Util.exec(callback);
|
||||
}
|
||||
|
|
@ -227,74 +239,59 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
function sendContent(pParams) {
|
||||
var p, lRet = main.checkParams(pParams);
|
||||
function sendContent(name, query, callback) {
|
||||
name = Util.removeStrOneTime(name, CloudFunc.FS) || main.SLASH;
|
||||
|
||||
if (lRet) {
|
||||
p = pParams;
|
||||
p.name = Util.removeStrOneTime(p.name, CloudFunc.FS) || main.SLASH;
|
||||
fs.stat(name, function(error, stat) {
|
||||
var func = Util.retExec(callback, name);
|
||||
|
||||
fs.stat(p.name, function(error, stat) {
|
||||
if (error)
|
||||
main.sendError(pParams, error);
|
||||
else
|
||||
if (stat.isDirectory())
|
||||
processContent(pParams);
|
||||
else
|
||||
main.sendFile(pParams);
|
||||
});
|
||||
}
|
||||
|
||||
return lRet;
|
||||
}
|
||||
|
||||
function processContent(params) {
|
||||
var p = params,
|
||||
ret = main.checkParams(params);
|
||||
|
||||
if (ret)
|
||||
main.commander.getDirContent(p.name, function(error, json) {
|
||||
var query, isJSON;
|
||||
|
||||
if (error)
|
||||
main.sendError(params, error);
|
||||
if (error)
|
||||
func(error);
|
||||
else
|
||||
if (!stat.isDirectory())
|
||||
func(error, null, true);
|
||||
else {
|
||||
query = main.getQuery(p.request);
|
||||
isJSON = Util.isContainStr(query, 'json');
|
||||
|
||||
if (!isJSON)
|
||||
readIndex(json, params);
|
||||
else {
|
||||
p.data = Util.stringifyJSON(json);
|
||||
p.name +='.json';
|
||||
main.sendResponse(params, null, true);
|
||||
}
|
||||
processContent(name, query, callback);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function readIndex(pJSON, params) {
|
||||
var p = params;
|
||||
|
||||
function processContent(name, query, callback) {
|
||||
main.commander.getDirContent(name, function(error, json) {
|
||||
var data, name,
|
||||
isJSON = Util.isContainStr(query, 'json');
|
||||
|
||||
if (!isJSON && !error)
|
||||
readIndex(json, Util.retExec(callback, INDEX_PATH));
|
||||
else {
|
||||
if (!error) {
|
||||
data = Util.stringifyJSON(json);
|
||||
name +='.json';
|
||||
}
|
||||
|
||||
Util.exec(callback, name, error, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function readIndex(json, callback) {
|
||||
Util.ifExec(!Minify, function(params) {
|
||||
var name = params && params.name;
|
||||
|
||||
fs.readFile(name || INDEX_PATH, 'utf8', function(error, template) {
|
||||
var panel,
|
||||
var panel, data,
|
||||
config = main.config,
|
||||
minify = config.minify;
|
||||
|
||||
if (error)
|
||||
main.sendError(p, error);
|
||||
else {
|
||||
p.name = INDEX_PATH,
|
||||
panel = CloudFunc.buildFromJSON(pJSON, FileTemplate, PathTemplate, LinkTemplate),
|
||||
|
||||
main.sendResponse(p, indexProcessing({
|
||||
if (!error) {
|
||||
panel = CloudFunc.buildFromJSON(json, FileTemplate, PathTemplate, LinkTemplate),
|
||||
data = indexProcessing({
|
||||
panel : panel,
|
||||
data : template,
|
||||
}), true);
|
||||
});
|
||||
}
|
||||
|
||||
Util.exec(callback, error, data);
|
||||
});
|
||||
}, function(callback) {
|
||||
Minify.optimize(INDEX_PATH, {
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@
|
|||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
height: 94%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 95%;
|
||||
width: 100%;
|
||||
font:16px "Droid Sans Mono";
|
||||
background-color:white;
|
||||
}
|
||||
|
|
@ -85,12 +86,13 @@ body {
|
|||
}
|
||||
|
||||
.loading {
|
||||
position : relative;
|
||||
top : 1px;
|
||||
display : inline-block;
|
||||
width : 15px;
|
||||
height : 14.8px;
|
||||
background : url(/img/spinner.gif);
|
||||
position : relative;
|
||||
top : 2px;
|
||||
display : inline-block;
|
||||
width : 16px;
|
||||
height : 16px;
|
||||
background : url(/img/spinner.gif);
|
||||
vertical-align : top;
|
||||
}
|
||||
|
||||
.refresh-icon {
|
||||
|
|
@ -103,6 +105,7 @@ body {
|
|||
|
||||
.cmd-button {
|
||||
width: 5%;
|
||||
height: 30px;
|
||||
margin: 20px 2px 0 2px;
|
||||
color: #222;
|
||||
background-color: white;
|
||||
|
|
@ -164,7 +167,8 @@ body {
|
|||
}
|
||||
.fm {
|
||||
height: 85%;
|
||||
margin: 26px 26px 0 26px;
|
||||
width: 97%;
|
||||
margin: 26px auto 0 auto;
|
||||
}
|
||||
.fm-header {
|
||||
font-weight: bold;
|
||||
|
|
@ -188,9 +192,8 @@ body {
|
|||
}
|
||||
.panel {
|
||||
width: 46%;
|
||||
height: 90%;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
height: 97%;
|
||||
padding: 1%;
|
||||
border: 1.5px solid;
|
||||
border-color: rgb(49, 123, 249);
|
||||
border-color: rgba(49, 123, 249, .40);
|
||||
|
|
@ -264,7 +267,22 @@ a:hover, a:active {
|
|||
* друг-под-другом
|
||||
*/
|
||||
/* responsive design */
|
||||
|
||||
@media only screen and (max-height: 800px) {
|
||||
.fm {
|
||||
height: 74%;
|
||||
}
|
||||
|
||||
.files {
|
||||
height: 85%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.panel {
|
||||
font-size: 26px;
|
||||
}
|
||||
/* текущий файл под курсором */
|
||||
.current-file {
|
||||
background-color: rgb(49, 123, 249);
|
||||
|
|
@ -272,25 +290,18 @@ a:hover, a:active {
|
|||
color:white;
|
||||
}
|
||||
/* делаем иконки под курсом белыми*/
|
||||
.current-file > .mini-icon{
|
||||
.current-file a {
|
||||
color:white;
|
||||
}
|
||||
.current-file > .text-file::before {
|
||||
.current-file .text-file::before {
|
||||
color:white;
|
||||
}
|
||||
|
||||
.fm-header {
|
||||
display:none;
|
||||
}
|
||||
|
||||
/* меняем иконки на шрифтовые*/
|
||||
.mini-icon {
|
||||
color : rgb(246, 224, 124);
|
||||
color : rgba(246, 224, 124, 0.56);
|
||||
font : 16px 'Fontello';
|
||||
width : 6%;
|
||||
margin-left : 10px;
|
||||
float : left;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
|
|
@ -300,8 +311,8 @@ a:hover, a:active {
|
|||
|
||||
.name {
|
||||
float: none;
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
width: 90%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.directory::before {
|
||||
|
|
@ -315,9 +326,9 @@ a:hover, a:active {
|
|||
.text-file {
|
||||
background-image:none;
|
||||
}
|
||||
|
||||
|
||||
/* убираем заголовок*/
|
||||
.fm_header {
|
||||
.fm-header {
|
||||
display:none;
|
||||
}
|
||||
|
||||
|
|
@ -341,7 +352,7 @@ a:hover, a:active {
|
|||
|
||||
@media only screen and (max-width: 1155px) {
|
||||
.panel {
|
||||
width:94%;
|
||||
width:97%;
|
||||
}
|
||||
/* если правая панель не помещаеться - прячем её */
|
||||
.panel-right, .cmd-button#f5, .cmd-button#f6 {
|
||||
|
|
|
|||
BIN
favicon.ico
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -7,27 +7,55 @@
|
|||
<meta content="width=device-width,initial-scale=1" name="viewport" />
|
||||
<!-- chrome frame -->
|
||||
<meta http-equiv="X-UA-Compatible" content=" chrome=1" />
|
||||
<link href=/img/favicon/favicon.png rel=icon type=image/png />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<title>{{ title }}</title>
|
||||
|
||||
<link rel=stylesheet href=/join/css/reset.css:css/style.css:css/icons.css>
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.path-icon, .keyspanel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.links {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.fm {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.panel-right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-left {
|
||||
width: 97%;
|
||||
}
|
||||
|
||||
.name a:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class=fm>{{ fm }}</div>
|
||||
<div class="keyspanel">
|
||||
<button id=f1 class="cmd-button reduce-text icon-help" title="help">F1</button>
|
||||
<button id=f2 class="cmd-button reduce-text icon-rename" title="rename">F2</button>
|
||||
<button id=f3 class="cmd-button reduce-text icon-view" title="view">F3</button>
|
||||
<button id=f4 class="cmd-button reduce-text icon-edit " title="edit">F4</button>
|
||||
<button id=f5 class="cmd-button reduce-text icon-copy" title="copy">F5</button>
|
||||
<button id=f6 class="cmd-button reduce-text icon-move" title="move">F6</button>
|
||||
<button id=f7 class="cmd-button reduce-text icon-directory" title="make directory">F7</button>
|
||||
<button id=f8 class="cmd-button reduce-text icon-delete" title="delete">F8</button>
|
||||
<button id=f9 class="cmd-button reduce-text icon-menu" title="menu">F9</button>
|
||||
<button id=f10 class="cmd-button reduce-text icon-config" title="config">F10</button>
|
||||
<button id=~ class="cmd-button reduce-text icon-console" title="console">~</button>
|
||||
<button id=contact class="cmd-button reduce-text icon-contact" title="contact"></button>
|
||||
<button id=f1 class="cmd-button reduce-text icon-help" title="help" >F1</button>
|
||||
<button id=f2 class="cmd-button reduce-text icon-rename" title="rename" >F2</button>
|
||||
<button id=f3 class="cmd-button reduce-text icon-view" title="view" >F3</button>
|
||||
<button id=f4 class="cmd-button reduce-text icon-edit " title="edit" >F4</button>
|
||||
<button id=f5 class="cmd-button reduce-text icon-copy" title="copy" >F5</button>
|
||||
<button id=f6 class="cmd-button reduce-text icon-move" title="move" >F6</button>
|
||||
<button id=f7 class="cmd-button reduce-text icon-directory" title="make directory" >F7</button>
|
||||
<button id=f8 class="cmd-button reduce-text icon-delete" title="delete" >F8</button>
|
||||
<button id=f9 class="cmd-button reduce-text icon-menu" title="menu" >F9</button>
|
||||
<button id=f10 class="cmd-button reduce-text icon-config" title="config" >F10</button>
|
||||
<button id=~ class="cmd-button reduce-text icon-console" title="console" >~</button>
|
||||
<button id=contact class="cmd-button reduce-text icon-contact" title="contact" ></button>
|
||||
</div>
|
||||
<script>
|
||||
!(function() {
|
||||
|
|
@ -42,6 +70,7 @@
|
|||
client + 'dom.js',
|
||||
client + 'loader.js',
|
||||
client + 'notify.js',
|
||||
client + 'storage.js',
|
||||
lib + 'client.js',
|
||||
client + 'listeners.js',
|
||||
client + 'key.js'
|
||||
1
html/fs/path.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<div data="js-path" class="reduce-text" title="{{ fullPath }}"><span class="path-icon clear-storage" title="clear storage (Ctrl+D)"></span><span class="path-icon refresh-icon" title="refresh (Ctrl+R)"><a href="{{ link }}"></a></span><span class=links>{{ path }}</span></div>
|
||||
|
|
@ -1 +0,0 @@
|
|||
<div id="js-path" class="reduce-text" title="{{ fullPath }}"><span class="path-icon clear-storage" title="clear storage (Ctrl+D)"></span><span class="path-icon refresh-icon" title="refresh (Ctrl+R)"><a href="{{ link }}"></a></span><span class=links>{{ path }}</span></div>
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 495 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 337 B |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 19 KiB |
|
|
@ -56,7 +56,7 @@
|
|||
".hh": "text/x-c",
|
||||
".htm": "text/html",
|
||||
".html": "text/html",
|
||||
".ico": "image/vnd.microsoft.icon",
|
||||
".ico": "image/x-icon",
|
||||
".ics": "text/calendar",
|
||||
".ifb": "text/calendar",
|
||||
".iso": "application/octet-stream",
|
||||
|
|
|
|||
398
lib/client.js
|
|
@ -11,6 +11,10 @@ var Util, DOM, CloudFunc;
|
|||
function CloudCmdProto(Util, DOM, CloudFunc) {
|
||||
var Key, Config, Modules, Extensions,
|
||||
FileTemplate, PathTemplate, LinkTemplate, Listeners,
|
||||
DIR_HTML = '/html/',
|
||||
DIR_HTML_FS = DIR_HTML + 'fs/',
|
||||
DIR_JSON = '/json/',
|
||||
|
||||
Images = DOM.Images,
|
||||
Info = DOM.CurrentInfo,
|
||||
CloudCmd = this,
|
||||
|
|
@ -18,13 +22,11 @@ var Util, DOM, CloudFunc;
|
|||
|
||||
this.LIBDIR = '/lib/';
|
||||
this.LIBDIRCLIENT = '/lib/client/';
|
||||
this.JSONDIR = '/json/';
|
||||
this.HTMLDIR = '/html/';
|
||||
this.MIN_ONE_PANEL_WIDTH = 1155;
|
||||
this.OLD_BROWSER = false;
|
||||
this.HOST = (function() {
|
||||
var lLocation = document.location;
|
||||
return lLocation.protocol + '//' + lLocation.host;
|
||||
var location = document.location;
|
||||
return location.protocol + '//' + location.host;
|
||||
})();
|
||||
|
||||
/**
|
||||
|
|
@ -34,25 +36,31 @@ var Util, DOM, CloudFunc;
|
|||
* @param pLink - ссылка
|
||||
* @param pNeedRefresh - необходимость обязательной загрузки данных с сервера
|
||||
*/
|
||||
this.loadDir = function(pLink, pNeedRefresh) {
|
||||
return function(pEvent) {
|
||||
/* показываем гиф загрузки возле пути папки сверху
|
||||
* ctrl+r нажата? */
|
||||
this.loadDir = function(paramLink, needRefresh) {
|
||||
return function(event) {
|
||||
var link,
|
||||
currentLink = DOM.getCurrentLink(),
|
||||
href = currentLink.href;
|
||||
|
||||
var lCurrentLink = DOM.getCurrentLink(),
|
||||
lHref = lCurrentLink.href,
|
||||
lLink = pLink || Util.removeStr(lHref, CloudCmd.HOST);
|
||||
if (paramLink)
|
||||
link = paramLink;
|
||||
else
|
||||
link = Util.removeStr(href, CloudCmd.HOST);
|
||||
|
||||
lLink += '?json';
|
||||
link += '?json';
|
||||
|
||||
if (lLink || lCurrentLink.target !== '_blank') {
|
||||
Images.showLoad(pNeedRefresh ? {top:true} : null);
|
||||
if (link || currentLink.target !== '_blank') {
|
||||
Images.showLoad(!needRefresh ? null: {
|
||||
top:true
|
||||
});
|
||||
|
||||
/* загружаем содержимое каталога */
|
||||
CloudCmd.ajaxLoad(lLink, { refresh: pNeedRefresh });
|
||||
CloudCmd.ajaxLoad(link, {
|
||||
refresh: needRefresh
|
||||
});
|
||||
}
|
||||
|
||||
DOM.preventDefault(pEvent);
|
||||
DOM.preventDefault(event);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -63,15 +71,15 @@ var Util, DOM, CloudFunc;
|
|||
* в верх по файловой структуре
|
||||
* @param pDirName - имя каталога с которого мы пришли
|
||||
*/
|
||||
function currentToParent(pDirName) {
|
||||
var lRootDir;
|
||||
function currentToParent(dirName) {
|
||||
var rootDir;
|
||||
/* убираем слэш с имени каталога */
|
||||
pDirName = Util.removeStr(pDirName, '/');
|
||||
lRootDir = DOM.getCurrentFileByName(pDirName);
|
||||
dirName = Util.removeStr(dirName, '/');
|
||||
rootDir = DOM.getCurrentFileByName(dirName);
|
||||
|
||||
if (lRootDir) {
|
||||
DOM.setCurrentFile(lRootDir);
|
||||
DOM.scrollIntoViewIfNeeded(lRootDir, true);
|
||||
if (rootDir) {
|
||||
DOM.setCurrentFile(rootDir);
|
||||
DOM.scrollIntoViewIfNeeded(rootDir, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,50 +87,51 @@ var Util, DOM, CloudFunc;
|
|||
* function load modules
|
||||
* @pParams = {name, path, func, dobefore, arg}
|
||||
*/
|
||||
function loadModule(pParams) {
|
||||
var lName, lPath, lFunc, lDoBefore, lSlash, lAfterSlash,
|
||||
function loadModule(params) {
|
||||
var name, path, func, doBefore, slash, afterSlash,
|
||||
isContain;
|
||||
|
||||
if (pParams) {
|
||||
lName = pParams.name,
|
||||
lPath = pParams.path,
|
||||
lFunc = pParams.func,
|
||||
lDoBefore = pParams.dobefore;
|
||||
if (params) {
|
||||
name = params.name,
|
||||
path = params.path,
|
||||
func = params.func,
|
||||
doBefore = params.dobefore;
|
||||
|
||||
if (Util.isString(pParams))
|
||||
lPath = pParams;
|
||||
if (Util.isString(params))
|
||||
path = params;
|
||||
|
||||
if (lPath && !lName) {
|
||||
lName = Util.getStrBigFirst(lPath);
|
||||
lName = Util.removeStr(lName, '.js');
|
||||
if (path && !name) {
|
||||
name = Util.getStrBigFirst(path);
|
||||
name = Util.removeStr(name, '.js');
|
||||
|
||||
lSlash = lName.indexOf('/');
|
||||
if (lSlash > 0) {
|
||||
lAfterSlash = lName.substr(lSlash);
|
||||
lName = Util.removeStr(lName, lAfterSlash);
|
||||
slash = name.indexOf('/');
|
||||
if (slash > 0) {
|
||||
afterSlash = name.substr(slash);
|
||||
name = Util.removeStr(name, afterSlash);
|
||||
}
|
||||
}
|
||||
|
||||
isContain = Util.isContainStr(lPath, '.js');
|
||||
if (!isContain)
|
||||
lPath += '.js';
|
||||
isContain = Util.isContainStr(path, '.js');
|
||||
|
||||
if (!CloudCmd[lName]) {
|
||||
CloudCmd[lName] = function(pArg) {
|
||||
var path = CloudCmd.LIBDIRCLIENT + lPath;
|
||||
if (!isContain)
|
||||
path += '.js';
|
||||
|
||||
if (!CloudCmd[name]) {
|
||||
CloudCmd[name] = function(arg) {
|
||||
path = CloudCmd.LIBDIRCLIENT + path;
|
||||
|
||||
Util.exec(lDoBefore);
|
||||
Util.exec(doBefore);
|
||||
|
||||
return DOM.jsload(path, lFunc ||
|
||||
return DOM.jsload(path, func ||
|
||||
function() {
|
||||
var Proto = CloudCmd[lName];
|
||||
var Proto = CloudCmd[name];
|
||||
|
||||
if (Util.isFunction(Proto))
|
||||
CloudCmd[lName] = new Proto(pArg);
|
||||
CloudCmd[name] = new Proto(arg);
|
||||
});
|
||||
};
|
||||
|
||||
CloudCmd[lName].show = CloudCmd[lName];
|
||||
CloudCmd[name].show = CloudCmd[name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,49 +141,50 @@ var Util, DOM, CloudFunc;
|
|||
* инициализации
|
||||
*/
|
||||
this.init = function() {
|
||||
var lCallBack, lFunc;
|
||||
|
||||
lCallBack = function() {
|
||||
Util.loadOnLoad([
|
||||
initModules,
|
||||
baseInit,
|
||||
Util.bind(CloudCmd.route, location.hash)
|
||||
]);
|
||||
},
|
||||
lFunc = function(pCallBack) {
|
||||
CloudCmd.OLD_BROWSER = true;
|
||||
var lSrc = CloudCmd.LIBDIRCLIENT + 'polyfill.js';
|
||||
var callback = function() {
|
||||
Util.loadOnLoad([
|
||||
initModules,
|
||||
baseInit,
|
||||
Util.bind(CloudCmd.route, location.hash)
|
||||
]);
|
||||
},
|
||||
|
||||
DOM.jqueryLoad(
|
||||
DOM.retJSLoad(lSrc, pCallBack)
|
||||
);
|
||||
};
|
||||
func = function(callBack) {
|
||||
var src = CloudCmd.LIBDIRCLIENT + 'polyfill.js';
|
||||
|
||||
CloudCmd.OLD_BROWSER = true;
|
||||
|
||||
DOM.jqueryLoad(function() {
|
||||
DOM.jsload(src, callback);
|
||||
});
|
||||
};
|
||||
|
||||
Util.ifExec(document.body.scrollIntoViewIfNeeded, lCallBack, lFunc);
|
||||
Util.ifExec(document.body.scrollIntoViewIfNeeded, callback, func);
|
||||
};
|
||||
|
||||
this.route = function(pPath) {
|
||||
var lQuery, lModule, lFile, lCurrent, lMsg;
|
||||
this.route = function(path) {
|
||||
var query, module, file, current, msg;
|
||||
|
||||
if (pPath.length > 0) {
|
||||
lQuery = pPath.split('/');
|
||||
if (path.length > 0) {
|
||||
query = path.split('/');
|
||||
|
||||
if (lQuery.length > 0) {
|
||||
lModule = Util.getStrBigFirst(lQuery[1]);
|
||||
lFile = lQuery[2];
|
||||
lCurrent = DOM.getCurrentFileByName(lFile);
|
||||
if (lFile && !lCurrent) {
|
||||
lMsg = CloudFunc.formatMsg('set current file', lFile, 'error');
|
||||
Util.log(lMsg);
|
||||
if (query.length > 0) {
|
||||
module = Util.getStrBigFirst(query[1]);
|
||||
file = query[2];
|
||||
current = DOM.getCurrentFileByName(file);
|
||||
|
||||
if (file && !current) {
|
||||
msg = CloudFunc.formatMsg('set current file', file, 'error');
|
||||
Util.log(msg);
|
||||
} else {
|
||||
DOM.setCurrentFile(lCurrent);
|
||||
CloudCmd.execFromModule(lModule, 'show');
|
||||
DOM.setCurrentFile(current);
|
||||
CloudCmd.execFromModule(module, 'show');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function initModules(pCallBack) {
|
||||
function initModules(callback) {
|
||||
Util.ifExec(CloudCmd.Key, function() {
|
||||
Key = new CloudCmd.Key();
|
||||
CloudCmd.Key = Key;
|
||||
|
|
@ -187,19 +197,15 @@ var Util, DOM, CloudFunc;
|
|||
});
|
||||
});
|
||||
|
||||
CloudCmd.getModules(function(pModules) {
|
||||
pModules = pModules || [];
|
||||
|
||||
CloudCmd.getModules(function(modules) {
|
||||
var i, n, module, storageObj, mod, name, path,
|
||||
STORAGE = 'storage',
|
||||
showLoadFunc = Util.bind(Images.showLoad, {
|
||||
top:true
|
||||
}),
|
||||
STORAGE = 'storage',
|
||||
showLoad = Images.showLoad.bind(Images),
|
||||
|
||||
doBefore = {
|
||||
'edit' : showLoadFunc,
|
||||
'view' : showLoadFunc,
|
||||
'menu' : showLoadFunc
|
||||
doBefore = {
|
||||
'edit' : showLoad,
|
||||
'menu' : showLoad,
|
||||
'storage/_filepicker' : showLoad
|
||||
},
|
||||
|
||||
load = function(name, path, func) {
|
||||
|
|
@ -210,25 +216,28 @@ var Util, DOM, CloudFunc;
|
|||
});
|
||||
};
|
||||
|
||||
for (i = 0, n = pModules.length; i < n ; i++) {
|
||||
module = pModules[i];
|
||||
if (!modules)
|
||||
modules = [];
|
||||
|
||||
n = modules.length;
|
||||
for (i = 0; i < n ; i++) {
|
||||
module = modules[i];
|
||||
|
||||
if (Util.isString(module))
|
||||
load(null, module, doBefore[module]);
|
||||
}
|
||||
|
||||
storageObj = Util.findObjByNameInArr(pModules, STORAGE),
|
||||
storageObj = Util.findObjByNameInArr(modules, STORAGE),
|
||||
mod = Util.getNamesFromObjArray(storageObj);
|
||||
|
||||
for (i = 0, n = mod.length; i < n; i++) {
|
||||
name = mod[i],
|
||||
path = STORAGE + '/_' + name.toLowerCase();
|
||||
|
||||
load(name, path);
|
||||
load(name, path, doBefore[path]);
|
||||
}
|
||||
|
||||
Util.exec(pCallBack);
|
||||
|
||||
Util.exec(callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -263,9 +272,13 @@ var Util, DOM, CloudFunc;
|
|||
|
||||
dirPath = CloudFunc.rmLastSlash(dirPath) || '/';
|
||||
|
||||
if (!Storage.get(dirPath))
|
||||
Storage.set(dirPath, getJSONfromFileTable());
|
||||
Storage.get(dirPath, function(data) {
|
||||
if (!data) {
|
||||
data = getJSONfromFileTable();
|
||||
Storage.set(dirPath, data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Util.exec(CloudCmd.Key);
|
||||
Util.exec(pCallBack);
|
||||
|
|
@ -289,35 +302,39 @@ var Util, DOM, CloudFunc;
|
|||
}
|
||||
|
||||
this.setConfig = function(config) { Config = config; };
|
||||
this.getConfig = getSystemFile(Config, CloudCmd.JSONDIR + 'config.json');
|
||||
this.getModules = getSystemFile(Modules, CloudCmd.JSONDIR + 'modules.json');
|
||||
this.getExt = getSystemFile(Extensions, CloudCmd.JSONDIR + 'ext.json');
|
||||
this.getFileTemplate = getSystemFile(FileTemplate, CloudCmd.HTMLDIR + 'file.html');
|
||||
this.getPathTemplate = getSystemFile(PathTemplate, CloudCmd.HTMLDIR + 'path.html');
|
||||
this.getLinkTemplate = getSystemFile(PathTemplate, CloudCmd.HTMLDIR + 'link.html');
|
||||
this.getConfig = getSystemFile(Config, DIR_JSON + 'config.json');
|
||||
this.getModules = getSystemFile(Modules, DIR_JSON + 'modules.json');
|
||||
this.getExt = getSystemFile(Extensions, DIR_JSON + 'ext.json');
|
||||
this.getFileTemplate = getSystemFile(FileTemplate, DIR_HTML_FS + 'file.html');
|
||||
this.getPathTemplate = getSystemFile(PathTemplate, DIR_HTML_FS + 'path.html');
|
||||
this.getLinkTemplate = getSystemFile(PathTemplate, DIR_HTML_FS + 'link.html');
|
||||
|
||||
this.execFromModule = function(pModuleName, pFuncName, pParams) {
|
||||
var lObject = CloudCmd[pModuleName];
|
||||
Util.ifExec(Util.isObject(lObject),
|
||||
this.execFromModule = function(moduleName, funcName, params) {
|
||||
var obj = CloudCmd[moduleName],
|
||||
isObj = Util.isObject(obj);
|
||||
|
||||
Util.ifExec(isObj,
|
||||
function() {
|
||||
var lObj = CloudCmd[pModuleName];
|
||||
Util.exec( lObj[pFuncName], pParams);
|
||||
var obj = CloudCmd[moduleName],
|
||||
func = obj[funcName];
|
||||
|
||||
Util.exec(func, params);
|
||||
},
|
||||
|
||||
function(pCallBack) {
|
||||
Util.exec(lObject, pCallBack);
|
||||
function(callback) {
|
||||
Util.exec(obj, callback);
|
||||
});
|
||||
};
|
||||
|
||||
this.refresh = function(pCurrent) {
|
||||
var lNEEDREFRESH = true,
|
||||
lPanel = pCurrent && pCurrent.parentElement,
|
||||
lPath = DOM.getCurrentDirPath(lPanel),
|
||||
lLink = CloudFunc.FS + lPath,
|
||||
lNotSlashlLink = CloudFunc.rmLastSlash(lLink),
|
||||
lLoad = CloudCmd.loadDir(lNotSlashlLink, lNEEDREFRESH);
|
||||
this.refresh = function(current) {
|
||||
var NEEDREFRESH = true,
|
||||
panel = current && current.parentElement,
|
||||
path = DOM.getCurrentDirPath(panel),
|
||||
link = CloudFunc.FS + path,
|
||||
notSlashlLink = CloudFunc.rmLastSlash(link),
|
||||
load = CloudCmd.loadDir(notSlashlLink, NEEDREFRESH);
|
||||
|
||||
lLoad();
|
||||
load();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -327,28 +344,33 @@ var Util, DOM, CloudFunc;
|
|||
* @param pOptions
|
||||
* { refresh, nohistory } - необходимость обновить данные о каталоге
|
||||
*/
|
||||
this.ajaxLoad = function(pPath, pOptions) {
|
||||
if (!pOptions)
|
||||
pOptions = {};
|
||||
this.ajaxLoad = function(path, options) {
|
||||
var SLASH = '/',
|
||||
dirPath = DOM.getCurrentDirPath(),
|
||||
fsPath = decodeURI(path),
|
||||
noJSONPath = Util.removeStr(fsPath, '?json' ),
|
||||
cleanPath = Util.removeStrOneTime(noJSONPath, CloudFunc.FS) || SLASH,
|
||||
setTitle = function() {
|
||||
var title;
|
||||
|
||||
dirPath = CloudFunc.rmLastSlash(dirPath) || '/';
|
||||
|
||||
if (dirPath !== cleanPath) {
|
||||
if (!options.nohistory)
|
||||
DOM.setHistory(noJSONPath, null, noJSONPath);
|
||||
|
||||
title = CloudFunc.getTitle(cleanPath);
|
||||
DOM.setTitle(title);
|
||||
}
|
||||
};
|
||||
|
||||
/* Отображаем красивые пути */
|
||||
var lSLASH = '/',
|
||||
title = CloudFunc.getTitle(lCleanPath),
|
||||
lFSPath = decodeURI(pPath),
|
||||
lNOJSPath = Util.removeStr( lFSPath, '?json' ),
|
||||
lCleanPath = Util.removeStrOneTime( lNOJSPath, CloudFunc.FS ) || lSLASH,
|
||||
|
||||
lOldURL = window.location.pathname;
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
if (lCleanPath === lSLASH)
|
||||
lNOJSPath = lSLASH;
|
||||
if (cleanPath === SLASH)
|
||||
noJSONPath = SLASH;
|
||||
|
||||
Util.log ('reading dir: "' + lCleanPath + '";');
|
||||
|
||||
if (!pOptions.nohistory)
|
||||
DOM.setHistory(lNOJSPath, null, lNOJSPath);
|
||||
|
||||
DOM.setTitle(title);
|
||||
Util.log ('reading dir: "' + cleanPath + '";');
|
||||
|
||||
/* если доступен localStorage и
|
||||
* в нём есть нужная нам директория -
|
||||
|
|
@ -357,102 +379,78 @@ var Util, DOM, CloudFunc;
|
|||
* если стоит поле обязательной перезагрузки -
|
||||
* перезагружаемся
|
||||
*/
|
||||
var lRet = pOptions.refresh;
|
||||
if (!lRet) {
|
||||
var lJSON = Storage.get(lCleanPath);
|
||||
Storage.get(cleanPath, function(json) {
|
||||
var ret = options && options.refresh;
|
||||
|
||||
if (lJSON) {
|
||||
lJSON = Util.parseJSON(lJSON);
|
||||
CloudCmd.createFileTable(lJSON);
|
||||
}
|
||||
else
|
||||
lRet = true;
|
||||
}
|
||||
|
||||
if (lRet)
|
||||
DOM.getCurrentFileContent({
|
||||
url : lFSPath,
|
||||
|
||||
dataType: 'json',
|
||||
|
||||
error : function() {
|
||||
DOM.setHistory(lOldURL, null, lOldURL);
|
||||
},
|
||||
|
||||
success : function(pData) {
|
||||
CloudCmd.createFileTable(pData);
|
||||
|
||||
/* переводим таблицу файлов в строку, для *
|
||||
* сохранения в localStorage */
|
||||
var lJSON_s = Util.stringifyJSON(pData);
|
||||
Util.log(lJSON_s.length);
|
||||
|
||||
/* если размер данных не очень бошьой *
|
||||
* сохраняем их в кэше */
|
||||
if (lJSON_s.length < 50000 )
|
||||
Storage.set(lCleanPath, lJSON_s);
|
||||
}
|
||||
});
|
||||
if (!ret && json) {
|
||||
json = Util.parseJSON(json);
|
||||
CloudCmd.createFileTable(json);
|
||||
setTitle();
|
||||
} else
|
||||
DOM.getCurrentFileContent({
|
||||
url : fsPath,
|
||||
dataType : 'json',
|
||||
success : function(json) {
|
||||
setTitle();
|
||||
CloudCmd.createFileTable(json);
|
||||
Storage.set(cleanPath, json);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Функция строит файловую таблицу
|
||||
* @param pJSON - данные о файлах
|
||||
*/
|
||||
this.createFileTable = function(pJSON) {
|
||||
this.createFileTable = function(json) {
|
||||
var files,
|
||||
panel = DOM.getPanel(),
|
||||
/* getting current element if was refresh */
|
||||
lPath = DOM.getCurrentDirPath(panel),
|
||||
|
||||
lCurrent = DOM.getCurrentFile(),
|
||||
lDir = DOM.getCurrentDirName(),
|
||||
|
||||
lName = DOM.getCurrentName(lCurrent),
|
||||
wasRefresh = lPath === pJSON.path,
|
||||
lFuncs = [
|
||||
path = DOM.getCurrentDirPath(panel),
|
||||
wasRefresh = path === json.path,
|
||||
funcs = [
|
||||
CloudCmd.getFileTemplate,
|
||||
CloudCmd.getPathTemplate,
|
||||
CloudCmd.getLinkTemplate
|
||||
];
|
||||
|
||||
Util.asyncCall(lFuncs, function(pTemplate, pPathTemplate, pLinkTemplate) {
|
||||
/* очищаем панель */
|
||||
var n, found,
|
||||
i = panel.childNodes.length;
|
||||
Util.asyncCall(funcs, function(templFile, templPath, templLink) {
|
||||
var n, found, varCurrent, varName, current,
|
||||
dir = DOM.getCurrentDirName(),
|
||||
name = DOM.getCurrentName(),
|
||||
i = panel.childNodes.length;
|
||||
|
||||
while(i--)
|
||||
panel.removeChild(panel.lastChild);
|
||||
|
||||
panel.innerHTML = CloudFunc.buildFromJSON(pJSON, pTemplate, pPathTemplate, pLinkTemplate);
|
||||
|
||||
files = DOM.getFiles(panel);
|
||||
panel.innerHTML = CloudFunc.buildFromJSON(json, templFile, templPath, templLink);
|
||||
files = DOM.getFiles(panel);
|
||||
|
||||
/* searching current file */
|
||||
if (wasRefresh) {
|
||||
n = files.length;
|
||||
|
||||
for (i = 0; i < n ; i++) {
|
||||
var lVarCurrent = files[i],
|
||||
lVarName = DOM.getCurrentName(lVarCurrent);
|
||||
|
||||
found = lVarName === lName;
|
||||
varCurrent = files[i],
|
||||
varName = DOM.getCurrentName(varCurrent);
|
||||
found = varName === name;
|
||||
|
||||
if (found) {
|
||||
lCurrent = files[i];
|
||||
current = files[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) /* .. */
|
||||
lCurrent = files[0];
|
||||
current = files[0];
|
||||
|
||||
DOM.setCurrentFile(lCurrent);
|
||||
DOM.setCurrentFile(current);
|
||||
|
||||
Listeners.changeLinks(panel.id);
|
||||
|
||||
if (lName === '..' && lDir !== '/')
|
||||
currentToParent(lDir);
|
||||
if (name === '..' && dir !== '/')
|
||||
currentToParent(dir);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,19 +6,23 @@ var CloudCmd, Util, DOM;
|
|||
CloudCmd.Config = ConfigProto;
|
||||
|
||||
function ConfigProto() {
|
||||
var Loading = true,
|
||||
Key = CloudCmd.Key,
|
||||
Images = DOM.Images,
|
||||
Events = DOM.Events,
|
||||
INPUT = 'INPUT',
|
||||
var Loading = true,
|
||||
Key = CloudCmd.Key,
|
||||
Images = DOM.Images,
|
||||
Events = DOM.Events,
|
||||
showLoad = Images.showLoad.bind(DOM, {
|
||||
top: true
|
||||
}),
|
||||
INPUT = 'INPUT',
|
||||
CONFIG,
|
||||
TEMPLATE,
|
||||
Notify = DOM.Notify,
|
||||
Config = this;
|
||||
Notify = DOM.Notify,
|
||||
Config = this;
|
||||
|
||||
function init(pCallBack) {
|
||||
Loading = true;
|
||||
|
||||
showLoad();
|
||||
Util.loadOnLoad([
|
||||
CloudCmd.View,
|
||||
function(callback) {
|
||||
|
|
@ -36,7 +40,7 @@ var CloudCmd, Util, DOM;
|
|||
];
|
||||
|
||||
if (!Loading) {
|
||||
Images.showLoad({top:true});
|
||||
showLoad();
|
||||
Util.asyncCall(funcs, fillTemplate);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
};
|
||||
|
||||
function getImage(name) {
|
||||
var id = 'image-' + name,
|
||||
var id = 'js-image-' + name,
|
||||
element = Images[id];
|
||||
|
||||
if (!element)
|
||||
|
|
@ -319,6 +319,18 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
return ret;
|
||||
};
|
||||
|
||||
this.getByAttr = function(attribute, element) {
|
||||
var ret,
|
||||
selector = '[' + 'data="' + attribute + '"]';
|
||||
|
||||
if (!element)
|
||||
element = document;
|
||||
|
||||
ret = element.querySelector(selector);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function search element by class name
|
||||
* @param pClass - className
|
||||
|
|
@ -585,78 +597,6 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
}
|
||||
}
|
||||
},
|
||||
StorageProto = function() {
|
||||
/* приватный переключатель возможности работы с кэшем */
|
||||
var StorageAllowed;
|
||||
|
||||
/* функция проверяет возможно ли работать с кэшем каким-либо образом */
|
||||
this.isAllowed = function() {
|
||||
var lRet = StorageAllowed && !!window.localStorage;
|
||||
return lRet;
|
||||
};
|
||||
|
||||
/**
|
||||
* allow Storage usage
|
||||
*/
|
||||
this.setAllowed = function(pAllowd) {
|
||||
StorageAllowed = pAllowd;
|
||||
|
||||
return pAllowd;
|
||||
};
|
||||
|
||||
/** remove element */
|
||||
this.remove = function(pItem) {
|
||||
var lRet = this;
|
||||
|
||||
if (StorageAllowed)
|
||||
localStorage.removeItem(pItem);
|
||||
|
||||
return lRet;
|
||||
};
|
||||
|
||||
/** если доступен localStorage и
|
||||
* в нём есть нужная нам директория -
|
||||
* записываем данные в него
|
||||
*/
|
||||
this.set = function(pName, pData) {
|
||||
var lRet = this;
|
||||
|
||||
if (StorageAllowed && pName)
|
||||
localStorage.setItem(pName, pData);
|
||||
|
||||
return lRet;
|
||||
},
|
||||
|
||||
/** Если доступен Storage принимаем из него данные*/
|
||||
this.get = function(pName) {
|
||||
var lRet;
|
||||
|
||||
if (StorageAllowed)
|
||||
lRet = localStorage.getItem(pName);
|
||||
|
||||
return lRet;
|
||||
},
|
||||
|
||||
/* get all Storage from local storage */
|
||||
this.getAll = function() {
|
||||
var lRet = null;
|
||||
|
||||
if (StorageAllowed)
|
||||
lRet = localStorage;
|
||||
|
||||
return lRet;
|
||||
};
|
||||
|
||||
/** функция чистит весь кэш для всех каталогов*/
|
||||
this.clear = function() {
|
||||
var lRet = this;
|
||||
|
||||
if (StorageAllowed)
|
||||
localStorage.clear();
|
||||
|
||||
return lRet;
|
||||
};
|
||||
},
|
||||
|
||||
CmdProto = function() {
|
||||
var Cmd = this,
|
||||
|
|
@ -758,9 +698,8 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
*
|
||||
* @pCurrentFile
|
||||
*/
|
||||
this.promptDeleteSelected = function(pCurrentFile) {
|
||||
var ret, type, isDir, path,
|
||||
current, query, msg,
|
||||
this.promptDeleteSelected = function(current) {
|
||||
var ret, type, isDir, path, query, msg,
|
||||
name = '',
|
||||
msgAsk = 'Do you really want to delete the ',
|
||||
msgSel = 'selected ',
|
||||
|
|
@ -768,7 +707,7 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
names = Cmd.getSelectedNames(files),
|
||||
i, n = names && names.length;
|
||||
|
||||
if (!Cmd.isCurrentFile(pCurrentFile))
|
||||
if (!Cmd.isCurrentFile(current))
|
||||
current = DOM.getCurrentFile();
|
||||
|
||||
if (n > 1) {
|
||||
|
|
@ -805,8 +744,9 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
|
||||
if (ret)
|
||||
RESTful.delete(path, names, function() {
|
||||
var dirPath = CurrentInfo.dirPath,
|
||||
dir = CloudFunc.rmLastSlash(dirPath);
|
||||
var Storage = DOM.Storage,
|
||||
dirPath = CurrentInfo.dirPath,
|
||||
dir = CloudFunc.rmLastSlash(dirPath);
|
||||
|
||||
if (n > 1)
|
||||
DOM.deleteSelected(files);
|
||||
|
|
@ -839,15 +779,16 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
/**
|
||||
* get current direcotory path
|
||||
*/
|
||||
this.getCurrentDirPath = function(pPanel) {
|
||||
var lPanel = pPanel || this.getPanel(),
|
||||
lPath = this.getById('js-path', lPanel),
|
||||
lRet;
|
||||
this.getCurrentDirPath = function(panel) {
|
||||
var ret, path;
|
||||
|
||||
if (lPath)
|
||||
lRet = lPath.textContent;
|
||||
if (!panel)
|
||||
panel = this.getPanel();
|
||||
|
||||
return lRet;
|
||||
path = this.getByAttr('js-path', panel);
|
||||
ret = path && path.textContent;
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1391,16 +1332,19 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
/**
|
||||
* set name from current (or param) file
|
||||
*
|
||||
* @param pCurrentFile
|
||||
* @param name
|
||||
* @param current
|
||||
*/
|
||||
this.setCurrentName = function(pName, pCurrentFile) {
|
||||
var lLink = this.getCurrentLink( pCurrentFile ),
|
||||
lDir = this.getCurrentDirName() + '/';
|
||||
this.setCurrentName = function(name, current) {
|
||||
var link = this.getCurrentLink(current),
|
||||
dir = this.getCurrentDirName() + '/',
|
||||
panel = DOM.getPanel();
|
||||
|
||||
lLink.title = lLink.textContent = pName;
|
||||
lLink.href = lDir + pName;
|
||||
link.title = link.textContent = name;
|
||||
link.href = dir + name;
|
||||
current.id = name + '(' + panel.id + ')';
|
||||
|
||||
return lLink;
|
||||
return link;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1408,17 +1352,20 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
*/
|
||||
this.checkStorageHash = function(name, callback) {
|
||||
DOM.loadCurrentHash(function(loadHash) {
|
||||
var equal, error,
|
||||
nameHash = name + '-hash',
|
||||
storeHash = Storage.get(name + '-hash'),
|
||||
isContain = Util.isContainStr(loadHash, 'error');
|
||||
var Storage = DOM.Storage;
|
||||
|
||||
if (isContain)
|
||||
error = loadHash;
|
||||
else if (loadHash === storeHash)
|
||||
equal = true;
|
||||
|
||||
Util.exec(callback, error, equal, loadHash);
|
||||
Storage.get(name + '-hash', function(storeHash) {
|
||||
var equal, error,
|
||||
nameHash = name + '-hash',
|
||||
isContain = Util.isContainStr(loadHash, 'error');
|
||||
|
||||
if (isContain)
|
||||
error = loadHash;
|
||||
else if (loadHash === storeHash)
|
||||
equal = true;
|
||||
|
||||
Util.exec(callback, error, equal, loadHash);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -1440,6 +1387,8 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
Util.exec(callback);
|
||||
else
|
||||
Util.ifExec(hash, function() {
|
||||
var Storage = DOM.Storage;
|
||||
|
||||
Storage.set(nameHash, hash);
|
||||
Storage.set(nameData, data);
|
||||
|
||||
|
|
@ -1463,6 +1412,7 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
this.getDataFromStorage = function(name, callback) {
|
||||
CloudCmd.getConfig(function(config) {
|
||||
var data, hash,
|
||||
Storage = DOM.Storage,
|
||||
nameHash = name + '-hash',
|
||||
nameData = name + '-data',
|
||||
allowed = config.localStorage,
|
||||
|
|
@ -1471,10 +1421,20 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
if (!allowed || isDir)
|
||||
Util.exec(callback);
|
||||
else {
|
||||
data = Storage.get(nameData);
|
||||
hash = Storage.get(nameHash);
|
||||
Util.asyncCall([
|
||||
function(callback) {
|
||||
Storage.get(nameData, function(data) {
|
||||
Util.exec(callback, data);
|
||||
});
|
||||
},
|
||||
function(callback) {
|
||||
Storage.get(nameHash, function(hash) {
|
||||
Util.exec(callback, hash);
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
|
||||
|
||||
Util.exec(callback, data, hash);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -1592,50 +1552,53 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
|
||||
/**
|
||||
* remove current file from file table
|
||||
* @pCurrent
|
||||
* @param current
|
||||
*
|
||||
*/
|
||||
this.deleteCurrent = function(pCurrent, pNextFile, pPreviousFile, pNotSet) {
|
||||
var lCurrent = pCurrent || Cmd.getCurrentFile(),
|
||||
lParent = lCurrent && lCurrent.parentElement,
|
||||
lName = Cmd.getCurrentName(lCurrent);
|
||||
this.deleteCurrent = function(current) {
|
||||
var name, next, prev, parent;
|
||||
|
||||
if (lCurrent && lParent && lName !== '..') {
|
||||
var lNext = pNextFile || lCurrent.nextSibling,
|
||||
lPrevious = pPreviousFile || lCurrent.previousSibling;
|
||||
if (!current)
|
||||
Cmd.getCurrentFile();
|
||||
|
||||
parent = current && current.parentElement;
|
||||
name = Cmd.getCurrentName(current);
|
||||
|
||||
if (current && name !== '..') {
|
||||
next = current.nextSibling,
|
||||
prev = current.previousSibling;
|
||||
|
||||
if (!pNotSet)
|
||||
if (lNext)
|
||||
this.setCurrentFile(lNext);
|
||||
else if (lPrevious)
|
||||
this.setCurrentFile(lPrevious);
|
||||
|
||||
lParent.removeChild(lCurrent);
|
||||
if (next)
|
||||
this.setCurrentFile(next);
|
||||
else if (prev)
|
||||
this.setCurrentFile(prev);
|
||||
|
||||
parent.removeChild(current);
|
||||
}
|
||||
|
||||
return lCurrent;
|
||||
return current;
|
||||
};
|
||||
|
||||
/**
|
||||
* remove selected files from file table
|
||||
* @Selected
|
||||
*/
|
||||
this.deleteSelected = function(pSelected) {
|
||||
var lSelected = pSelected || this.getSelectedFiles();
|
||||
this.deleteSelected = function(selected) {
|
||||
var i, n, last, current;
|
||||
|
||||
if (lSelected) {
|
||||
var n = lSelected.length,
|
||||
lLast = n-1,
|
||||
lNext = lSelected[lLast].nextSibling,
|
||||
lPrev = lSelected[0].previousSibling;
|
||||
if (!selected)
|
||||
selected = this.getSelectedFiles();
|
||||
|
||||
if (selected) {
|
||||
n = selected.length;
|
||||
|
||||
/* lSelected[0] - becouse lSelected is a link to DOM so
|
||||
* when we remove 0 element, it's removed from lSelected to
|
||||
*/
|
||||
for(var i = 0; i < n; i++)
|
||||
this.deleteCurrent( lSelected[0], lNext, lPrev, i !== lLast);
|
||||
for (i = 0; i < n; i++) {
|
||||
current = selected[i];
|
||||
this.deleteCurrent(current);
|
||||
}
|
||||
}
|
||||
|
||||
return lSelected;
|
||||
return selected;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1643,23 +1606,29 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
*
|
||||
* @pCurrent
|
||||
*/
|
||||
this.renameCurrent = function(pCurrentFile) {
|
||||
if (!Cmd.isCurrentFile(pCurrentFile))
|
||||
pCurrentFile = null;
|
||||
this.renameCurrent = function(current) {
|
||||
var from, to, dirPath, cmp, files;
|
||||
|
||||
var lCurrent = pCurrentFile || Cmd.getCurrentFile(),
|
||||
lFrom = Cmd.getCurrentName(lCurrent),
|
||||
lTo = Dialog.prompt('Rename', lFrom) || lFrom,
|
||||
lDirPath = Cmd.getCurrentDirPath();
|
||||
if (!Cmd.isCurrentFile(current))
|
||||
current = Cmd.getCurrentFile();
|
||||
|
||||
if (!Util.strCmp(lFrom, lTo)) {
|
||||
var lFiles = {
|
||||
from : lDirPath + lFrom,
|
||||
to : lDirPath + lTo
|
||||
from = Cmd.getCurrentName(current),
|
||||
to = Dialog.prompt('Rename', from) || from,
|
||||
dirPath = Cmd.getCurrentDirPath();
|
||||
cmp = Util.strCmp(from, to);
|
||||
|
||||
if (!cmp) {
|
||||
files = {
|
||||
from : dirPath + from,
|
||||
to : dirPath + to
|
||||
};
|
||||
|
||||
RESTful.mv(lFiles, function() {
|
||||
DOM.setCurrentName(lTo, lCurrent);
|
||||
RESTful.mv(files, function() {
|
||||
var Storage = DOM.Storage,
|
||||
path = CloudFunc.rmLastSlash(dirPath);
|
||||
|
||||
DOM.setCurrentName(to, current);
|
||||
Storage.remove(path);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -1669,30 +1638,35 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
*
|
||||
* @pCurrent
|
||||
*/
|
||||
this.moveCurrent = function(pCurrentFile) {
|
||||
if (!Cmd.isCurrentFile(pCurrentFile))
|
||||
pCurrentFile = null;
|
||||
this.moveCurrent = function(current) {
|
||||
var name, from, to, cmp, files;
|
||||
|
||||
var lCurrent = pCurrentFile || Cmd.getCurrentFile(),
|
||||
lName = Cmd.getCurrentName(lCurrent),
|
||||
lFromPath = Cmd.getCurrentPath(),
|
||||
lToPath = Cmd.getNotCurrentDirPath() + lName;
|
||||
if (!Cmd.isCurrentFile(current))
|
||||
current = Cmd.getCurrentFile();
|
||||
|
||||
lToPath = Dialog.prompt('Rename/Move file "' + lName + '"', lToPath);
|
||||
name = Cmd.getCurrentName(current),
|
||||
from = Cmd.getCurrentPath(),
|
||||
to = Cmd.getNotCurrentDirPath() + name;
|
||||
|
||||
if (lToPath && !Util.strCmp(lFromPath, lToPath)) {
|
||||
var lFiles = {
|
||||
from : lFromPath,
|
||||
to : lToPath
|
||||
to = Dialog.prompt('Rename/Move file "' + name + '"', to);
|
||||
cmp = !Util.strCmp(from, to);
|
||||
|
||||
if (to && cmp) {
|
||||
files = {
|
||||
from : from,
|
||||
to : to
|
||||
};
|
||||
|
||||
RESTful.mv(lFiles, function() {
|
||||
DOM.deleteCurrent(lCurrent);
|
||||
RESTful.mv(files, function() {
|
||||
var dotDot,
|
||||
panel = DOM.getPanel(true),
|
||||
id = panel.id,
|
||||
name = '..(' + id + ')';
|
||||
|
||||
var lPanel = DOM.getPanel(true),
|
||||
lDotDot = DOM.getById( '..(' + lPanel.id + ')');
|
||||
dotDot = DOM.getById(name);
|
||||
|
||||
DOM.setCurrentFile ( lDotDot );
|
||||
DOM.deleteCurrent(current);
|
||||
DOM.setCurrentFile (dotDot);
|
||||
CloudCmd.refresh();
|
||||
});
|
||||
}
|
||||
|
|
@ -1701,29 +1675,32 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
/**
|
||||
* copy current file
|
||||
*
|
||||
* @pCurrent
|
||||
* @param current
|
||||
*/
|
||||
this.copyCurrent = function(pCurrentFile) {
|
||||
if (!Cmd.isCurrentFile(pCurrentFile))
|
||||
pCurrentFile = null;
|
||||
this.copyCurrent = function(current) {
|
||||
var name, from, to, files, cmp;
|
||||
|
||||
var lCurrent = pCurrentFile || Cmd.getCurrentFile(),
|
||||
lName = Cmd.getCurrentName(lCurrent),
|
||||
lFromPath = Cmd.getCurrentPath(),
|
||||
lToPath = Cmd.getNotCurrentDirPath() + lName;
|
||||
lToPath = Dialog.prompt( 'Copy file "' + lName + '" to', lToPath );
|
||||
if (!Cmd.isCurrentFile(current))
|
||||
current = Cmd.getCurrentFile();
|
||||
|
||||
if (lToPath && !Util.strCmp(lFromPath, lToPath)) {
|
||||
var lFiles = {
|
||||
from : lFromPath,
|
||||
to : lToPath
|
||||
name = Cmd.getCurrentName(current),
|
||||
from = Cmd.getCurrentPath(),
|
||||
to = Cmd.getNotCurrentDirPath() + name;
|
||||
to = Dialog.prompt('Copy file "' + name + '" to', to);
|
||||
cmp = Util.strCmp(from, to);
|
||||
|
||||
if (!cmp) {
|
||||
files = {
|
||||
from : from,
|
||||
to : to
|
||||
};
|
||||
|
||||
RESTful.cp(lFiles, function() {
|
||||
var lPanel = DOM.getPanel(true),
|
||||
lDotDot = DOM.getById( '..(' + lPanel.id + ')');
|
||||
RESTful.cp(files, function() {
|
||||
var panel = DOM.getPanel(true),
|
||||
id = panel.id,
|
||||
dotDot = DOM.getById( '..(' + id + ')');
|
||||
|
||||
DOM.setCurrentFile ( lDotDot );
|
||||
DOM.setCurrentFile(dotDot);
|
||||
CloudCmd.refresh();
|
||||
});
|
||||
}
|
||||
|
|
@ -1814,8 +1791,7 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
DOMTree = Util.extendProto(DOMTreeProto),
|
||||
Events = Util.extendProto(EventsProto),
|
||||
Images = Util.extendProto(ImagesProto),
|
||||
RESTful = Util.extendProto(RESTfulProto),
|
||||
Storage = Util.extendProto(StorageProto);
|
||||
RESTful = Util.extendProto(RESTfulProto);
|
||||
|
||||
DOMProto = DOMFunc.prototype = new CmdProto();
|
||||
|
||||
|
|
@ -1826,7 +1802,6 @@ var CloudCmd, Util, DOM, CloudFunc, Dialog;
|
|||
Events : Events,
|
||||
RESTful : RESTful,
|
||||
Images : Images,
|
||||
Storage : Storage,
|
||||
Dialog : Dialog
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -139,6 +139,12 @@ var CloudCmd, Util, DOM, CloudFunc, ace, DiffProto, diff_match_patch;
|
|||
exec : save
|
||||
});
|
||||
|
||||
Ace.commands.addCommand({
|
||||
name : 'saveMC',
|
||||
bindKey : { win: 'F2', mac: 'F2' },
|
||||
exec : save
|
||||
});
|
||||
|
||||
ace.require('ace/ext/language_tools');
|
||||
Modelist = ace.require('ace/ext/modelist');
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ var CloudCmd, Util, DOM;
|
|||
INSERT : 45,
|
||||
DELETE : 46,
|
||||
|
||||
ZERO : 48,
|
||||
|
||||
A : 65,
|
||||
|
||||
D : 68,
|
||||
|
|
@ -87,7 +89,7 @@ var CloudCmd, Util, DOM;
|
|||
ctrl = pEvent.ctrlKey;
|
||||
/* если клавиши можно обрабатывать*/
|
||||
if (Binded) {
|
||||
if (!lAlt && !ctrl && lKeyCode >= KEY.A && lKeyCode <= KEY.Z)
|
||||
if (!lAlt && !ctrl && lKeyCode >= KEY.ZERO && lKeyCode <= KEY.Z)
|
||||
setCurrentByLetter(lKeyCode);
|
||||
else {
|
||||
Chars = [];
|
||||
|
|
|
|||
|
|
@ -95,67 +95,9 @@ var Util, DOM, CloudCmd;
|
|||
DOM.preventDefault(event);
|
||||
},
|
||||
|
||||
/* right mouse click function varible */
|
||||
onContextMenu = function(pEvent) {
|
||||
var target,
|
||||
isFunc = Util.isFunction(CloudCmd.Menu),
|
||||
ret = true,
|
||||
Key = CloudCmd.Key;
|
||||
|
||||
/* getting html element
|
||||
* currentTarget - DOM event
|
||||
* target - jquery event
|
||||
*/
|
||||
target = pEvent.currentTarget || pEvent.target;
|
||||
DOM.setCurrentFile(target);
|
||||
|
||||
if (isFunc) {
|
||||
CloudCmd.Menu({
|
||||
x: pEvent.clientX,
|
||||
y: pEvent.clientY
|
||||
});
|
||||
|
||||
/* disabling browsers menu*/
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
/* drag and drop function varible
|
||||
* download file from browser to descktop
|
||||
* in Chrome (HTML5)
|
||||
*/
|
||||
onDragStart = function(pEvent) {
|
||||
var lElement = pEvent.target,
|
||||
EXT = 'json',
|
||||
isDir = Info.isDir,
|
||||
lLink = lElement.href,
|
||||
lName = lElement.textContent;
|
||||
|
||||
/* if it's directory - adding json extension */
|
||||
if (isDir) {
|
||||
lName += '.' + EXT;
|
||||
lLink += '?' + EXT;
|
||||
}
|
||||
|
||||
pEvent.dataTransfer.setData('DownloadURL',
|
||||
'application/octet-stream' + ':' +
|
||||
lName + ':' +
|
||||
lLink);
|
||||
},
|
||||
|
||||
setCurrentFile = function(pEvent) {
|
||||
var pElement = pEvent.target,
|
||||
lTag = pElement.tagName;
|
||||
|
||||
if (lTag !== 'LI')
|
||||
do {
|
||||
pElement = pElement.parentElement;
|
||||
lTag = pElement.tagName;
|
||||
} while(lTag !== 'LI');
|
||||
|
||||
DOM.setCurrentFile(pElement);
|
||||
onTouchEnd = function(event) {
|
||||
setCurrentFile(event);
|
||||
loadDirOnce(event);
|
||||
};
|
||||
|
||||
/* ставим загрузку гифа на клик*/
|
||||
|
|
@ -195,7 +137,7 @@ var Util, DOM, CloudCmd;
|
|||
else
|
||||
events = {
|
||||
'dblclick' : loadDirOnce,
|
||||
'touchend' : loadDirOnce,
|
||||
'touchend' : onTouchEnd,
|
||||
'click' : DOM.preventDefault,
|
||||
};
|
||||
|
||||
|
|
@ -209,6 +151,68 @@ var Util, DOM, CloudCmd;
|
|||
}
|
||||
};
|
||||
|
||||
function onContextMenu(event) {
|
||||
var target,
|
||||
isFunc = Util.isFunction(CloudCmd.Menu),
|
||||
ret = true,
|
||||
Key = CloudCmd.Key;
|
||||
|
||||
/* getting html element
|
||||
* currentTarget - DOM event
|
||||
* target - jquery event
|
||||
*/
|
||||
target = event.currentTarget || event.target;
|
||||
DOM.setCurrentFile(target);
|
||||
|
||||
if (isFunc) {
|
||||
CloudCmd.Menu({
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
});
|
||||
|
||||
/* disabling browsers menu*/
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* download file from browser to desktop
|
||||
* in Chrome (HTML5)
|
||||
*/
|
||||
function onDragStart(event) {
|
||||
var element = event.target,
|
||||
EXT = 'json',
|
||||
isDir = Info.isDir,
|
||||
link = element.href,
|
||||
name = element.textContent;
|
||||
|
||||
/* if it's directory - adding json extension */
|
||||
if (isDir) {
|
||||
name += '.' + EXT;
|
||||
link += '?' + EXT;
|
||||
}
|
||||
|
||||
event.dataTransfer.setData('DownloadURL',
|
||||
'application/octet-stream' + ':' +
|
||||
name + ':' +
|
||||
link);
|
||||
}
|
||||
|
||||
function setCurrentFile(event) {
|
||||
var element = event.target,
|
||||
tag = element.tagName;
|
||||
|
||||
if (tag !== 'LI')
|
||||
do {
|
||||
element = element.parentElement;
|
||||
tag = element.tagName;
|
||||
} while(tag !== 'LI');
|
||||
|
||||
DOM.setCurrentFile(element);
|
||||
}
|
||||
|
||||
function appStorage() {
|
||||
getConfig(function(config) {
|
||||
var isAppStorage = config.appStorage,
|
||||
|
|
@ -296,16 +300,17 @@ var Util, DOM, CloudCmd;
|
|||
}
|
||||
|
||||
function pop() {
|
||||
Events.add("popstate", function(pEvent) {
|
||||
var lPath = pEvent.state + '?json';
|
||||
Events.add("popstate", function(event) {
|
||||
var path;
|
||||
|
||||
if (pEvent.state) {
|
||||
lPath = pEvent.state + '?json';
|
||||
CloudCmd.ajaxLoad(lPath, {nohistory: true});
|
||||
} else
|
||||
if (!event.state)
|
||||
CloudCmd.route(location.hash);
|
||||
|
||||
return true;
|
||||
else {
|
||||
path = event.state + '?json';
|
||||
CloudCmd.ajaxLoad(path, {
|
||||
nohistory: true
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ var CloudCmd, Util, DOM, CloudFunc, $;
|
|||
MenuSeted = false,
|
||||
Menu = this,
|
||||
Position,
|
||||
Images = DOM.Images,
|
||||
UploadToItemNames;
|
||||
|
||||
this.ENABLED = false;
|
||||
|
|
@ -41,7 +42,7 @@ var CloudCmd, Util, DOM, CloudFunc, $;
|
|||
|
||||
if (!Loading) {
|
||||
set();
|
||||
DOM.Images.hideLoad();
|
||||
Images.hideLoad();
|
||||
|
||||
if (Position && !Position.x )
|
||||
Position = undefined;
|
||||
|
|
@ -144,7 +145,7 @@ var CloudCmd, Util, DOM, CloudFunc, $;
|
|||
* download menu item callback
|
||||
*/
|
||||
function downloadFromMenu(key, opt) {
|
||||
DOM.Images.showLoad();
|
||||
Images.showLoad();
|
||||
|
||||
var TIME = 1000,
|
||||
lPath = Info.path,
|
||||
|
|
@ -161,16 +162,16 @@ var CloudCmd, Util, DOM, CloudFunc, $;
|
|||
async : false,
|
||||
className : 'hidden',
|
||||
src : lPath,
|
||||
func : DOM.Images.hideLoad
|
||||
func : Images.hideLoad
|
||||
});
|
||||
|
||||
DOM.Images.hideLoad();
|
||||
Images.hideLoad();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(lDownload);
|
||||
}, TIME);
|
||||
}
|
||||
else
|
||||
DOM.Images.showError({
|
||||
Images.showError({
|
||||
responseText: 'Error: You trying to' +
|
||||
'download same file to often'});
|
||||
}
|
||||
|
|
@ -197,10 +198,14 @@ var CloudCmd, Util, DOM, CloudFunc, $;
|
|||
lMenuItems.Download = downloadFromMenu;
|
||||
|
||||
lMenuItems.New = {
|
||||
'File' : DOM.promptNewFile,
|
||||
'Directory' : DOM.promptNewDir,
|
||||
'File' : DOM.promptNewFile,
|
||||
'Directory' : DOM.promptNewDir,
|
||||
|
||||
'From Cloud' : function() {
|
||||
'From FilePicker' : function() {
|
||||
Images.showLoad({
|
||||
top: true
|
||||
});
|
||||
|
||||
CloudCmd.execFromModule('FilePicker', 'saveFile', function(pName, pData) {
|
||||
var lPath = DOM.getCurrentDirPath() + pName;
|
||||
|
||||
|
|
|
|||
|
|
@ -235,76 +235,4 @@ var Util, DOM, jQuery;
|
|||
};
|
||||
}
|
||||
|
||||
if (!window.localStorage) {
|
||||
var Storage = function() {
|
||||
/* приватный переключатель возможности работы с кэшем */
|
||||
var StorageAllowed,
|
||||
Data = {};
|
||||
|
||||
/* функция проверяет возможно ли работать с кэшем каким-либо образом */
|
||||
this.isAllowed = function() {
|
||||
return StorageAllowed;
|
||||
};
|
||||
|
||||
this.setAllowed = function(pAllowed) {
|
||||
StorageAllowed = pAllowed;
|
||||
return pAllowed;
|
||||
};
|
||||
|
||||
/** remove element */
|
||||
this.remove = function(pItem) {
|
||||
var lRet = this;
|
||||
if (StorageAllowed)
|
||||
delete Data[pItem];
|
||||
|
||||
return lRet;
|
||||
};
|
||||
|
||||
/** если доступен localStorage и
|
||||
* в нём есть нужная нам директория -
|
||||
* записываем данные в него
|
||||
*/
|
||||
this.set = function(pName, pData) {
|
||||
var lRet = this;
|
||||
|
||||
if (StorageAllowed && pName && pData)
|
||||
Data[pName] = pData;
|
||||
|
||||
return lRet;
|
||||
},
|
||||
|
||||
/** Если доступен Storage принимаем из него данные*/
|
||||
this.get = function(pName) {
|
||||
var lRet = false;
|
||||
|
||||
if (StorageAllowed)
|
||||
lRet = Data[pName];
|
||||
|
||||
return lRet;
|
||||
},
|
||||
|
||||
/* get all Storage from local storage */
|
||||
this.getAll = function() {
|
||||
var lRet = null;
|
||||
|
||||
if (StorageAllowed)
|
||||
lRet = Data;
|
||||
|
||||
return lRet;
|
||||
};
|
||||
|
||||
/** функция чистит весь кэш для всех каталогов*/
|
||||
this.clear = function() {
|
||||
var lRet = this;
|
||||
|
||||
if (StorageAllowed)
|
||||
Data = {};
|
||||
|
||||
return lRet;
|
||||
};
|
||||
};
|
||||
|
||||
DOM.Storage = new Storage();
|
||||
}
|
||||
|
||||
})(Util, DOM, jQuery);
|
||||
})(Util, DOM, jQuery);
|
||||
|
|
|
|||
85
lib/client/storage.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
var Util, DOM;
|
||||
|
||||
(function(Util, DOM) {
|
||||
'use strict';
|
||||
|
||||
|
||||
var Storage = Util.extendProto(StorageProto),
|
||||
DOMProto = Object.getPrototypeOf(DOM);
|
||||
|
||||
Util.extend(DOMProto, {
|
||||
Storage: Storage
|
||||
});
|
||||
|
||||
function StorageProto() {
|
||||
/* приватный переключатель возможности работы с кэшем */
|
||||
var Allowed;
|
||||
|
||||
/* функция проверяет возможно ли работать с кэшем каким-либо образом */
|
||||
this.isAllowed = function() {
|
||||
var ret = Allowed && !!window.localStorage;
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* allow Storage usage
|
||||
*/
|
||||
this.setAllowed = function(isAllowed) {
|
||||
Allowed = isAllowed;
|
||||
};
|
||||
|
||||
/** remove element */
|
||||
this.remove = function(item, callback) {
|
||||
var ret = Allowed;
|
||||
|
||||
if (ret)
|
||||
localStorage.removeItem(item);
|
||||
|
||||
Util.exec(callback, ret);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** если доступен localStorage и
|
||||
* в нём есть нужная нам директория -
|
||||
* записываем данные в него
|
||||
*/
|
||||
this.set = function(name, data, callback) {
|
||||
var str, ret = Allowed && name;
|
||||
|
||||
if (Util.isObject(data))
|
||||
str = Util.stringifyJSON(data);
|
||||
|
||||
if (Allowed && name)
|
||||
localStorage.setItem(name, str || data);
|
||||
|
||||
Util.exec(callback, ret);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Если доступен Storage принимаем из него данные*/
|
||||
this.get = function(name, callback) {
|
||||
var ret;
|
||||
|
||||
if (Allowed)
|
||||
ret = localStorage.getItem(name);
|
||||
|
||||
Util.exec(callback, ret);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/** функция чистит весь кэш для всех каталогов*/
|
||||
this.clear = function(callback) {
|
||||
var ret = Allowed;
|
||||
|
||||
if (ret)
|
||||
localStorage.clear();
|
||||
|
||||
Util.exec(callback, ret);
|
||||
|
||||
return this;
|
||||
};
|
||||
}
|
||||
})(Util, DOM);
|
||||
|
|
@ -51,40 +51,42 @@ var CloudCmd, Util, DOM, CloudFunc, Github, cb;
|
|||
}
|
||||
|
||||
|
||||
GitHub.autorize = function(pCallBack, pCode) {
|
||||
var lCode, lToken = Storage.get('token');
|
||||
|
||||
if (lToken) {
|
||||
GitHub.Login(lToken);
|
||||
Util.exec(pCallBack);
|
||||
}
|
||||
else {
|
||||
lCode = pCode || window.location.search;
|
||||
|
||||
if (lCode || Util.isContainStr(lCode, '?code=') )
|
||||
CloudCmd.getConfig(function(pConfig) {
|
||||
DOM.ajax({
|
||||
type : 'put',
|
||||
url : pConfig && pConfig.apiURL + '/auth',
|
||||
data : Util.removeStr(lCode, '?code='),
|
||||
success : function(pData) {
|
||||
if (pData && pData.token) {
|
||||
lToken = pData.token;
|
||||
|
||||
GitHub.Login(lToken);
|
||||
Storage.set('token', lToken);
|
||||
Util.exec(pCallBack);
|
||||
GitHub.autorize = function(callback, code) {
|
||||
Storage.get('token', function(token) {
|
||||
var code, isContain,
|
||||
URL = '//' + window.location.host + '/auth/github';
|
||||
|
||||
if (token) {
|
||||
GitHub.Login(token);
|
||||
Util.exec(callback);
|
||||
} else {
|
||||
if (!code)
|
||||
code = window.location.search;
|
||||
|
||||
isContain = Util.isContainStr(code, '?code=');
|
||||
|
||||
if (!isContain)
|
||||
DOM.openWindow(URL);
|
||||
else
|
||||
CloudCmd.getConfig(function(config) {
|
||||
DOM.ajax({
|
||||
type : 'put',
|
||||
url : config && config.apiURL + '/auth',
|
||||
data : Util.removeStr(code, '?code='),
|
||||
success : function(data) {
|
||||
if (data && data.token) {
|
||||
token = data.token;
|
||||
|
||||
GitHub.Login(token);
|
||||
Storage.set('token', token);
|
||||
Util.exec(callback);
|
||||
} else
|
||||
Util.log('Worning: token not getted...');
|
||||
}
|
||||
else
|
||||
Util.log('Worning: token not getted...');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
else{
|
||||
var lUrl = '//' + window.location.host + '/auth/github';
|
||||
DOM.openWindow(lUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
GitHub.getUserData = function(pCallBack) {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ var CloudCmd, Util, DOM, CloudFunc, $;
|
|||
$.fancybox(element, config);
|
||||
|
||||
} else {
|
||||
Images.showLoad();
|
||||
path = CloudFunc.FS + Info.path;
|
||||
isImage = $.fancybox.isImage(path);
|
||||
|
||||
|
|
|
|||
192
lib/server.js
|
|
@ -1,4 +1,4 @@
|
|||
(function() {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
if (!global.cloudcmd)
|
||||
|
|
@ -52,108 +52,120 @@
|
|||
* @param pProcessing {index, appcache, rest}
|
||||
*/
|
||||
function start(options) {
|
||||
var redirectServer,
|
||||
config = main.config;
|
||||
var redirectServer, port, ip, ssl, sslPort,
|
||||
HTTP = 'http://',
|
||||
HTTPS = 'https://',
|
||||
config = main.config;
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
Rest = options.rest;
|
||||
Route = options.route;
|
||||
Rest = options.rest;
|
||||
Route = options.route;
|
||||
|
||||
init(options.appcache);
|
||||
|
||||
var lPort = process.env.PORT || /* c9 */
|
||||
process.env.app_port || /* nodester */
|
||||
process.env.VCAP_APP_PORT || /* cloudfoundry */
|
||||
config.port,
|
||||
|
||||
lIP = process.env.IP || /* c9 */
|
||||
config.ip ||
|
||||
(main.WIN32 ? '127.0.0.1' : '0.0.0.0'),
|
||||
|
||||
lSSL = options.ssl,
|
||||
lSSLPort = config.sslPort,
|
||||
lHTTP = 'http://',
|
||||
lHTTPS = 'https://',
|
||||
|
||||
lSockets = function(pServer) {
|
||||
var listen, msg,
|
||||
status = 'off';
|
||||
|
||||
if (config.socket && Socket) {
|
||||
listen = Socket.listen(pServer);
|
||||
|
||||
if (listen) {
|
||||
status = 'on';
|
||||
Console.init();
|
||||
Terminal.init();
|
||||
}
|
||||
}
|
||||
|
||||
msg = CloudFunc.formatMsg('sockets', '', status);
|
||||
|
||||
Util.log(msg);
|
||||
},
|
||||
|
||||
lHTTPServer = function() {
|
||||
expressApp = express.getApp([
|
||||
Rest,
|
||||
Route,
|
||||
join,
|
||||
controller
|
||||
]);
|
||||
|
||||
Server = http.createServer(expressApp || respond);
|
||||
|
||||
Server.on('error', Util.log.bind(Util));
|
||||
Server.listen(lPort, lIP);
|
||||
lServerLog(lHTTP, lPort);
|
||||
lSockets(Server);
|
||||
},
|
||||
|
||||
lServerLog = function(http, port) {
|
||||
Util.log('* Server running at ' + http + lIP + ':' + port);
|
||||
};
|
||||
port = process.env.PORT || /* c9 */
|
||||
process.env.app_port || /* nodester */
|
||||
process.env.VCAP_APP_PORT || /* cloudfoundry */
|
||||
config.port,
|
||||
ip = process.env.IP || /* c9 */
|
||||
config.ip ||
|
||||
(main.WIN32 ? '127.0.0.1' : '0.0.0.0'),
|
||||
|
||||
ssl = options.ssl,
|
||||
sslPort = config.sslPort;
|
||||
|
||||
/* server mode or testing mode */
|
||||
if (config.server)
|
||||
if (lSSL) {
|
||||
Util.log('* Redirection http -> https is setted up');
|
||||
lServerLog(lHTTP, lPort);
|
||||
if (!config.server)
|
||||
Util.log('Cloud Commander testing mode');
|
||||
else
|
||||
if (!ssl)
|
||||
createServer(port, ip, HTTP);
|
||||
else {
|
||||
createRedirect(port, ip, HTTPS, sslPort);
|
||||
|
||||
redirectServer = http.createServer(function(req, res) {
|
||||
var url,
|
||||
host = req.headers.host,
|
||||
parsed = url.parse(host),
|
||||
hostName = parsed.protocol;
|
||||
|
||||
url = lHTTPS + hostName + lSSLPort + req.url;
|
||||
|
||||
main.redirect({
|
||||
response: res,
|
||||
url: url
|
||||
});
|
||||
});
|
||||
|
||||
redirectServer.listen(lPort, lIP);
|
||||
|
||||
Server = https.createServer(lSSL, respond);
|
||||
Server.on('error', function (error) {
|
||||
Util.log('Could not use https port: ' + lSSLPort);
|
||||
Util.log(error);
|
||||
createServer(sslPort, ip, HTTP, ssl, function() {
|
||||
Util.log('Could not use https port: ' + sslPort);
|
||||
redirectServer.close();
|
||||
Util.log('* Redirection http -> https removed');
|
||||
lHTTPServer();
|
||||
createServer(port, ip);
|
||||
});
|
||||
|
||||
lSockets(Server);
|
||||
|
||||
Server.listen(lSSLPort, lIP);
|
||||
lServerLog(lHTTPS, lSSLPort);
|
||||
} else
|
||||
lHTTPServer();
|
||||
}
|
||||
}
|
||||
|
||||
function createRedirect(port, ip, protocol, sslPort) {
|
||||
var server = function(req, res) {
|
||||
var url,
|
||||
host = req.headers.host,
|
||||
parsed = URL.parse(host),
|
||||
hostName = parsed.protocol;
|
||||
|
||||
url = protocol + hostName + sslPort + req.url;
|
||||
|
||||
main.redirect({
|
||||
response: res,
|
||||
url: url
|
||||
});
|
||||
};
|
||||
|
||||
Util.log('* Redirection http -> https is setted up');
|
||||
logServer(port, ip, protocol);
|
||||
|
||||
http.createServer(server)
|
||||
.listen(port, ip);
|
||||
}
|
||||
|
||||
function createServer(port, ip, protocol, ssl, callback) {
|
||||
var server, app;
|
||||
|
||||
expressApp = express.getApp([
|
||||
Rest,
|
||||
Route,
|
||||
join,
|
||||
controller
|
||||
]);
|
||||
|
||||
app = expressApp || respond;
|
||||
|
||||
if (ssl)
|
||||
server = https.createServer(ssl, app);
|
||||
else
|
||||
Util.log('Cloud Commander testing mode');
|
||||
server = http.createServer(app);
|
||||
|
||||
server.on('error', function(error) {
|
||||
Util.log(error);
|
||||
Util.exec(callback, error);
|
||||
});
|
||||
|
||||
server.listen(port, ip);
|
||||
|
||||
logServer(port, ip, protocol);
|
||||
addSockets(server);
|
||||
}
|
||||
|
||||
function logServer(port, ip, http) {
|
||||
Util.log('* Server running at ' + http + ip + ':' + port);
|
||||
}
|
||||
|
||||
function addSockets(server) {
|
||||
var listen, msg,
|
||||
config = main.config,
|
||||
status = 'off';
|
||||
|
||||
if (config.socket && Socket) {
|
||||
listen = Socket.listen(server);
|
||||
|
||||
if (listen) {
|
||||
status = 'on';
|
||||
Console.init();
|
||||
Terminal.init();
|
||||
}
|
||||
}
|
||||
|
||||
msg = CloudFunc.formatMsg('sockets', '', status);
|
||||
|
||||
Util.log(msg);
|
||||
}
|
||||
|
||||
function respond(req, res) {
|
||||
|
|
|
|||
|
|
@ -197,37 +197,40 @@
|
|||
* query
|
||||
* https://developers.google.com/speed/docs/best-practices/caching?hl=ru#LeverageProxyCaching
|
||||
*/
|
||||
function generateHeaders(pParams) {
|
||||
var lRet = Util.checkObjTrue(pParams, ['name']);
|
||||
function generateHeaders(params) {
|
||||
var header, p, extension, type, encoding, isContain, cmp;
|
||||
|
||||
if (lRet) {
|
||||
var p = pParams,
|
||||
lExt = Util.getExtension(p.name),
|
||||
lType = ext[lExt] || 'text/plain',
|
||||
lContentEncoding = '';
|
||||
if (params.name) {
|
||||
p = params,
|
||||
extension = Util.getExtension(p.name),
|
||||
type = ext[extension] || 'text/plain',
|
||||
encoding = '';
|
||||
|
||||
/* if type of file any, but img - then we shoud specify charset */
|
||||
if (!Util.isContainStr(lType, 'img'))
|
||||
lContentEncoding = '; charset=UTF-8';
|
||||
isContain = Util.isContainStr(type, ['img', 'image']);
|
||||
if (!isContain)
|
||||
encoding = '; charset=UTF-8';
|
||||
|
||||
if (Util.isContainStr(p.query, 'download'))
|
||||
lType = 'application/octet-stream';
|
||||
isContain = Util.isContainStr(p.query, 'download');
|
||||
if (isContain)
|
||||
type = 'application/octet-stream';
|
||||
|
||||
lRet = {
|
||||
header = {
|
||||
'Access-Control-Allow-Origin' : '*',
|
||||
'Content-Type' : lType + lContentEncoding,
|
||||
'last-modified' : new Date().toString(),
|
||||
'Content-Type' : type + encoding,
|
||||
'last-modified' : '' + new Date(),
|
||||
'Vary' : 'Accept-Encoding'
|
||||
};
|
||||
|
||||
if (!Util.strCmp(lExt, '.appcache') && p.cache)
|
||||
lRet['cache-control'] = 'max-age=' + 31337 * 21;
|
||||
cmp = Util.strCmp(ext, '.appcache');
|
||||
if (!cmp && p.cache)
|
||||
header['cache-control'] = 'max-age=' + 31337 * 21;
|
||||
|
||||
if (p.gzip)
|
||||
lRet['content-encoding'] = 'gzip';
|
||||
header['content-encoding'] = 'gzip';
|
||||
}
|
||||
|
||||
return lRet;
|
||||
return header;
|
||||
}
|
||||
|
||||
function mainSetHeader(pParams) {
|
||||
|
|
|
|||
|
|
@ -103,115 +103,69 @@
|
|||
p.command = Util.removeStrOneTime(p.name, '/');
|
||||
|
||||
switch(p.request.method) {
|
||||
case 'GET':
|
||||
ret = onGET(pParams);
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
getBody(p.request, function(pBody) {
|
||||
p.body = pBody;
|
||||
onPUT(p);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'GET':
|
||||
ret = onGET(pParams);
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
getBody(p.request, function(pBody) {
|
||||
p.body = pBody;
|
||||
onPUT(p);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function onFS(params) {
|
||||
var p, lQuery, isGet,
|
||||
var p, query, isGet,
|
||||
ret = main.checkParams(params);
|
||||
|
||||
if (ret) {
|
||||
p = params;
|
||||
lQuery = main.getQuery(p.request);
|
||||
query = main.getQuery(p.request);
|
||||
p.name = Util.removeStrOneTime(p.name, CloudFunc.FS) || '/';
|
||||
|
||||
switch (p.request.method) {
|
||||
case 'GET':
|
||||
isGet = onFSGet(lQuery, p.name, function(error, result) {
|
||||
checkSendError(error, params, function() {
|
||||
sendResponse(p, result);
|
||||
});
|
||||
});
|
||||
|
||||
if (!isGet)
|
||||
fs.stat(p.name, function(error, stat) {
|
||||
var getDirContent = main.commander.getDirContent;
|
||||
onFSGet(query, p.name, function(error, data, name, isFile) {
|
||||
if (error)
|
||||
sendError(params, error);
|
||||
else if (isFile) {
|
||||
p.name = name;
|
||||
p.data = data;
|
||||
|
||||
if (error)
|
||||
Util.exec(error);
|
||||
else
|
||||
if (!stat.isDirectory())
|
||||
main.sendFile(p);
|
||||
else
|
||||
getDirContent(p.name, function(pError, pData) {
|
||||
checkSendError(pError, p, function() {
|
||||
p.name += '.json';
|
||||
p.data = Util.stringifyJSON(pData);
|
||||
sendResponse(p);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
main.sendFile(p);
|
||||
} else
|
||||
sendResponse(p, data);
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case 'PUT':
|
||||
if (lQuery === 'dir')
|
||||
fse.mkdirs(p.name, function(pError) {
|
||||
checkSendError(pError, params, function() {
|
||||
sendMsg(params, 'make dir', p.name);
|
||||
});
|
||||
});
|
||||
else if (lQuery === 'patch')
|
||||
getBody(p.request, function(patch) {
|
||||
fs.readFile(p.name, 'utf8', read.bind(null, p.name));
|
||||
|
||||
function read(name, error, data) {
|
||||
checkSendError(error, p.params, function() {
|
||||
var diffResult;
|
||||
|
||||
ret = Util.tryCatchLog(function() {
|
||||
diffResult = diff.applyPatch(data, patch);
|
||||
});
|
||||
|
||||
if (diffResult && !ret)
|
||||
fs.writeFile(name, diffResult, write.bind(null, name));
|
||||
else {
|
||||
name = path.basename(name);
|
||||
sendMsg(p.params, 'patch', name, 'fail');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function write(name, error) {
|
||||
checkSendError(error, params, function() {
|
||||
name = path.basename(name);
|
||||
sendMsg(params, 'patch', name);
|
||||
});
|
||||
}
|
||||
});
|
||||
else
|
||||
pipe.create({
|
||||
read : p.request,
|
||||
to : p.name,
|
||||
callback : function(pError) {
|
||||
checkSendError(pError, params, function() {
|
||||
var lName = path.basename(p.name);
|
||||
sendMsg(params, 'save', lName);
|
||||
});
|
||||
}
|
||||
});
|
||||
onFSPut(p.name, query, p.request, function(error, msg) {
|
||||
if (error)
|
||||
sendError(params, error);
|
||||
else
|
||||
sendResponse(params, msg);
|
||||
});
|
||||
break;
|
||||
|
||||
case 'DELETE':
|
||||
onDelete(params, lQuery, function(error, msg, callback) {
|
||||
checkSendError(error, params, function() {
|
||||
if (callback)
|
||||
Util.exec(callback);
|
||||
else
|
||||
sendMsg(params, 'delete', msg);
|
||||
getBody(p.request, function(body) {
|
||||
var files = Util.parseJSON(body);
|
||||
|
||||
onDelete(p.name, files, query, function(error, callback) {
|
||||
checkSendError(error, params, function() {
|
||||
var names = files.length ? files : p.name;
|
||||
|
||||
if (callback)
|
||||
Util.exec(callback);
|
||||
else
|
||||
sendMsg(params, 'delete', names);
|
||||
});
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
|
@ -221,57 +175,123 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
function onDelete(params, query, callback) {
|
||||
var rmFile = fs.unlink.bind(fs),
|
||||
rmDir = fse.remove.bind(fse),
|
||||
p = params;
|
||||
function onFSPut(name, query, readStream, callback) {
|
||||
var func = Util.retExec(callback),
|
||||
baseName = path.basename(name);
|
||||
|
||||
if (query === 'dir')
|
||||
rmDir(p.name, function(error) {
|
||||
Util.exec(callback, error, p.name);
|
||||
});
|
||||
else if (query === 'files')
|
||||
getBody(p.request, function(body) {
|
||||
var i, name,
|
||||
files = Util.parseJSON(body),
|
||||
n = files.length,
|
||||
dir = p.name,
|
||||
log = Util.log.bind(Util),
|
||||
assync = 0;
|
||||
switch(query) {
|
||||
case 'dir':
|
||||
fse.mkdirs(name, function(error) {
|
||||
var msg;
|
||||
|
||||
function onStat(name, error, stat) {
|
||||
++assync;
|
||||
if (!error)
|
||||
msg = CloudFunc.formatMsg('make dir', name);
|
||||
|
||||
func(error, msg);
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
pipe.create({
|
||||
read : readStream,
|
||||
to : name,
|
||||
callback : function(error) {
|
||||
var msg;
|
||||
|
||||
if (!error)
|
||||
msg = CloudFunc.formatMsg('save', baseName);
|
||||
|
||||
func(error, msg);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case 'patch':
|
||||
getBody(readStream, function(patch) {
|
||||
fs.readFile(name, 'utf8', read);
|
||||
|
||||
function read(error, data) {
|
||||
var diffResult;
|
||||
|
||||
if (error)
|
||||
Util.exec(callback, error);
|
||||
func(error);
|
||||
else {
|
||||
if (stat.isDirectory())
|
||||
rmDir(name, log);
|
||||
error = Util.tryCatchLog(function() {
|
||||
diffResult = diff.applyPatch(data, patch);
|
||||
});
|
||||
|
||||
else if (stat.isFile())
|
||||
rmFile(name, log);
|
||||
|
||||
if (assync === n)
|
||||
Util.exec(callback, null, body);
|
||||
if (diffResult && !error)
|
||||
fs.writeFile(name, diffResult, write);
|
||||
else {
|
||||
msg = CloudFunc.formatMsg('patch', baseName, 'fail');
|
||||
func(null, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i ++) {
|
||||
name = dir + files[i];
|
||||
function write(name, error) {
|
||||
var msg;
|
||||
|
||||
Util.log(name);
|
||||
if (!error)
|
||||
msg = CloudFunc.formatMsg('patch', baseName);
|
||||
|
||||
fs.stat(name, onStat.bind(null, name));
|
||||
func(error, msg);
|
||||
}
|
||||
});
|
||||
else
|
||||
rmFile(p.name, function(error) {
|
||||
Util.exec(callback, error, p.name);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function onDelete(name, files, query, callback) {
|
||||
var i, n, onStat,
|
||||
assync = 0,
|
||||
rmFile = fs.unlink.bind(fs),
|
||||
rmDir = fse.remove.bind(fse),
|
||||
func = Util.retExec(callback);
|
||||
|
||||
switch(query) {
|
||||
default:
|
||||
rmFile(name, func);
|
||||
break;
|
||||
|
||||
case 'dir':
|
||||
rmDir(name, func);
|
||||
break;
|
||||
|
||||
case 'files':
|
||||
n = files && files.length,
|
||||
dir = name;
|
||||
|
||||
onStat = function(name, error, stat) {
|
||||
var log = Util.log.bind(Util);
|
||||
++assync;
|
||||
|
||||
if (error)
|
||||
func(error);
|
||||
else {
|
||||
if (stat.isDirectory())
|
||||
rmDir(name, log);
|
||||
|
||||
else if (stat.isFile())
|
||||
rmFile(name, log);
|
||||
|
||||
if (assync === n)
|
||||
func();
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 0; i < n; i ++) {
|
||||
name = dir + files[i];
|
||||
Util.log(name);
|
||||
fs.stat(name, onStat.bind(null, name));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function onFSGet(query, name, callback) {
|
||||
var msg, hash, ret = true;
|
||||
var error, hash,
|
||||
func = Util.retExec(callback);
|
||||
|
||||
switch (query) {
|
||||
case 'size':
|
||||
|
|
@ -279,14 +299,18 @@
|
|||
if (!error)
|
||||
size = CloudFunc.getShortSize(size);
|
||||
|
||||
Util.exec(callback, error, size);
|
||||
func(error, size);
|
||||
});
|
||||
break;
|
||||
|
||||
case 'time':
|
||||
time.get(name, function(error, time) {
|
||||
var timeStr = time.toString();
|
||||
Util.exec(callback, error, timeStr);
|
||||
var timeStr;
|
||||
|
||||
if (!error)
|
||||
timeStr = time.toString();
|
||||
|
||||
func(error, timeStr);
|
||||
});
|
||||
break;
|
||||
|
||||
|
|
@ -294,26 +318,46 @@
|
|||
hash = Hash.create();
|
||||
|
||||
if (!hash) {
|
||||
msg = 'not suported, try update node';
|
||||
msg = CloudFunc.formatMsg('hash', msg, 'error');
|
||||
Util.exec(callback, msg);
|
||||
error = 'not suported, try update node';
|
||||
error = CloudFunc.formatMsg('hash', error, 'error');
|
||||
func(error);
|
||||
} else
|
||||
pipe.create({
|
||||
from : name,
|
||||
write : hash,
|
||||
callback : function (error) {
|
||||
var hex = hash.get();
|
||||
Util.exec(callback, error, hex);
|
||||
var hex;
|
||||
|
||||
if (!error)
|
||||
hash = hash.get();
|
||||
|
||||
func(error, hash);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = false;
|
||||
fs.stat(name, function(error, stat) {
|
||||
var getDirContent = main.commander.getDirContent,
|
||||
isFile = !stat.isDirectory();
|
||||
|
||||
if (error)
|
||||
func(error);
|
||||
else
|
||||
if (isFile)
|
||||
func(null, null, null, isFile);
|
||||
else
|
||||
getDirContent(name, function(error, data) {
|
||||
if (!error) {
|
||||
name += '.json';
|
||||
data = Util.stringifyJSON(data);
|
||||
}
|
||||
|
||||
func(error, name, data);
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -454,18 +498,18 @@
|
|||
/**
|
||||
* get body of url query
|
||||
*
|
||||
* @param pReq
|
||||
* @param pCallBack
|
||||
* @param req
|
||||
* @param callback
|
||||
*/
|
||||
function getBody(req, pCallBack) {
|
||||
var lBody = '';
|
||||
function getBody(req, callback) {
|
||||
var body = '';
|
||||
|
||||
req.on('data', function(chunk) {
|
||||
lBody += chunk.toString();
|
||||
body += chunk.toString();
|
||||
});
|
||||
|
||||
req.on('end', function() {
|
||||
Util.exec(pCallBack, lBody);
|
||||
Util.exec(callback, body);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
53
lib/util.js
|
|
@ -565,42 +565,43 @@
|
|||
|
||||
/**
|
||||
* function render template with view
|
||||
* @pTempl
|
||||
* @pView
|
||||
* @templ
|
||||
* @view
|
||||
*/
|
||||
this.render = function(pTempl, pView) {
|
||||
var lRet = Util.ownRender(pTempl, pView);
|
||||
this.render = function(templ, view) {
|
||||
var ret,
|
||||
NOT_ESCAPE = true,
|
||||
SPACES = '\\s*',
|
||||
symbols = ['{{' + SPACES, SPACES + '}}'];
|
||||
|
||||
ret = Util.ownRender(templ, view, symbols, NOT_ESCAPE);
|
||||
|
||||
return lRet;
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* function render template with view and own symbols
|
||||
* @pTempl
|
||||
* @pView
|
||||
* @pSymbols
|
||||
* @templ
|
||||
* @view
|
||||
* @symbols
|
||||
*/
|
||||
this.ownRender = function(pTempl, pView, pSymbols) {
|
||||
var SPACES = '\\s*';
|
||||
|
||||
if (!pSymbols)
|
||||
pSymbols = ['{{' + SPACES, SPACES + '}}'];
|
||||
|
||||
var lRet = pTempl,
|
||||
lFirstChar,
|
||||
lSecondChar;
|
||||
this.ownRender = function(templ, view, symbols, notEscape) {
|
||||
var str, param, expr,
|
||||
ret = templ,
|
||||
firstChar,
|
||||
secondChar;
|
||||
|
||||
lFirstChar = pSymbols[0];
|
||||
lSecondChar = pSymbols[1] || lFirstChar;
|
||||
firstChar = symbols[0];
|
||||
secondChar = symbols[1] || firstChar;
|
||||
|
||||
for(var lVar in pView) {
|
||||
var lStr = pView[lVar];
|
||||
lStr = Util.exec(lStr) || lStr;
|
||||
|
||||
lRet = Util.replaceStr(lRet, lFirstChar + lVar + lSecondChar, lStr, true);
|
||||
for (param in view) {
|
||||
str = view[param];
|
||||
str = Util.exec(str) || str;
|
||||
expr = firstChar + param + secondChar;
|
||||
ret = Util.replaceStr(ret, expr, str, notEscape);
|
||||
}
|
||||
|
||||
return lRet;
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -853,7 +854,7 @@
|
|||
args = Util.slice(arguments, 1);
|
||||
|
||||
if (Util.isFunction(callback))
|
||||
ret = callback.apply(null, args);
|
||||
ret = callback.apply(null, args);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cloudcmd",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.2",
|
||||
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
||||
"description": "Cloud Commander - file manager with console and editor",
|
||||
"homepage": "http://cloudcmd.io",
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
"subdomain": "cloudcmd",
|
||||
"dependencies": {
|
||||
"dropbox": "0.10.2",
|
||||
"minify": "0.2.5",
|
||||
"minify": "0.2.6",
|
||||
"socket.io": "0.9.16",
|
||||
"express": "3.4.x",
|
||||
"http-auth": "2.1.x",
|
||||
|
|
|
|||
12
shell/log.sh
|
|
@ -1,8 +1,14 @@
|
|||
#!/bin/sh
|
||||
if test -z $1
|
||||
then
|
||||
echo "log.sh <tag>"
|
||||
echo 'log.sh <tag>'
|
||||
else
|
||||
git log $1..HEAD --pretty=format:"- %s" --grep fix
|
||||
git log $1..HEAD --pretty=format:"- %s" --grep feature
|
||||
echo 'fix:'
|
||||
git log $1..HEAD --pretty=format:"- %s" --grep fix | sed 's/fix//g'
|
||||
echo '\n'
|
||||
|
||||
echo 'feature:'
|
||||
git log $1..HEAD --pretty=format:"- %s" --grep feature | sed 's/feature//g'
|
||||
|
||||
echo '\n\n'
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
|
||||
Expect =
|
||||
'<div id="js-path" class="reduce-text" title="/etc/X11/">' +
|
||||
'<div data="js-path" class="reduce-text" title="/etc/X11/">' +
|
||||
'<span class="path-icon clear-storage" ' +
|
||||
'title="clear storage (Ctrl+D)">' +
|
||||
'</span>' +
|
||||
|
|
|
|||