diff --git a/ChangeLog b/ChangeLog index 888f6c01..d624365b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,87 @@ +2013.11.08, v0.6.0 + +update: +- minify v0.2.3 +- dropbox: 0.10.1 -> 0.10.2 +- express: 3.4.2 -> 3.4.x + +fix: +- (rest) config: sendError -> main.sendError +- (socket) if " " at begin execption occurs +- (socket) error: undefined +- (rest) crash on /api/v1 +- (main) sendFile callback: add error condition +- (main) if file not exist - send error; sendFile: add stat, add setHeader +- (main) header was sended twice + +feature: +- (ind) f10: rm hidden +- (style) .cmd-button width: 8% -> 9% +- (dom) rest: add {top: true} +- (minify) rm setAllowed +- (config) add saving of config +- (reset) rm font-size, line-height +- (cloudcmd) rm config watch +- (config) port, ssl port: add title +- (config) rm api_url, server, ip, rest from gui +- (config) add autosize +- (config) rm border +- (minify) rm force flag +- (cloudocmd) rm minimize +- (cloudcmd) rm all.min.css +- (rest) add config +- (config) add change +- (config) add template-updating +- (config) rm checked +- (util) copyObj: rm copy +- (config) add +- (socket) JSON.stringify -> Util.stringifyJSON +- (socket) exec symbols: add "*" +- (socket) add "#" +- (socket) connect: add reconnect limit: 5 seconds +- (socket) reconnect_failed: mv from options to events +- (rest) rm proxy +- (rest) rm " " +- (rest) rm log lSize +- (socket) getExec: add lError condition +- (util) add addNewLine +- (socket) getSpawn: rm log +- (express) add +- (socket) lExecSymbols: add "&" +- (socket) getSpawn error: add retFalse +- (socket) add spawn +- (console) add Buffer +- (socket) listen: add stringifyJSON +- (socket) connected -> connected\n +- (console) rm addNewLine +- (rest) rm log error (would log later anyway) +- (server) add express logger (if exist) +- (server) add express +- (main) mrequire: error -> no +- (socket) connect: rm reconnect, reconnect delay +- (edit) showMessage: ".msg" -> "#view .msg" +- (edit) show: rm className +- (asyncCall) add any count of params +- (client) getSystemFile: rm !pGlobal +- (dom) Dialog: add confirm +- (dom) add Dialog +- (help) show: add cssSet, list-style-type +- (server) controller log: rm ":" +- (main) mrequire: add formatMsg +- (util) checkObj: add trace +- (cloudcmd) retExec -> retFunc +- (help) add margin: 25px +- (dom) addOneTime -> addOnce +- (server) change socket msg +- (cloudfunc) formatMsg: add empty name condition +- (socket) rm flashsocket +- (main) readFiles: add formatMsg +- (server) add query +- (cloudcmd) sendResponse: p -> p, null, true +- (cloudcmd) change logs: rm pathname, request, name; add method, data +- (util) log: add if lArg[0] + + 2013.10.17, v0.5.0 feature: @@ -16,7 +100,7 @@ feature: - (config) add online upadate: -- minify: v0.2.1 -> v0.2.2* +- minify: v0.2.1 -> v0.2.2- fix: - (util) retExec: if param was - use it @@ -145,288 +229,288 @@ inside: 2013.08.01, v0.3.0 -* Changed jquery cdn to one with https suport jquery.com -> google cdn. +- Changed jquery cdn to one with https suport jquery.com -> google cdn. -* Added Access-Control-Allow-Origin header. +- Added Access-Control-Allow-Origin header. -* Added functions in DOM module: createEvent +- Added functions in DOM module: createEvent (createKeyEvent, createClickEvent, createDblClickEvent), dispatch (dispatchKeyEvent, dispatchClickEvent, dispatchDblClickEvent) -* Changed object name CloudCommander -> CloudCmd +- Changed object name CloudCommander -> CloudCmd -* Moved loading functions to Loader object in DOM module. +- Moved loading functions to Loader object in DOM module. -* Added addtables script' +- Added addtables script' -* Fixed typo in README. +- Fixed typo in README. -* Fixed same background declartion a couple times. +- Fixed same background declartion a couple times. -* Changed the way of work with listeners (DOM.addListener to DOM.Events.add). +- Changed the way of work with listeners (DOM.addListener to DOM.Events.add). -* Added ability to add a couple events in Events.add. +- Added ability to add a couple events in Events.add. -* Moved jqeuryLoader and socketLoader to CMD object in DOM. +- Moved jqeuryLoader and socketLoader to CMD object in DOM. -* Fixed bug with deletting in menu js. +- Fixed bug with deletting in menu js. -* Removed function _editFileName from client.js. +- Removed function _editFileName from client.js. -* Removed linuxWatch function from main.js. +- Removed linuxWatch function from main.js. -* Added tryCatch to fs.watch in cloudcmd.js. +- Added tryCatch to fs.watch in cloudcmd.js. -* Set F3 to veiw. +- Set F3 to veiw. -* Renamed KeyBinding -> Key. +- Renamed KeyBinding -> Key. -* Renamed: set -> setBinded, unSet -> unsetBinded, get -> isBinded. +- Renamed: set -> setBinded, unSet -> unsetBinded, get -> isBinded. -* Functions maked private: ajaxload, changeLinks, createFileTable, +- Functions maked private: ajaxload, changeLinks, createFileTable, getJSONfromFileTable. -* Moved CloudCmd.KEY object data to prototype of CloudCmd.Key. +- Moved CloudCmd.KEY object data to prototype of CloudCmd.Key. -* Simpified plugins id's. +- Simpified plugins id's. -* Rewrited _codemirror and view modules with prototypes. +- Rewrited _codemirror and view modules with prototypes. -* Added hide method to view module. +- Added hide method to view module. -* Updated socket.io to v0.9.16. +- Updated socket.io to v0.9.16. -* Removed init property from view and edit. +- Removed init property from view and edit. -* FilePicker gets key from modules.json. +- FilePicker gets key from modules.json. -* Added ability to put callback to view. +- Added ability to put callback to view. -* Added help module. +- Added help module. -* Added ability to show help on F1. +- Added ability to show help on F1. -* Added ability to set attributes in Loader.anyload. +- Added ability to set attributes in Loader.anyload. -* Fixed upload function of filepicker. +- Fixed upload function of filepicker. -* fix(DOM) this promptNewFile -> Cmd.promptNewFile +- fix(DOM) this promptNewFile -> Cmd.promptNewFile -* feature(console) add jq-console +- feature(console) add jq-console -* fix(style) .name{width}: 37% -> 35% +- fix(style) .name{width}: 37% -> 35% -* feature(view) show(pData) -> show(pData, pCallBack) +- feature(view) show(pData) -> show(pData, pCallBack) -* doc(license) add +- doc(license) add -* doc(contribute) add commit message conventions +- doc(contribute) add commit message conventions -* fix(socket) log level: debug -> info +- fix(socket) log level: debug -> info -* feature(console) jquery-terminal -> jq-console +- feature(console) jquery-terminal -> jq-console -* fix(help) remove pre +- fix(help) remove pre -* feature(socket) add disconect +- feature(socket) add disconect -* feature(socket) add minification and gzip +- feature(socket) add minification and gzip -* feature(socket) if id in use - reconnect +- feature(socket) if id in use - reconnect -* chore(console) remove jquery-terminal +- chore(console) remove jquery-terminal -* feature(favicon) add +- feature(favicon) add -* fix(style) .mode width: 25% -> 23% +- fix(style) .mode width: 25% -> 23% -* feature(edit) codemirror -> ace +- feature(edit) codemirror -> ace -* feature(edit) add diff +- feature(edit) add diff -* chore(dom) jquery: v2.0.0 -> v2.0.3 +- chore(dom) jquery: v2.0.0 -> v2.0.3 -* feature(util) call log with any count of params +- feature(util) call log with any count of params -* feature(util) add logArray +- feature(util) add logArray -* feature(socket) add chdir on cd +- feature(socket) add chdir on cd -* feature(dom) add events.add array +- feature(dom) add events.add array -* feauture(client) add unload event +- feauture(client) add unload event -* feature(update) exec -> exec(cwd) +- feature(update) exec -> exec(cwd) -* feature(cloudcmd) add bin +- feature(cloudcmd) add bin -* feature(rest) add put patch +- feature(rest) add put patch -* feature(edit) save file only if it was changed +- feature(edit) save file only if it was changed -* fix(dom) rm array param from jsload +- fix(dom) rm array param from jsload -* feature(main) add to exports checkCallBackParams +- feature(main) add to exports checkCallBackParams -* feature(win) diskpart -> wmic +- feature(win) diskpart -> wmic -* fix(diff) rm, work bad with win line ending +- fix(diff) rm, work bad with win line ending -* fix(dom) this -> Cmd +- fix(dom) this -> Cmd -* fix(css) .cmd-button: "outline:0" +- fix(css) .cmd-button: "outline:0" -* feature(index) add "~ - console" button +- feature(index) add "~ - console" button -* chore(css) .cmd-button {width: 10% -> 8%} +- chore(css) .cmd-button {width: 10% -> 8%} -* feature(index) add "f9 - menu" button +- feature(index) add "f9 - menu" button -* feature(Events) dispatch: event -> event || eventName +- feature(Events) dispatch: event -> event || eventName -* feature(css) add media-query for .cmd-button +- feature(css) add media-query for .cmd-button -* fix(view) open on f3 cmd button click +- fix(view) open on f3 cmd button click -* fix(rest) save and create new file +- fix(rest) save and create new file -* chore(minify) v0.2.0 -> v0.2.1 +- chore(minify) v0.2.0 -> v0.2.1 2013.04.22, v0.2.0 -* Added alerting about errors. +- Added alerting about errors. -* Removed Listeners array for DOM. +- Removed Listeners array for DOM. -* Added ability create folders. +- Added ability create folders. -* Added filepicker. +- Added filepicker. -* Added ability to load files to cloud +- Added ability to load files to cloud and get them out to file system. -* Added SSL suport. +- Added SSL suport. -* jquery updated to v1.9.1. +- jquery updated to v1.9.1. -* Fixed bug with multiple click events on f3 and f4 buttons. +- Fixed bug with multiple click events on f3 and f4 buttons. -* Added ability to move files. +- Added ability to move files. -* Added ability to degradate to http from https. +- Added ability to degradate to http from https. -* Fixed bug of multiple call of sockets. +- Fixed bug of multiple call of sockets. -* If create directory command executed - loading spinner +- If create directory command executed - loading spinner would be on top. -* Refactored getShortSize. +- Refactored getShortSize. -* Added update of size on file changing in editor. +- Added update of size on file changing in editor. -* Removed cache control of fs resour. +- Removed cache control of fs resour. -* Added ability to copy files. +- Added ability to copy files. -* Fixed bug with saving json to localStorage, it's always +- Fixed bug with saving json to localStorage, it's always writed root directory. -* Moved out set current file from cloudfunc to client.js. +- Moved out set current file from cloudfunc to client.js. -* Changed the way file table building. From now templating used. +- Changed the way file table building. From now templating used. -* Changed sync reading of certs to async. +- Changed sync reading of certs to async. -* Updated dropbox to v0.9.2 and moved to packege.json +- Updated dropbox to v0.9.2 and moved to packege.json from storage folder. -* Updated socket.io to v0.9.14. +- Updated socket.io to v0.9.14. -* Fixed Util.time and Util.timeEnd +- Fixed Util.time and Util.timeEnd -* Added ability to select files with Insert key. +- Added ability to select files with Insert key. -* Added ability to delete selected files from DOM. +- Added ability to delete selected files from DOM. -* Added ability to recursivly get current folder size. +- Added ability to recursivly get current folder size. -* Added ability to get directory size, when space button +- Added ability to get directory size, when space button is pressed and current file is directory. -* Added ability to select all files on Ctrl + A +- Added ability to select all files on Ctrl + A -* Fixed the href generation of renamed file. +- Fixed the href generation of renamed file. -* Renamed promptNewFolder -> promptNewDir'. +- Renamed promptNewFolder -> promptNewDir'. -* Added function getSelectedNames. +- Added function getSelectedNames. -* Added ability to delete file when f8 key pressed. +- Added ability to delete file when f8 key pressed. -* Fixed bug with selectecting root directory with space. +- Fixed bug with selectecting root directory with space. -* Fixed bug with processing selected root directory. +- Fixed bug with processing selected root directory. -* Added ability to delete files. +- Added ability to delete files. -* Removed modules cache.js. +- Removed modules cache.js. -* Fixed bug with writing new file. +- Fixed bug with writing new file. -* Updated jquery to v2.0.0. +- Updated jquery to v2.0.0. -* Improved CloudFunc module. +- Improved CloudFunc module. -* Fixed selection style in opera. +- Fixed selection style in opera. -* Fixed header of api fs GET. +- Fixed header of api fs GET. -* Fixed bug with sending response on +- Fixed bug with sending response on query other then json on /fs url. -* Fixed bug with getting back to +- Fixed bug with getting back to directory where file was removed. 2013.03.01, v0.1.9 -* Changed the way of getting github application id +- Changed the way of getting github application id (now it's just from config, rest api removed). -* Added ability to upload files to GDrive. +- Added ability to upload files to GDrive. -* Added functions DOM.getCurrentFileContent(pCallBack [, pCurrentFile]) +- Added functions DOM.getCurrentFileContent(pCallBack [, pCurrentFile]) and Util.setTimeout(pFunction [, pCallBack, pTime]) -* Added functions in win.js for parsing diskpart output. +- Added functions in win.js for parsing diskpart output. -* Added function getCurrentDir to DOM module. +- Added function getCurrentDir to DOM module. -* Fixed bug with terminal load. +- Fixed bug with terminal load. -* From now api url on client readed from config.json. +- From now api url on client readed from config.json. -* If choosen upload to -> Gist, and file in json have +- If choosen upload to -> Gist, and file in json have not '.json' extension, it's added to the and of filename. -* Fixed bug in not fully functional browsers, +- Fixed bug in not fully functional browsers, jquery loaded after ie.js, should be before. -* Fixed bug with closing terminal and opening viewer: +- Fixed bug with closing terminal and opening viewer: inside event function varible called event do not exist (everithing ok on webkit). -* Added ability to upload files to dropbox. +- Added ability to upload files to dropbox. -* Added ability to authorize on github thru new window, +- Added ability to authorize on github thru new window, changed redirecting url to /auth and added rout function to cloudcmd.js -* DropBox, GDrive and GitHub modules now look the same. +- DropBox, GDrive and GitHub modules now look the same. -* Fixed bug with pressing Esc when menu showed. +- Fixed bug with pressing Esc when menu showed. We could not to now, when key was pressed becaouse of stopPropogation function in jquery.contextMenu module. Commented stopPropogration. @@ -439,577 +523,577 @@ keyStop: function(e, opt) { //e.stopPropagation(); } ``` -* Updated socket.io to v0.9.13. +- Updated socket.io to v0.9.13. -* Updated jquery-terminal to v0.4.22. +- Updated jquery-terminal to v0.4.22. -* Refactore viewer module. +- Refactore viewer module. -* Removed loading spinner by commenting jquery.fancybox.css block +- Removed loading spinner by commenting jquery.fancybox.css block #fancybox-loading div { width: 44px; height: 44px; background: url('fancybox_loading.gif') center center no-repeat; } -* Updated CodeMirror to v2.37.01. +- Updated CodeMirror to v2.37.01. -* Updated jquery to v.1.8.3. +- Updated jquery to v.1.8.3. -* Improved optimizing size of menu.js from 2539 to 2444. +- Improved optimizing size of menu.js from 2539 to 2444. -* Fixed bug with height of terminal. +- Fixed bug with height of terminal. -* Added ability to read gdrive key from config. +- Added ability to read gdrive key from config. -* Fixed bug with setting curent cursor when +- Fixed bug with setting curent cursor when clicked on menu item. -* Updated dropbox library to v.0.8.1. +- Updated dropbox library to v.0.8.1. -* Added ability to authorize on dropbox thru popup. +- Added ability to authorize on dropbox thru popup. -* Added ability to authorize in vk.com. +- Added ability to authorize in vk.com. -* Added vk to menu. +- Added vk to menu. -* Updated funcyBox to v2.1.4. +- Updated funcyBox to v2.1.4. -* Updated jquery to v1.9.0. +- Updated jquery to v1.9.0. -* Improved modules.json format and parsing. +- Improved modules.json format and parsing. -* Added ability to read storage modules information from menu module. +- Added ability to read storage modules information from menu module. -* Added easy template renderrer system Util.render. +- Added easy template renderrer system Util.render. -* Added functions DOM.parseJSON and DOM.stringifyJSON +- Added functions DOM.parseJSON and DOM.stringifyJSON -* Improved modules.json. +- Improved modules.json. -* Added migrate plugin for jquery. +- Added migrate plugin for jquery. -* Removed getting data from Minify cache. +- Removed getting data from Minify cache. -* Moved jsons to json folder. +- Moved jsons to json folder. -* Fixed bug with working links in path panel and +- Fixed bug with working links in path panel and with clicks on files. -* Changed icons font from octicons to foundicons +- Changed icons font from octicons to foundicons -* Changed icons font from foundicons to fonteollo +- Changed icons font from foundicons to fonteollo -* Removed Octicons font. +- Removed Octicons font. -* Removed allowed from cache property in config. +- Removed allowed from cache property in config. -* Added ability to hide "Upload To" menu item if +- Added ability to hide "Upload To" menu item if no storage modules setted up in modules.json. -* From now any file minifying only if last modified +- From now any file minifying only if last modified time was changed. -* Removed ability to cache files in memory. +- Removed ability to cache files in memory. -* Moved extensions from main.js to json/ext.json. +- Moved extensions from main.js to json/ext.json. -* Commander functions moved out to commander.js from server.js +- Commander functions moved out to commander.js from server.js -* Fixed bug with old browsers support. +- Fixed bug with old browsers support. -* Fixed bug with scrolling in opera and firefox. +- Fixed bug with scrolling in opera and firefox. -* Fixed bug with (fake) deleting file. +- Fixed bug with (fake) deleting file. -* Added ability show context menu on right click +- Added ability show context menu on right click while menu is showing now. -* Added ability to remove /fs/no-js when go up to root +- Added ability to remove /fs/no-js when go up to root directory. -* Removed reflows maded by js. +- Removed reflows maded by js. -* Fixed bug with setting current file +- Fixed bug with setting current file after refresh and refreshing dir content. -* Removed part of url thet says that js is disabled, from +- Removed part of url thet says that js is disabled, from now json data of file structure would be getted from click event with ?json flag. "no-js" part of url would not be supported anymore. -* Added ability to add ?json flag only if we work with dir. +- Added ability to add ?json flag only if we work with dir. -* Added ability not to change url if we have no rights +- Added ability not to change url if we have no rights for reading. -* Fixed bug with pressing enter on file. +- Fixed bug with pressing enter on file. -* Updated jquery jQuery-contextMenu to v1.6.5. +- Updated jquery jQuery-contextMenu to v1.6.5. -* Fixed bug with getting showed menu in firefox. +- Fixed bug with getting showed menu in firefox. -* Added temporary redirection for old no-js urls. +- Added temporary redirection for old no-js urls. -* Changed the way clickProcessing of menu works, +- Changed the way clickProcessing of menu works, for now it's much simplier. -* Fixed dblclick selection in firefox. +- Fixed dblclick selection in firefox. -* Fixed the first show of menu in firefox. +- Fixed the first show of menu in firefox. -* Added ability to change configs without restart +- Added ability to change configs without restart (works for js minification only). -* Added ability to disable browser cache from config.json. +- Added ability to disable browser cache from config.json. -* Totaly refactored and leave in commander.js just +- Totaly refactored and leave in commander.js just generation of json of directory listing. -* Added ability to upload files. +- Added ability to upload files. -* Added ability save files on Ctrl+S in CodeMirror. +- Added ability save files on Ctrl+S in CodeMirror. -* Added ability to delete files. +- Added ability to delete files. -* Added rename menu item. +- Added rename menu item. -* Added to html templating. +- Added to html templating. -* Added ability to rename files. +- Added ability to rename files. -* Added RESTfull object to DOM for easy work with +- Added RESTful object to DOM for easy work with CloudCmd REST API. -* Added help screen (on F1 after viewer loads). +- Added help screen (on F1 after viewer loads). 2012.12.12, v0.1.8 -* Added ability to shutdown Cloud Commander +- Added ability to shutdown Cloud Commander thru terminal command: "cloudcmd exit" -* Fixed bug with showing terminal and viewer +- Fixed bug with showing terminal and viewer at the same time. -* Fixed bug with appcache config. Windows reads +- Fixed bug with appcache config. Windows reads file not just like Linux. -* Added ability to update thru git. +- Added ability to update thru git. -* Added ability to change charset on terminal only if +- Added ability to change charset on terminal only if it's build in command on win32. -* Fixed bug with testing mode. If was same arguments, +- Fixed bug with testing mode. If was same arguments, Cloud Commander works in testing mode and server do not started. -* Added more demo mirrors to readme (appfog, cloudfoundry). +- Added more demo mirrors to readme (appfog, cloudfoundry). -* Removed resize event from jquery-terminal. +- Removed resize event from jquery-terminal. -* Fixed bug with error code of program execution in terminal. +- Fixed bug with error code of program execution in terminal. -* Fixed bug with menu itmes edit and view. +- Fixed bug with menu itmes edit and view. -* Added function jsLoadOnLoad, thet loads js files +- Added function jsLoadOnLoad, thet loads js files one-by-one, and then calls callback if needed. -* Added function anyloadOnLoad thet loads any files or +- Added function anyloadOnLoad thet loads any files or elements one-by-one. -* Added function loadModule thet make it easier to connect +- Added function loadModule thet make it easier to connect new module. -* Fixed bug with context menu hiding (on Esc). +- Fixed bug with context menu hiding (on Esc). Keys was unbinded. -* Added ability to disable web sockets. +- Added ability to disable web sockets. -* Moved cloudRequire to srvfunc.js file. +- Moved cloudRequire to srvfunc.js file. -* Fixed bug with directory pathes detection +- Fixed bug with directory pathes detection (used document.location.href, now using document.location.origin) -* Fixed bug with keybinding in FireFox +- Fixed bug with keybinding in FireFox (removed KeyBinding call on window load). -* Fixed bug with getting current url in Firefox. +- Fixed bug with getting current url in Firefox. -* Util cleaned up (addClass and removeClass +- Util cleaned up (addClass and removeClass moved to ie.js). -* Index processing function moved out from +- Index processing function moved out from server.js to cloudcmd.js. -* Added ability of authorithation in GitHub. +- Added ability of authorithation in GitHub. -* Rewrited sizing of names if they are to +- Rewrited sizing of names if they are to long thru css, from JavaScript. -* Fixed bug with application cahe forming on windows +- Fixed bug with application cahe forming on windows and linux. -* Removed unneeded windows check. +- Removed unneeded windows check. -* Fixed bug with downloading directory +- Fixed bug with downloading directory listing in json from menu. -* Changed default port to 80. +- Changed default port to 80. -* Util object moved from client.js to modules +- Util object moved from client.js to modules dom.js and util.js. -* Fixed bug with navigation thru path panel. +- Fixed bug with navigation thru path panel. -* Added functions DOM.addKeyListener and Util.loadOnLoad +- Added functions DOM.addKeyListener and Util.loadOnLoad -* Added buttons panel. +- Added buttons panel. -* Fixed bug with config file, when no need to minification. +- Fixed bug with config file, when no need to minification. -* Added ability to hide keys panel thru config option. +- Added ability to hide keys panel thru config option. -* CodeMirror upgraded to version 2.35.0. +- CodeMirror upgraded to version 2.35.0. -* Fixed bug with keys panel and fm bottom margin, +- Fixed bug with keys panel and fm bottom margin, when CodeMirror is open on the right panel. -* Fixed bug with positioning of CodeMirror on the +- Fixed bug with positioning of CodeMirror on the right panel. -* Function generateHeaders moved to main module. +- Function generateHeaders moved to main module. -* Setted up auth on GitHub thru rest. +- Setted up auth on GitHub thru rest. -* Fixed bug with context menu. Now it disabled +- Fixed bug with context menu. Now it disabled before load menu module to. -* Throw out jquery from github module, moved Cache +- Throw out jquery from github module, moved Cache object from client to DOM module, refactored Cache object and added polyfill. -* Added ability to connect github development id, +- Added ability to connect github development id, to Cloud Commander instance working in any host, for this all the needed to be done is: set enveronment varibles "oauth_client_id" and "oauth_client_secret" values from github profile. -* Changed funcyBox version to 2.1.3. +- Changed funcyBox version to 2.1.3. -* Improved reading file with streams. +- Improved reading file with streams. -* Improved download speed of js and css files by +- Improved download speed of js and css files by adding DOM.anyLoadInParallel function that is loading files in parallel and then execute callback function. -* Added ability to load a couple scripts after one main, +- Added ability to load a couple scripts after one main, in any position in anyLoadOnLoad function. -* Added chainable to Cache object in DOM. +- Added chainable to Cache object in DOM. -* Changed default ip to null so IP would be geted from +- Changed default ip to null so IP would be geted from config.json only if it setted up. -* Fixed bug with starting node from other then projects dir. +- Fixed bug with starting node from other then projects dir. -* Fixed bug with slashes on win32. +- Fixed bug with slashes on win32. -* Fixed bug with editor close, when started from menu. +- Fixed bug with editor close, when started from menu. -* Added url change on folder changing. +- Added url change on folder changing. -* Fixed bug with traveling in directories with +- Fixed bug with traveling in directories with Javascript dissabled. -* client.js and server.js moved to lib directory. +- client.js and server.js moved to lib directory. -* Improved work with browsers history api. +- Improved work with browsers history api. -* Fixed bug with setting path of index.html. +- Fixed bug with setting path of index.html. -* Added dropbox module. +- Added dropbox module. -* Renamed config options ouath_client_id and +- Renamed config options ouath_client_id and oauth_client_secre to github_id and github_secret. Added dropbox_id option. -* Fixed bug in github show function. +- Fixed bug in github show function. -* Added ability to call dropbox chooser on + . +- Added ability to call dropbox chooser on + . -* Added ability to read dropbox key from config. +- Added ability to read dropbox key from config. -* Fixed bug with menu load, when dir other then root. +- Fixed bug with menu load, when dir other then root. -* Added confirmation before (not real) deleting file. +- Added confirmation before (not real) deleting file. -* Added ability to upload file to gists on github thru menu. +- Added ability to upload file to gists on github thru menu. -* Added getCurrentPath function to Util module. +- Added getCurrentPath function to Util module. -* GitHub and DropBox secret's moved out from +- GitHub and DropBox secret's moved out from config.json to env. -* Fixed bug with auth in github. +- Fixed bug with auth in github. -* Fixed bug with opening empty files in CodeMiror. +- Fixed bug with opening empty files in CodeMiror. Editor window could not be cloused. -* Added windows support on terminal command: "cloudcmd exit". +- Added windows support on terminal command: "cloudcmd exit". -* Fixed IP on windows. +- Fixed IP on windows. -* Added ability to delete files (not for real for now) +- Added ability to delete files (not for real for now) thru keys panel (F8). -* Changed "Upload" menu item to "Upload to". +- Changed "Upload" menu item to "Upload to". -* Fixed bug with minified styles. +- Fixed bug with minified styles. -* If git not installed do not show error. +- If git not installed do not show error. Just propose install git and clone from github repo. -* Fixed bug with client.js minifying. +- Fixed bug with client.js minifying. -* Fixed bug with appcache. +- Fixed bug with appcache. 2012.10.01, v0.1.7 -* Changed name of menu files, fixed npm and jitsu +- Changed name of menu files, fixed npm and jitsu problem with menu showing. -* Fixed bug with empty directorys. If directory +- Fixed bug with empty directorys. If directory was empty, we could not go in. -* Removed packed versions of files, uglifing +- Removed packed versions of files, uglifing would be doing on-a-fly -* Added ability to use ajax without jquery. +- Added ability to use ajax without jquery. -* From now jquery not necessary for Cloud Commander +- From now jquery not necessary for Cloud Commander work, (so start load get faster), but it could be loaded any time by any extension. -* Fixed bug with getByClass IE version. +- Fixed bug with getByClass IE version. -* Fixed bug with keyboard not responding when go deeper +- Fixed bug with keyboard not responding when go deeper in file tree thru mouse double click. -* Removed property keyBinded. From not it's private +- Removed property keyBinded. From not it's private member of KeyBinding class. -* Fixed scrolling bug on non-webkit based browsers. +- Fixed scrolling bug on non-webkit based browsers. Function scrollIntoViewIfNeeded was polyfilled. -* Added classic borders to panels. +- Added classic borders to panels. -* Added ability to download files thru drag'n'drop. +- Added ability to download files thru drag'n'drop. -* Fixed bug with setting current file when mouse down. +- Fixed bug with setting current file when mouse down. -* Improved borders over CodeMirror and panels thru css. +- Improved borders over CodeMirror and panels thru css. -* Added ability to watch is file changed wile server is +- Added ability to watch is file changed wile server is running -* Moved calling api scrollIntoViewIfNeeded to setCurrentFile. +- Moved calling api scrollIntoViewIfNeeded to setCurrentFile. -* Added module is-file-changed. +- Added module is-file-changed. -* Added suport of AppCache. So CloudCommander can work totaly +- Added suport of AppCache. So CloudCommander can work totaly in offline mode (if connection suddenly lost, all visited directories would be cached). -* fixed bug with keyboard not responding when click on file. +- fixed bug with keyboard not responding when click on file. -* Server.js separated to two files: cloudcmd.js and server.js. +- Server.js separated to two files: cloudcmd.js and server.js. Start file is - cloudcmd.js -* Refactored and fixed old bugs in function generateHeaders (server.js). +- Refactored and fixed old bugs in function generateHeaders (server.js). -* Added ability to remove files (on the surface, not for real). +- Added ability to remove files (on the surface, not for real). -* From now right panel would be always shown no matter js enabled or +- From now right panel would be always shown no matter js enabled or disabled in browsers. -* Added plagin terminal ( ` button under TAB). +- Added plagin terminal ( ` button under TAB). -* Added ability to execute commands on server thru terminal. +- Added ability to execute commands on server thru terminal. -* Added appcache paramter to config.json +- Added appcache paramter to config.json -* Added ability convert charset from win to unicode on win32. +- Added ability convert charset from win to unicode on win32. -* Added ability to freeze terminal screen on connection lost +- Added ability to freeze terminal screen on connection lost -* Added serialisation to socket connection. +- Added serialisation to socket connection. -* Added ability to work with terminal to any number of clients +- Added ability to work with terminal to any number of clients -* Fixed bug with jquery load in viewer. Jquery could be loaded to late. +- Fixed bug with jquery load in viewer. Jquery could be loaded to late. -* Changed version of FuncyBox to 2.1.0. +- Changed version of FuncyBox to 2.1.0. -* Added Ace editor. +- Added Ace editor. -* Little bit changed styles. Fixed margins in responsive view. +- Little bit changed styles. Fixed margins in responsive view. -* Fixed bug with minifying, if file do not minimized so allowed set to none. +- Fixed bug with minifying, if file do not minimized so allowed set to none. -* Added fix of 866 charset. +- Added fix of 866 charset. 2012.08.24, v0.1.6 -* From now jsload, cssload and anyload suport arrays. +- From now jsload, cssload and anyload suport arrays. -* Added ability to move scrollbar, when Home and +- Added ability to move scrollbar, when Home and End buttons pressed. -* Added ability to move with Page Up and Page Down +- Added ability to move with Page Up and Page Down buttons. -* Added moving scrolling by cursor ability. +- Added moving scrolling by cursor ability. -* Fixed bug with go to parent directory: from now, +- Fixed bug with go to parent directory: from now, if parent directory not in view area, page will scroll to needed place. -* Fixed bug with tab key pressed. +- Fixed bug with tab key pressed. -* Fixed bug: files now clickable to. +- Fixed bug: files now clickable to. -* Fixed bug with double click on files. +- Fixed bug with double click on files. -* Fixed bug with double click on images. +- Fixed bug with double click on images. -* Fixed bug with Array.isArray and getElementsByClassName in IE. +- Fixed bug with Array.isArray and getElementsByClassName in IE. -* Fixed bug with document.head in IE. +- Fixed bug with document.head in IE. -* JQuery 1.7.2 changed to 1.8.0 +- JQuery 1.7.2 changed to 1.8.0 -* Added support of mibile browsers and touch events. +- Added support of mibile browsers and touch events. -* Fixed bug with ignoring all browser defined keys. +- Fixed bug with ignoring all browser defined keys. -* Moved unSetCurrentfile to setCurrent file. +- Moved unSetCurrentfile to setCurrent file. All the time one of files must be current, so wen we setting up some file current, file that was previously current must be unset automatically. -* Added context menu on shift + F10. +- Added context menu on shift + F10. -* A little bit beautified css. +- A little bit beautified css. -* Added function getRefreshButton. +- Added function getRefreshButton. -* Fixed bug with refreshing directory, from now current file would not be seeted up to first, after refresh. +- Fixed bug with refreshing directory, from now current file would not be seeted up to first, after refresh. -* Added ability to view any file. +- Added ability to view any file. -* Moved error message a little bit lower. +- Moved error message a little bit lower. -* Added ability to download files. +- Added ability to download files. 2012.08.06, v0.1.5 -* Added tab support. +- Added tab support. -* Fixed bug with Path links. +- Fixed bug with Path links. -* From now CodeMirror js files loads, when f4 key pressed. +- From now CodeMirror js files loads, when f4 key pressed. -* Fixed bug with showing CodeMirror after first show. +- Fixed bug with showing CodeMirror after first show. -* Added ability to read files in CodeMirror. +- Added ability to read files in CodeMirror. -* Added ability rename files. +- Added ability rename files. -* Fixed bug with CodeMirror vertical scroll bar. +- Fixed bug with CodeMirror vertical scroll bar. -* Added loading image when file going to be edited. +- Added loading image when file going to be edited. -* All sync functions changed to async equivalents. +- All sync functions changed to async equivalents. -* On f4 key pressed when current-file is folder +- On f4 key pressed when current-file is folder CodeMirror opens json data of folder. -* Fixed bug with response when we have no rihgts +- Fixed bug with response when we have no rihgts read dir server sends 404 response for now, not 200 ok. -* Fixed bug with forming error of loading dir. +- Fixed bug with forming error of loading dir. Was : "not found". Now : "Error: EACCES, readdir '/root'" -* Fixed bug with showing loading spinner, when f4 key +- Fixed bug with showing loading spinner, when f4 key pressed couple times and CodeMirror not loaded fully. -* Setted readOnly mode, when directory opened in CodeMirror. +- Setted readOnly mode, when directory opened in CodeMirror. -* Added api for getting curent file, getting active +- Added api for getting curent file, getting active and passive panels and show/hide any of panels. 2012.07.27, v0.1.4 -* Added local version of Droids font for offline mode +- Added local version of Droids font for offline mode -* Fixed bug with positioning of cursor when came back +- Fixed bug with positioning of cursor when came back from folder whith long name. -* Fixed bug with setting up current file, if a couple of +- Fixed bug with setting up current file, if a couple of files was with the same name on 16-chars, after going up on folders, current file would be last. -* Fixed bug with links and titles with spaces in Path of +- Fixed bug with links and titles with spaces in Path of current directory. -* Added ability to send 404 response if file not found. +- Added ability to send 404 response if file not found. -* Fixed bug which occurs when error reading directory happens. +- Fixed bug which occurs when error reading directory happens. -* Fixed bug: ErrorImage.title writes always for now, no matter +- Fixed bug: ErrorImage.title writes always for now, no matter why error occurred. -* Seted up default cursor on file attributes. +- Seted up default cursor on file attributes. -* _currentToParent refactored, no more cicles again. Changed +- _currentToParent refactored, no more cicles again. Changed the way of searching of current root directory, now it shoud be more faster, DOM, short, simple and logical. -* Added ability to view images on F3 key pressed. +- Added ability to view images on F3 key pressed. -* Added ability to work view images offline. +- Added ability to work view images offline. -* Added async flag to anyload function. +- Added async flag to anyload function. -* Added ability remove not loaded scripts from DOM. +- Added ability remove not loaded scripts from DOM. 2012.07.19, v0.1.3 -* Fixed bug with nodester (jitsu env.HOME make him go done). +- Fixed bug with nodester (jitsu env.HOME make him go done). -* Fixed bug: gzip do not working out, becouse accessible flag settet +- Fixed bug: gzip do not working out, becouse accessible flag settet up to _controller object. -* To every panel added scroll bars which is hiding if do not needed. +- To every panel added scroll bars which is hiding if do not needed. -* Fixed bug with setting up flag in config.json: do not minimize js. +- Fixed bug with setting up flag in config.json: do not minimize js. -* Fixed bugs many bugs in _anyload function (client.js). +- Fixed bugs many bugs in _anyload function (client.js). -* Added function cssLoad to client.js +- Added function cssLoad to client.js -* Added Client Side CodeMirror library with name Cloud Editor. +- Added Client Side CodeMirror library with name Cloud Editor. -* Fixed bug with building file table from json data, when we go around +- Fixed bug with building file table from json data, when we go around and come back to root dir. If name of a file or directory is more then 16 charactes it shows like 'VERY-LONG-NAME..', so becaouse of on first came we load page @@ -1018,41 +1102,41 @@ server. So if file to long we should take it's name from title parameter of tag, it's wasn't, so folder navigation not every time was possible. -* Fixed bug with undefined size on root directory of Cloud Commander. +- Fixed bug with undefined size on root directory of Cloud Commander. Now Cloud Commander writes size 0, if can't get size, and besides will setted b char: "0b". -* Added supporting of Russian language in directory names. +- Added supporting of Russian language in directory names. 2012.07.14, v0.1.2 -* Added suport of jitsu. +- Added suport of jitsu. -* Added module objects.js, Minify and Cache objects moved there. +- Added module objects.js, Minify and Cache objects moved there. -* Module Minify moved to node_modules dir +- Module Minify moved to node_modules dir -* Changed the minimize function calls accroding to Minify 0.1.2 changes. +- Changed the minimize function calls accroding to Minify 0.1.2 changes. 2012.07.11, v0.1.1 -* Added onerror parametr to anyload in Clinet Side, so now we can process situation when +- Added onerror parametr to anyload in Clinet Side, so now we can process situation when js-script(or something other) has not loaded. -* Added jquery file, so from now Cloud Commander can totaly work offline. +- Added jquery file, so from now Cloud Commander can totaly work offline. -* Added css-lint to travis ci. +- Added css-lint to travis ci. -* Fixed bug in object Minify, doit function, more processing function did not +- Fixed bug in object Minify, doit function, more processing function did not return final_code so changes was not saving, and clien side loaded keyBinding.js and cloudfunc.js full sized versions. -* Changed the way Minify post-processing js-files so, from now in Minify object +- Changed the way Minify post-processing js-files so, from now in Minify object post-processing functions passed like this {'client.js': function(){}} -* Added ability to read file data from Minify Cache, without writing to disk +- Added ability to read file data from Minify Cache, without writing to disk -* Changed the passing MoreProcessing agrument to jsScripts function Minify module, +- Changed the passing MoreProcessing agrument to jsScripts function Minify module, no it passes with a file name, and js file name writing only once. diff --git a/ChangeLog.rus.md b/ChangeLog.rus.md index 0952eb49..0f826bba 100644 --- a/ChangeLog.rus.md +++ b/ChangeLog.rus.md @@ -225,4 +225,4 @@ - Изминен принцип работы функции clickProcessing в меню, теперь он гораздо проще. - Произведен тотальный рефакторинг в файле commander.js, теперь там только генерация. структуры каталогов в формате json. -- добавлен обьект RESTfull в DOM модуль для упрощения работы с CloudCmd REST API. +- добавлен обьект RESTful в DOM модуль для упрощения работы с CloudCmd REST API. diff --git a/HELP.md b/HELP.md index 4a0a55a1..78f7be4d 100644 --- a/HELP.md +++ b/HELP.md @@ -1,19 +1,25 @@ -Cloud Commander v0.5.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] +Cloud Commander v0.6.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] =============== -###[Main][MainURL] [Blog][BlogURL] [Demo][DemoURL] +###[Main][MainURL] [Blog][BlogURL] Live(![IO][IO_LIVE_IMG] [IO][IOURL], ![JitSu][JitSu_LIVE_IMG] [JitSu][JitSuURL], ![Heroku][Heroku_LIVE_IMG] [Heroku][HerokuURL] ![RunKite][RunKite_LIVE_IMG] [RunKite][RunKiteURL]) [NPMIMGURL]: https://badge.fury.io/js/cloudcmd.png [BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master [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 -[NPMURL]: https://npmjs.org/package/cloudcmd +[NPMURL]: https://npmjs.org/package/cloudcmd "npm" [BuildStatusURL]: http://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" -[NPM_INFO_URL]: https://npmjs.org/package/cloudcmd "npm" [MainURL]: http://cloudcmd.io "Main" [BlogURL]: http://blog.cloudcmd.io "Blog" -[DemoURL]: http://io.cloudcmd.io "Demo" +[IOURL]: http://io.cloudcmd.io "IO" +[JitSuURL]: http://cloudcmd.jit.su "JitSu" +[HerokuURL]: http://cloudcmd.herokuapp.com/ "Heroku" +[RunKiteURL]: http://cloudcmd.apps.runkite.com/ "RunKite" +[IO_LIVE_IMG]: http://status-ok.cloudcmd.io/host/io.cloudcmd.io "IO" +[JitSu_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.jit.su "JitSu" +[HEROKU_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.herokuapp.com "Heroku" +[RunKite_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.apps.runkite.com/ "RunKite" **Cloud Commander** - cloud file manager with console and editor. @@ -32,10 +38,11 @@ Benefits Install --------------- -[![NPM_INFO][NPM_INFO_IMG]][NPM_INFO_URL] +[![NPM_INFO][NPM_INFO_IMG]][NPMURL] Installing **Cloud Commander** is very simple. All you need is + - 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: @@ -46,6 +53,7 @@ and unpack or just clone repository from github: node cloudcmd ``` or install in npm: + ``` npm i cloudcmd -g cloudcmd @@ -63,6 +71,7 @@ Hot keys - **F7** - new dir - **F8, Delete** - remove current file - **F9** - menu +- **F10** - config - **Ctrl + r** - reload dir content - **Ctrl + d** - clear local cache (wich contains dir contents) - **Alt + q** - disable key bindings @@ -82,7 +91,7 @@ Hot keys Edit --------------- [Demo](http://io.cloudcmd.io/fs/etc#/edit/passwd "Edit") -![Edit](/img/screenshot/edit.png "Edit") +![Edit](/img/screen/edit.png "Edit") ###Hot keys - **F4** - open @@ -94,16 +103,25 @@ For more details see [Ace keyboard shortcuts](https://github.com/ajaxorg/ace/wik Console --------------- [Demo](http://io.cloudcmd.io#/console "Console") -![Console](/img/screenshot/console.png "Console") +![Console](/img/screen/console.png "Console") ###Hot keys - **~** - open - **Esc** - close +Config +--------------- +[Demo](http://io.cloudcmd.io#/config "Config") +![Console](/img/screen/config.png "Config") + +###Hot keys +- **F10** - open +- **Esc** - close + Menu --------------- [Demo](http://io.cloudcmd.io#/menu "Menu") -![Menu](/img/screenshot/menu.png "Menu") +![Menu](/img/screen/menu.png "Menu") Right mouse click button shows context menu with items: - View - Edit @@ -200,7 +218,7 @@ in your list they could differ). ``` ###nginx -Get [nginx](http://nginx.org/ "nginx"). On linux it could be done like that +Get [nginx](http://nginx.org/ "nginx"). On linux it could be done this way: ```sh sudo apt-get install nginx #for ubuntu and debian @@ -324,6 +342,8 @@ so to get it you should type a couple more commands: Version history --------------- + +- *2013.11.08*, **[v0.6.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.6.0.zip)** - *2013.10.17*, **[v0.5.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.5.0.zip)** - *2013.09.27*, **[v0.4.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.4.0.zip)** - *2013.08.01*, **[v0.3.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.3.0.zip)** @@ -337,7 +357,7 @@ Version history - *2012.07.19*, **[v0.1.3](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.3.zip)** - *2012.07.14*, **[v0.1.2](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.2.zip)** - *2012.07.11*, **[v0.1.1](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.1.zip)** -- *2012.00.00*, **[v0.1.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.0.zip)** +- *2012.07.09*, **[v0.1.0](//github.com/coderaiser/cloudcmd-archive/raw/master/cloudcmd-v0.1.0.zip)** License --------------- @@ -345,5 +365,8 @@ MIT [license](LICENSE "license"). Special Thanks --------------- -- [Polietilena](http://polietilena.github.io/ "Polietilena") for [logo](img/logo/cloudcmd.png "logo") and [favicon](img/favicon/favicon.png "favicon"). -- [Elec-ua](https://github.com/elec-ua) for [ru](http://ru.cloudcmd.io "Cloud Commander in Russian") and [ua](http://ua.cloudcmd.io "Cloud Commander in Ukrainian") translations. + +- [Polietilena](http://polietilena.github.io/ "Polietilena") for [logo](img/logo/cloudcmd.png "logo") and [favicon](img/favicon/favicon.png "favicon"); +- [Elec-ua](https://github.com/elec-ua) + - [ru](http://ru.cloudcmd.io "Cloud Commander in Russian") and [ua](http://ua.cloudcmd.io "Cloud Commander in Ukrainian") translations; + - config [template](html/config.html) and [style](css/config.css); diff --git a/Procfile b/Procfile new file mode 100644 index 00000000..e24c4096 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node cloudcmd.js \ No newline at end of file diff --git a/README.md b/README.md index e115f3e6..bdddd2f4 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,25 @@ -Cloud Commander v0.5.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] +Cloud Commander v0.6.0 [![NPM version][NPMIMGURL]][NPMURL] [![Dependency Status][DependencyStatusIMGURL]][DependencyStatusURL] [![Build Status][BuildStatusIMGURL]][BuildStatusURL] =============== -###[Main][MainURL] [Blog][BlogURL] [Demo][DemoURL] +###[Main][MainURL] [Blog][BlogURL] Live(![IO][IO_LIVE_IMG] [IO][IOURL], ![JitSu][JitSu_LIVE_IMG] [JitSu][JitSuURL], ![Heroku][Heroku_LIVE_IMG] [Heroku][HerokuURL] ![RunKite][RunKite_LIVE_IMG] [RunKite][RunKiteURL]) [NPMIMGURL]: https://badge.fury.io/js/cloudcmd.png [BuildStatusIMGURL]: https://secure.travis-ci.org/coderaiser/cloudcmd.png?branch=master [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 -[NPMURL]: https://npmjs.org/package/cloudcmd +[NPMURL]: https://npmjs.org/package/cloudcmd "npm" [BuildStatusURL]: http://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" -[NPM_INFO_URL]: https://npmjs.org/package/cloudcmd "npm" [MainURL]: http://cloudcmd.io "Main" [BlogURL]: http://blog.cloudcmd.io "Blog" -[DemoURL]: http://io.cloudcmd.io "Demo" +[IOURL]: http://io.cloudcmd.io "IO" +[JitSuURL]: http://cloudcmd.jit.su "JitSu" +[HerokuURL]: http://cloudcmd.herokuapp.com/ "Heroku" +[RunKiteURL]: http://cloudcmd.apps.runkite.com/ "RunKite" +[IO_LIVE_IMG]: http://status-ok.cloudcmd.io/host/io.cloudcmd.io "IO" +[JitSu_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.jit.su "JitSu" +[HEROKU_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.herokuapp.com "Heroku" +[RunKite_LIVE_IMG]: http://status-ok.cloudcmd.io/host/cloudcmd.apps.runkite.com/ "RunKite" **Cloud Commander** - cloud file manager with console and editor. diff --git a/cloudcmd.js b/cloudcmd.js index 3007fec2..2bebe41e 100644 --- a/cloudcmd.js +++ b/cloudcmd.js @@ -1,4 +1,4 @@ -(function(){ +(function() { 'use strict'; var DIR = __dirname + '/', @@ -49,18 +49,6 @@ lData = pData.data, lAdditional = pData.additional; - /* - * если выбрана опция минимизировать скрипты - * меняем в index.html обычные css на - * минифицированый - */ - if (Minify.allowed) { - lPath = '/' + Util.removeStr(Minify.MinFolder, DIR); - lReplace = ''; - lData = Util.removeStr(lData, lReplace) - .replace('/css/style.css', lPath + 'all.min.css'); - } - if (!Config.appcache) lData = Util.removeStr(lData, [ /* min */ @@ -86,7 +74,7 @@ /** * init and process of appcache if it allowed in config */ - function appCacheProcessing(){ + 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', @@ -96,54 +84,19 @@ lFiles[0][lFONT_REMOTE] = lFONT_LOCAL; lFiles[1][lJQUERY_REMOTE] = lJQUERY_LOCAL; - if (Config.minify) - lFiles.push('node_modules/minify/min/all.min.css'); - AppCache.addFiles(lFiles); AppCache.createManifest(); } - /** - * Функция минимизирует css/js/html - * если установлены параметры минимизации - */ - function minimize(pAllowed){ - var lOptimizeParams = [], - lStyles = [{}, {}], - lStyleCSS = DIR + 'css/style.css', - lResetCSS = DIR + 'css/reset.css', - - lCSSOptions = { - img : true, - merge : true - }; - - if (pAllowed) { - lOptimizeParams.push(LIBDIR + 'client.js'); - lOptimizeParams.push(INDEX); - - lStyles[0][lStyleCSS] = lCSSOptions; - lStyles[1][lResetCSS] = lCSSOptions; - - lOptimizeParams.push(lStyles[0]); - lOptimizeParams.push(lStyles[1]); - } - - if (lOptimizeParams.length) - Minify.optimize(lOptimizeParams, { - force: true - }); - } - /** * rest interface * @pParams pConnectionData {request, responce} */ - function rest(pConnectionData){ + function rest(pConnectionData) { return Util.exec(main.rest, pConnectionData); } - function init(){ + function init() { var lServerDir, lArg, lParams, lFiles; if (update) @@ -161,94 +114,72 @@ process.chdir(lServerDir); } - Util.log('server dir: ' + lServerDir); - Util.log('reading configuration file config.json...'); + Util.log('server dir: ' + lServerDir); - if (Config) { - Util.log('config.json readed'); - - /* 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]; - - if ( lArg === 'test' || lArg === 'test\r') { - Util.log(process.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(); - } - - if (Config.server) - Util.tryCatchLog(function(){ - fs.watch(CONFIG_PATH, function(){ - /* every catch up - calling twice */ - setTimeout(function() { - readConfig(); - }, 1000); - }); - }); - - lParams = { - appcache : appCacheProcessing, - minimize : minimize, - rest : rest, - route : route - }, - - lFiles = [FILE_TMPL, PATH_TMPL]; - - if (Config.ssl) - lFiles.push(CA, KEY, CERT); - - main.readFiles(lFiles, function(pErrors, pFiles){ - if (pErrors) - Util.log(pErrors); - else { - FileTemplate = pFiles[FILE_TMPL].toString(); - PathTemplate = pFiles[PATH_TMPL].toString(); - - if (Config.ssl) - lParams.ssl = { - ca : pFiles[CA], - key : pFiles[KEY], - cert : pFiles[CERT] - }; - - server.start(lParams); - } - }); + /* 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]; + + if ( lArg === 'test' || lArg === 'test\r') { + Util.log(process.argv); + Config.server = false; } - else - Util.log('read error: config.json'); + + 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 = { + appcache : appCacheProcessing, + rest : rest, + route : route + }, + + lFiles = [FILE_TMPL, PATH_TMPL]; + + if (Config.ssl) + lFiles.push(CA, KEY, CERT); + + main.readFiles(lFiles, function(pErrors, pFiles) { + if (pErrors) + Util.log(pErrors); + else { + FileTemplate = pFiles[FILE_TMPL].toString(); + PathTemplate = pFiles[PATH_TMPL].toString(); + + if (Config.ssl) + lParams.ssl = { + ca : pFiles[CA], + key : pFiles[KEY], + cert : pFiles[CERT] + }; + + server.start(lParams); + } + }); } - function readConfig(pCallBack){ - fs.readFile(CONFIG_PATH, function(pError, pData){ - if (!pError){ - Util.log('config: readed'); + function readConfig(pCallBack) { + fs.readFile(CONFIG_PATH, function(pError, pData) { + var msg, status, str, readed; + + if (pError) + status = 'error'; + else { + status = 'ok'; + str = pData.toString(), + readed = Util.parseJSON(str); - var lStr = pData.toString(), - lReadedConf = Util.parseJSON(lStr); - - if (!Config.minify) - main.config = Config = lReadedConf; - - Util.tryCatchLog(function(){ - Config.minify = lReadedConf.minify; - Config.cache = lReadedConf.cache; - - Minify.setAllowed(Config.minify); - }); + main.config = Config = readed; } - else - Util.log(pError); + + msg = CloudFunc.formatMsg('read', 'config', status); + Util.log(msg); Util.exec(pCallBack); }); @@ -257,13 +188,13 @@ /** * routing of server queries */ - function route(pParams){ + function route(pParams) { var lRet = main.checkParams(pParams); - if (lRet){ + if (lRet) { var p = pParams; - if ( Util.strCmp(p.name, ['/auth', '/auth/github']) ){ + if ( Util.strCmp(p.name, ['/auth', '/auth/github']) ) { Util.log('* Routing' + '-> ' + p.name); @@ -280,14 +211,14 @@ return lRet; } - function sendCommanderContent(pParams){ + function sendCommanderContent(pParams) { var p, lRet = main.checkParams(pParams); - if (lRet){ + if (lRet) { p = pParams; p.name = Util.removeStrOneTime(p.name, CloudFunc.FS) || main.SLASH; - fs.stat(p.name, function(pError, pStat){ + fs.stat(p.name, function(pError, pStat) { if (!pError) if ( pStat.isDirectory() ) processCommanderContent(pParams); @@ -301,22 +232,22 @@ return lRet; } - function processCommanderContent(pParams){ + function processCommanderContent(pParams) { var lRet = main.checkParams(pParams); - if (lRet){ + if (lRet) { var p = pParams; - main.commander.getDirContent(p.name, function(pError, pJSON){ - if (!pError){ + main.commander.getDirContent(p.name, function(pError, pJSON) { + if (!pError) { var lQuery = main.getQuery(p.request); - if ( Util.isContainStr(lQuery, 'json') ){ + if ( Util.isContainStr(lQuery, 'json') ) { p.data = Util.stringifyJSON(pJSON); p.name +='.json'; - main.sendResponse(p); + main.sendResponse(p, null, true); } else{ /* get back html*/ p.name = Minify.allowed ? Minify.getName(INDEX) : INDEX; - fs.readFile(p.name, function(pError, pData){ + fs.readFile(p.name, function(pError, pData) { if (!pError) { var lPanel = CloudFunc.buildFromJSON(pJSON, FileTemplate, PathTemplate), lList = '
    ' + lPanel + '
' + @@ -325,7 +256,7 @@ main.sendResponse(p, indexProcessing({ additional : lList, data : pData.toString(), - })); + }), true); } else main.sendError(pParams, pError); diff --git a/css/config.css b/css/config.css new file mode 100644 index 00000000..3a38141f --- /dev/null +++ b/css/config.css @@ -0,0 +1,57 @@ +.config { + white-space: normal; +} + +.list li{ + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.config .form-control{ + padding: 0 12px; + font-size: 16px; + line-height: 1.428571429; + color: #555555; + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} + +.config .form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 1px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 1px rgba(102, 175, 233, 0.6); +} + +.config .form-control:-moz-placeholder { + color: #999999; +} + +.config .form-control::-moz-placeholder { + color: #999999; +} + +.config .form-control:-ms-input-placeholder { + color: #999999; +} + +.config .form-control::-webkit-input-placeholder { + color: #999999; +} + +.config .list { + margin : 5%; + text-align : left; +} + +.config .border{ + width : 300px; + margin : 10% auto; +} diff --git a/css/reset.css b/css/reset.css index 9a0cb0f5..0c70b773 100644 --- a/css/reset.css +++ b/css/reset.css @@ -10,7 +10,10 @@ html{ color: #222; } -body { margin: 0; font-size: 1em; line-height: 1.4; } + +body { + margin: 0; +} /* * Remove text-shadow in selection highlight: h5bp.com/i diff --git a/css/style.css b/css/style.css index 8f250198..4b585390 100644 --- a/css/style.css +++ b/css/style.css @@ -92,7 +92,7 @@ body { } .cmd-button { - width: 8%; + width: 9%; margin: 20px 2px 0 2px; overflow: hidden; color: rgb(49,123,249); diff --git a/html/config.html b/html/config.html new file mode 100644 index 00000000..53e4397c --- /dev/null +++ b/html/config.html @@ -0,0 +1,16 @@ +
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+ diff --git a/html/index.html b/html/index.html index 2b8cb2d1..c2596d49 100644 --- a/html/index.html +++ b/html/index.html @@ -26,6 +26,7 @@ + diff --git a/img/screen/config.png b/img/screen/config.png new file mode 100644 index 00000000..ce2f0ac5 Binary files /dev/null and b/img/screen/config.png differ diff --git a/img/screen/console.png b/img/screen/console.png new file mode 100644 index 00000000..59ecdf4a Binary files /dev/null and b/img/screen/console.png differ diff --git a/img/screen/edit.png b/img/screen/edit.png new file mode 100644 index 00000000..be4a3f2f Binary files /dev/null and b/img/screen/edit.png differ diff --git a/img/screen/menu.png b/img/screen/menu.png new file mode 100644 index 00000000..926b4c4c Binary files /dev/null and b/img/screen/menu.png differ diff --git a/img/screenshot/console.png b/img/screenshot/console.png deleted file mode 100644 index fdc893e6..00000000 Binary files a/img/screenshot/console.png and /dev/null differ diff --git a/img/screenshot/edit.png b/img/screenshot/edit.png deleted file mode 100644 index 96d5cbc1..00000000 Binary files a/img/screenshot/edit.png and /dev/null differ diff --git a/img/screenshot/menu.png b/img/screenshot/menu.png deleted file mode 100644 index 1bcec184..00000000 Binary files a/img/screenshot/menu.png and /dev/null differ diff --git a/json/modules.json b/json/modules.json index 64732a08..957b6b7b 100644 --- a/json/modules.json +++ b/json/modules.json @@ -3,6 +3,7 @@ "menu", "view", "help", + "config", "console", { "name": "storage", "data": [{ diff --git a/lib/client.js b/lib/client.js index 76c94959..bfc4ec53 100644 --- a/lib/client.js +++ b/lib/client.js @@ -4,7 +4,7 @@ */ var Util, DOM, CloudFunc, CloudCmd; -(function(Util, DOM){ +(function(Util, DOM) { 'use strict'; var Key, Config, Modules, FileTemplate, PathTemplate, Listeners, @@ -19,7 +19,7 @@ var Util, DOM, CloudFunc, CloudCmd; MIN_ONE_PANEL_WIDTH : 1155, OLD_BROWSER : false, - HOST : (function(){ + HOST : (function() { var lLocation = document.location; return lLocation.protocol + '//' + lLocation.host; })() @@ -32,8 +32,8 @@ var Util, DOM, CloudFunc, CloudCmd; * @param pLink - ссылка * @param pNeedRefresh - необходимость обязательной загрузки данных с сервера */ - CloudCmd.loadDir = function(pLink, pNeedRefresh){ - return function(pEvent){ + CloudCmd.loadDir = function(pLink, pNeedRefresh) { + return function(pEvent) { /* показываем гиф загрузки возле пути папки сверху * ctrl+r нажата? */ @@ -43,7 +43,7 @@ var Util, DOM, CloudFunc, CloudCmd; lLink += '?json'; - if(lLink || lCurrentLink.target !== '_blank'){ + if (lLink || lCurrentLink.target !== '_blank') { DOM.Images.showLoad(pNeedRefresh ? {top:true} : null); /* загружаем содержимое каталога */ @@ -61,13 +61,13 @@ var Util, DOM, CloudFunc, CloudCmd; * в верх по файловой структуре * @param pDirName - имя каталога с которого мы пришли */ - function currentToParent(pDirName){ + function currentToParent(pDirName) { var lRootDir; /* убираем слэш с имени каталога */ pDirName = Util.removeStr(pDirName, '/'); lRootDir = DOM.getCurrentFileByName(pDirName); - if (lRootDir){ + if (lRootDir) { DOM.setCurrentFile(lRootDir); DOM.scrollIntoViewIfNeeded(lRootDir, true); } @@ -77,36 +77,36 @@ var Util, DOM, CloudFunc, CloudCmd; * function load modules * @pParams = {name, path, func, dobefore, arg} */ - function loadModule(pParams){ - if(pParams){ + function loadModule(pParams) { + if (pParams) { var lName = pParams.name, lPath = pParams.path, lFunc = pParams.func, lDoBefore = pParams.dobefore; - if( Util.isString(pParams) ) + if ( Util.isString(pParams) ) lPath = pParams; - if(lPath && !lName){ + if (lPath && !lName) { lName = Util.getStrBigFirst(lPath); lName = Util.removeStr(lName, '.js'); var lSlash = lName.indexOf('/'); - if(lSlash > 0){ + if (lSlash > 0) { var lAfterSlash = lName.substr(lSlash); lName = Util.removeStr(lName, lAfterSlash); } } - if( !Util.isContainStr(lPath, '.js') ) + if ( !Util.isContainStr(lPath, '.js') ) lPath += '.js'; - if(!CloudCmd[lName]) - CloudCmd[lName] = function(pArg){ + if (!CloudCmd[lName]) + CloudCmd[lName] = function(pArg) { Util.exec(lDoBefore); return DOM.jsload(CloudCmd.LIBDIRCLIENT + lPath, lFunc || - function(){ + function() { Util.exec(CloudCmd[lName].init, pArg); }); }; @@ -117,7 +117,7 @@ var Util, DOM, CloudFunc, CloudCmd; * выполняет весь функционал по * инициализации */ - CloudCmd.init = function(){ + CloudCmd.init = function() { var lCallBack, lFunc, lHeight; /* устанавливаем размер высоты таблицы файлов * исходя из размеров разрешения экрана @@ -141,14 +141,14 @@ var Util, DOM, CloudFunc, CloudCmd; '}' }); - lCallBack = function(){ + lCallBack = function() { Util.loadOnLoad([ - Util.retExec(CloudCmd.route, location.hash), + Util.retFunc(CloudCmd.route, location.hash), baseInit, initModules, ]); }, - lFunc = function(pCallBack){ + lFunc = function(pCallBack) { CloudCmd.OLD_BROWSER = true; var lSrc = CloudCmd.LIBDIRCLIENT + 'polyfill.js'; @@ -160,7 +160,7 @@ var Util, DOM, CloudFunc, CloudCmd; Util.ifExec(document.body.scrollIntoViewIfNeeded, lCallBack, lFunc); }; - CloudCmd.route = function(pPath){ + CloudCmd.route = function(pPath) { var lQuery, lModule, lFile, lCurrent, lMsg; if (pPath.length > 0) { @@ -181,11 +181,11 @@ var Util, DOM, CloudFunc, CloudCmd; } }; - function initModules(pCallBack){ + function initModules(pCallBack) { loadModule({ /* привязываем клавиши к функциям */ path : 'key.js', - func : function(){ + func : function() { Key = CloudCmd.Key; Key.bind(); } @@ -214,14 +214,14 @@ var Util, DOM, CloudFunc, CloudCmd; for (i = 0, n = pModules.length; i < n ; i++) { var lModule = pModules[i]; - if( Util.isString(lModule) ) + if ( Util.isString(lModule) ) lLoad(null, lModule, lDoBefore[lModule]); } var lStorageObj = Util.findObjByNameInArr( pModules, lStorage ), lMod = Util.getNamesFromObjArray( lStorageObj ); - for (i = 0, n = lMod.length; i < n; i++){ + for (i = 0, n = lMod.length; i < n; i++) { var lName = lMod[i], lPath = lStorage + '/_' + lName.toLowerCase(); @@ -270,7 +270,7 @@ var Util, DOM, CloudFunc, CloudCmd; /* выделяем строку с первым файлом */ var lFmHeader = DOM.getByClass('fm-header'); - if(lFmHeader && lFmHeader[0]){ + if (lFmHeader && lFmHeader[0]) { var lCurrent = lFmHeader[0].nextSibling; DOM.setCurrentFile(lCurrent); } @@ -282,18 +282,17 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.Key(); } - function getSystemFile(pGlobal, pURL){ + function getSystemFile(pGlobal, pURL) { - function lGetSysFile(pCallBack){ - Util.ifExec(pGlobal, pCallBack, function(pCallBack){ - if(!pGlobal) - DOM.ajax({ - url : pURL, - success : function(pLocal){ - pGlobal = pLocal; - Util.exec(pCallBack, pLocal); - } - }); + function lGetSysFile(pCallBack) { + Util.ifExec(pGlobal, pCallBack, function(pCallBack) { + DOM.ajax({ + url : pURL, + success : function(pLocal) { + pGlobal = pLocal; + Util.exec(pCallBack, pLocal); + } + }); }); } @@ -307,20 +306,20 @@ var Util, DOM, CloudFunc, CloudCmd; CloudCmd.getFileTemplate = getSystemFile(FileTemplate, CloudCmd.HTMLDIR + 'file.html'); CloudCmd.getPathTemplate = getSystemFile(PathTemplate, CloudCmd.HTMLDIR + 'path.html'); - CloudCmd.execFromModule = function(pModuleName, pFuncName, pParams){ + CloudCmd.execFromModule = function(pModuleName, pFuncName, pParams) { var lObject = CloudCmd[pModuleName]; Util.ifExec(Util.isObject(lObject), - function(){ + function() { var lObj = CloudCmd[pModuleName]; Util.exec( lObj[pFuncName], pParams); }, - function(pCallBack){ + function(pCallBack) { Util.exec(lObject, pCallBack); }); }; - CloudCmd.refresh = function(pCurrent){ + CloudCmd.refresh = function(pCurrent) { var lNEEDREFRESH = true, lPanel = pCurrent && pCurrent.parentElement, lPath = DOM.getCurrentDirPath(lPanel), @@ -338,8 +337,8 @@ var Util, DOM, CloudFunc, CloudCmd; * @param pOptions * { refresh, nohistory } - необходимость обновить данные о каталоге */ - CloudCmd.ajaxLoad = function(pPath, pOptions){ - if(!pOptions) + CloudCmd.ajaxLoad = function(pPath, pOptions) { + if (!pOptions) pOptions = {}; /* Отображаем красивые пути */ @@ -350,12 +349,12 @@ var Util, DOM, CloudFunc, CloudCmd; lOldURL = window.location.pathname; - if(lCleanPath === lSLASH) + if (lCleanPath === lSLASH) lNOJSPath = lSLASH; Util.log ('reading dir: "' + lCleanPath + '";'); - if(!pOptions.nohistory) + if (!pOptions.nohistory) DOM.setHistory(lNOJSPath, null, lNOJSPath); DOM.setTitle( CloudFunc.getTitle(lCleanPath) ); @@ -369,10 +368,10 @@ var Util, DOM, CloudFunc, CloudCmd; * перезагружаемся */ var lRet = pOptions.refresh; - if(!lRet){ + if (!lRet) { var lJSON = Cache.get(lCleanPath); - if (lJSON){ + if (lJSON) { lJSON = Util.parseJSON(lJSON); createFileTable(lPanel, lJSON); } @@ -380,17 +379,17 @@ var Util, DOM, CloudFunc, CloudCmd; lRet = true; } - if(lRet) + if (lRet) DOM.getCurrentFileContent({ url : lFSPath, dataType: 'json', - error : function(){ + error : function() { DOM.setHistory(lOldURL, null, lOldURL); }, - success : function(pData){ + success : function(pData) { createFileTable(lPanel, pData); /* переводим таблицу файлов в строку, для * @@ -400,7 +399,7 @@ var Util, DOM, CloudFunc, CloudCmd; /* если размер данных не очень бошьой * * сохраняем их в кэше */ - if(lJSON_s.length < 50000 ) + if (lJSON_s.length < 50000 ) Cache.set(lCleanPath, lJSON_s); } }); @@ -411,7 +410,7 @@ var Util, DOM, CloudFunc, CloudCmd; * @param pEleme - родительский элемент * @param pJSON - данные о файлах */ - function createFileTable(pElem, pJSON){ + function createFileTable(pElem, pJSON) { var lElem = DOM.getById(pElem), /* getting current element if was refresh */ lPath = DOM.getByClass('path', lElem), @@ -438,28 +437,28 @@ var Util, DOM, CloudFunc, CloudCmd; /* если нажали на ссылку на верхний каталог*/ var lFound; /* searching current file */ - if(lWasRefresh_b){ + if (lWasRefresh_b) { var n = lElem.childNodes.length; - for(i = 2; i < n ; i++){ + for(i = 2; i < n ; i++) { var lVarCurrent = lElem.childNodes[i], lVarName = DOM.getCurrentName(lVarCurrent); lFound = lVarName === lName; - if(lFound){ + if (lFound) { lCurrent = lElem.childNodes[i]; break; } } } - if(!lFound) /* .. */ + if (!lFound) /* .. */ lCurrent = lElem.childNodes[2]; DOM.setCurrentFile(lCurrent); Listeners.changeLinks(pElem); - if(lName === '..' && lDir !== '/') + if (lName === '..' && lDir !== '/') currentToParent(lDir); }); } @@ -468,7 +467,7 @@ var Util, DOM, CloudFunc, CloudCmd; * Функция генерирует JSON из html-таблицы файлов и * используеться при первом заходе в корень */ - function getJSONfromFileTable(){ + function getJSONfromFileTable() { var lLeft = DOM.getById('left'), lPath = DOM.getByClass('path')[0].textContent, @@ -487,7 +486,7 @@ var Util, DOM, CloudFunc, CloudCmd; */ /* пропускам Path и Header*/ - for(i = 2, n = lLI.length; i < n; i++){ + for(i = 2, n = lLI.length; i < n; i++) { var lCurrent = lLI[i], lName = DOM.getCurrentName(lCurrent), lSize = DOM.getCurrentSize(lCurrent), @@ -495,7 +494,7 @@ var Util, DOM, CloudFunc, CloudCmd; lMode = DOM.getCurrentMode(lCurrent); lMode = CloudFunc.getNumericPermissions(lMode); - if(lName !== '..') + if (lName !== '..') lFileTable[ j++ ] = { name: lName, size: lSize, @@ -505,5 +504,5 @@ var Util, DOM, CloudFunc, CloudCmd; return Util.stringifyJSON(lFileTable); } - DOM.Events.addOneTime('load', CloudCmd.init); + DOM.Events.addOnce('load', CloudCmd.init); })(Util, DOM); diff --git a/lib/client/config.js b/lib/client/config.js new file mode 100644 index 00000000..8aff72d3 --- /dev/null +++ b/lib/client/config.js @@ -0,0 +1,152 @@ +var CloudCmd, Util, DOM; +(function(CloudCmd, Util, DOM){ + 'use strict'; + + CloudCmd.Config = new ConfigProto(CloudCmd, Util, DOM); + + function ConfigProto(CloudCmd, Util, DOM){ + var Key = CloudCmd.Key, + Images = DOM.Images, + Events = DOM.Events, + ESC = CloudCmd.Key.ESC, + INPUT = 'INPUT', + CONFIG, + TEMPLATE, + Config = this; + + this.init = function(pCallBack){ + Util.loadOnLoad([ + Config.show, + CloudCmd.View, + ]); + + DOM.Events.addKey(listener); + DOM.setButtonKey('f10', Config.show); + + delete Config.init; + }; + + this.show = function() { + var funcs = [ + getTemplate, + cssLoad + ]; + + Images.showLoad({top:true}); + Util.asyncCall(funcs, fillTemplate); + }; + + function cssLoad(callback) { + DOM.cssLoad({ + src : '/css/config.css', + func: Util.retExec(callback) + }); + } + + + function getTemplate(callback) { + Util.ifExec(TEMPLATE, callback, function (execCall) { + DOM.ajax({ + url : '/html/config.html', + success : function(data) { + TEMPLATE = data; + execCall(); + }, + error : Images.showError + }); + + }); + } + + function fillTemplate() { + Util.ifExec(CONFIG, function() { + var i, n, div, data, li, param, obj = {}; + + Util.copyObj(CONFIG, obj); + changeConfig(obj); + data = Util.render(TEMPLATE, obj); + div = DOM.anyload({ + name : 'div', + className : 'config', + inner : data.toString() + }); + + li = DOM.getByTag(INPUT, div); + n = li.length; + + for (i = 0; i < n; i++) { + param = li[i]; + Events.add('change', change, param); + Events.addKey(key, param); + } + + Images.hideLoad(); + CloudCmd.View.show(div, null, { + autoSize: true + }); + }, function(callback) { + CloudCmd.getConfig(function(config){ + CONFIG = config; + callback(); + }); + }); + } + + this.hide = function() { + CloudCmd.View.hide(); + }; + + function listener(pEvent){ + var f10 = Key.F10, + isBind = Key.isBind(), + key = pEvent.keyCode; + + /* если клавиши можно обрабатывать */ + if (isBind && key === f10) + Config.show(); + } + + function changeConfig(config) { + var name; + + for (name in config) + if (Util.isBoolean(config[name])) + config[name] = setState(config[name]); + } + + function setState(state) { + var ret = ""; + + if (state) + ret = " checked"; + + return ret; + } + + function change(event) { + var data, + obj = {}, + el = event.target, + name = el.id, + type = el.type; + + if (el.type === 'checkbox') + data = el.checked; + else + data = el.value; + + obj[name] = data; + CONFIG[name] = data; + + DOM.RESTful.config(obj); + } + + function key(event) { + var keyCode = event.keyCode; + + if (keyCode === ESC) + Config.hide(); + } + } + +})(CloudCmd, Util, DOM); diff --git a/lib/client/console.js b/lib/client/console.js index 7a801325..294d3992 100644 --- a/lib/client/console.js +++ b/lib/client/console.js @@ -1,10 +1,15 @@ var CloudCmd, Util, DOM, $; -(function(CloudCmd, Util, DOM){ +(function(CloudCmd, Util, DOM) { 'use strict'; + var Buffer = { + log : '', + error : '' + }; + CloudCmd.Console = new ConsoleProto(CloudCmd, Util, DOM); - function ConsoleProto(CloudCmd, Util, DOM){ + function ConsoleProto(CloudCmd, Util, DOM) { var Name = 'Console', Loading, jqconsole, @@ -72,10 +77,10 @@ var CloudCmd, Util, DOM, $; handler(); } - CloudCmd.View.show(Element, function(){ + CloudCmd.View.show(Element, function() { var l$Console = jqconsole.$console, l$Input = jqconsole.$input_source, - lFocus = function(){ + lFocus = function() { var x = window.scrollX, y = window.scrollY; @@ -102,32 +107,33 @@ var CloudCmd, Util, DOM, $; } }; - this.hide = function(){ + this.hide = function() { CloudCmd.View.hide(); }; - this.log = function(pText){ - if (jqconsole) - jqconsole.Write( addNewLine(pText), 'log-msg'); + this.log = function(pText) { + log(pText, 'log'); }; - this.error = function(pText){ - if (jqconsole) - jqconsole.Write( addNewLine(pText), 'error-msg'); + this.error = function(pText) { + log(pText, 'error'); }; - function addNewLine(pText){ - var lNewLine = '', - n = pText && pText.length; + function log(msg, status) { + var ret; - if(n && pText[n-1] !== '\n') - lNewLine = '\n'; - - return pText + lNewLine; + if (msg) { + Buffer[status] += msg; + ret = Util.isContainStr(Buffer[status], '\n'); + + if (jqconsole && ret) { + jqconsole.Write(Buffer[status], status + '-msg'); + Buffer[status] = ''; + } + } } - - function load(pCallBack){ + function load(pCallBack) { Util.time(Name + ' load'); var lDir = CloudCmd.LIBDIRCLIENT + 'console/', @@ -137,7 +143,7 @@ var CloudCmd, Util, DOM, $; lDir + 'ansi.css' ]; - DOM.anyLoadInParallel(lFiles, function(){ + DOM.anyLoadInParallel(lFiles, function() { Util.timeEnd(Name + ' load'); Loading = false; @@ -145,15 +151,15 @@ var CloudCmd, Util, DOM, $; }); } - function listener(pEvent){ + function listener(pEvent) { var lTRA = Key.TRA, lESC = Key.ESC, lIsBind = Key.isBind(), lKey = pEvent.keyCode; - switch(lKey){ + switch(lKey) { case lTRA: - if (lIsBind){ + if (lIsBind) { Console.show(); DOM.preventDefault(pEvent); } diff --git a/lib/client/dom.js b/lib/client/dom.js index eed2f535..c22ee5e1 100644 --- a/lib/client/dom.js +++ b/lib/client/dom.js @@ -1,4 +1,4 @@ -var CloudCmd, Util, DOM, CloudFunc; +var CloudCmd, Util, DOM, CloudFunc, Dialog; (function(Util) { 'use strict'; @@ -6,6 +6,12 @@ var CloudCmd, Util, DOM, CloudFunc; var DOMFunc = function() {}, DOMProto, + DialogProto = function() { + this.alert = alert.bind(window); + this.prompt = prompt.bind(window); + this.confirm = confirm.bind(window); + }, + ImagesProto = function() { var LImagesProto = function() { function getImage(pName) { @@ -95,14 +101,13 @@ var CloudCmd, Util, DOM, CloudFunc; } /* если файла не существует*/ - if ( Util.isContainStr(lText, 'Error: ENOENT, ') ) + if (Util.isContainStr(lText, 'Error: ENOENT, ')) lText = lText.replace('Error: ENOENT, n','N'); /* если не хватает прав для чтения файла*/ - else if ( Util.isContainStr(lText, 'Error: EACCES,') ) + else if (Util.isContainStr(lText, 'Error: EACCES,')) lText = lText.replace('Error: EACCES, p','P'); - DOM.show(lErrorImage); lErrorImage.title = lText; @@ -114,14 +119,14 @@ var CloudCmd, Util, DOM, CloudFunc; if (lText) { Util.log(lText); - setTimeout(Util.retExec(alert, lText), 100); + setTimeout(Util.retFunc(Dialog.alert, lText), 100); } return lErrorImage; }; }, - RESTfullProto = function() { + RESTfulProto = function() { this.delete = function(pUrl, pData, pCallBack, pQuery) { sendRequest({ method : 'DELETE', @@ -176,6 +181,16 @@ var CloudCmd, Util, DOM, CloudFunc; callback : pCallBack }); }; + + this.config = function(pData, pCallBack) { + sendRequest({ + method : 'PUT', + url : '/config', + data : pData, + callback : pCallBack, + imgPosition : { top: true } + }); + }; function sendRequest(pParams) { var lRet = Util.checkObjTrue(pParams, ['method']); @@ -343,7 +358,7 @@ var CloudCmd, Util, DOM, CloudFunc; * @param pUseCapture * @param pElement {document by default} */ - this.addOneTime = function(pType, pListener, pElement, pUseCapture) { + this.addOnce = function(pType, pListener, pElement, pUseCapture) { var lRet = this, lOneTime = function (pEvent) { lRet.remove(pType, lOneTime, pElement, pUseCapture); @@ -1098,10 +1113,10 @@ var CloudCmd, Util, DOM, CloudFunc; if (lName === '..') lName = ''; - lName = prompt(lMsg, lName); + lName = Dialog.prompt(lMsg, lName); if (lName) - RESTfull.save(lDir + lName + lType, null, CloudCmd.refresh); + RESTful.save(lDir + lName + lType, null, CloudCmd.refresh); }; /** @@ -1117,7 +1132,7 @@ var CloudCmd, Util, DOM, CloudFunc; }; if (lName && lName !== '..') - RESTfull.zip(lFiles, CloudCmd.refresh); + RESTful.zip(lFiles, CloudCmd.refresh); }; @@ -1173,9 +1188,9 @@ var CloudCmd, Util, DOM, CloudFunc; } if (lName !== '..') - lRet = confirm(lMsg); + lRet = Dialog.confirm(lMsg); else - alert('No files selected!'); + Dialog.alert('No files selected!'); if (lRet) { var lUrl; @@ -1188,7 +1203,7 @@ var CloudCmd, Util, DOM, CloudFunc; } if (lCurrent || lSelected) - RESTfull.delete(lUrl, lSelected, function() { + RESTful.delete(lUrl, lSelected, function() { if (n > 1) DOM.deleteSelected(lFiles); else @@ -1317,7 +1332,7 @@ var CloudCmd, Util, DOM, CloudFunc; /* если это папка - возвращаем слово dir вместо размера*/ if (lName !== '..') - RESTfull.read(lLink, function(pSize) { + RESTful.read(lLink, function(pSize) { DOM.setCurrentSize(pSize, lCurrent); Util.exec(pCallBack, lCurrent); }, '?size'); @@ -1813,7 +1828,7 @@ var CloudCmd, Util, DOM, CloudFunc; var lCurrent = pCurrentFile || Cmd.getCurrentFile(), lFrom = Cmd.getCurrentName(lCurrent), - lTo = prompt('Rename', lFrom) || lFrom, + lTo = Dialog.prompt('Rename', lFrom) || lFrom, lDirPath = Cmd.getCurrentDirPath(); if ( !Util.strCmp(lFrom, lTo) ) { @@ -1822,7 +1837,7 @@ var CloudCmd, Util, DOM, CloudFunc; to : lDirPath + lTo }; - RESTfull.mv(lFiles, function() { + RESTful.mv(lFiles, function() { DOM.setCurrentName(lTo, lCurrent); }); } @@ -1842,7 +1857,7 @@ var CloudCmd, Util, DOM, CloudFunc; lFromPath = Cmd.getCurrentPath(), lToPath = Cmd.getNotCurrentDirPath() + lName; - lToPath = prompt( 'Rename/Move file "' + lName + '"', lToPath ); + lToPath = Dialog.prompt('Rename/Move file "' + lName + '"', lToPath); if ( lToPath && !Util.strCmp(lFromPath, lToPath) ) { var lFiles = { @@ -1850,7 +1865,7 @@ var CloudCmd, Util, DOM, CloudFunc; to : lToPath }; - RESTfull.mv(lFiles, function() { + RESTful.mv(lFiles, function() { DOM.deleteCurrent(lCurrent); var lPanel = DOM.getPanel(true), @@ -1875,7 +1890,7 @@ var CloudCmd, Util, DOM, CloudFunc; lName = Cmd.getCurrentName(lCurrent), lFromPath = Cmd.getCurrentPath(), lToPath = Cmd.getNotCurrentDirPath() + lName; - lToPath = prompt( 'Copy file "' + lName + '" to', lToPath ); + lToPath = Dialog.prompt( 'Copy file "' + lName + '" to', lToPath ); if ( lToPath && !Util.strCmp(lFromPath, lToPath) ) { var lFiles = { @@ -1883,7 +1898,7 @@ var CloudCmd, Util, DOM, CloudFunc; to : lToPath }; - RESTfull.cp(lFiles, function() { + RESTful.cp(lFiles, function() { var lPanel = DOM.getPanel(true), lDotDot = DOM.getById( '..(' + lPanel.id + ')'); @@ -1940,16 +1955,18 @@ var CloudCmd, Util, DOM, CloudFunc; Events = Util.extendProto(EventsProto), Loader = Util.extendProto(LoaderProto), Images = Util.extendProto(ImagesProto), - RESTfull = Util.extendProto(RESTfullProto), + RESTful = Util.extendProto(RESTfulProto), Cache = Util.extendProto(CacheProto); DOMProto = DOMFunc.prototype = new CmdProto(); + Dialog = new DialogProto(); + Util.extend(DOMProto, [ DOMTree, Loader, { Events : Events, - RESTfull: RESTfull, + RESTful: RESTful, Images : Images, Cache : Cache } diff --git a/lib/client/edit.js b/lib/client/edit.js index 6d99bd91..3d90ceb9 100644 --- a/lib/client/edit.js +++ b/lib/client/edit.js @@ -49,7 +49,6 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; if (!Element) { Element = DOM.anyload({ name : 'div', - className : 'edit', style : 'width : 100%;' + 'height : 100%;' + @@ -122,7 +121,7 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; var lPath = DOM.getCurrentPath(), lValue = Ace.getValue(); - DOM.RESTfull.save(lPath, lValue, Edit.showMessage); + DOM.RESTful.save(lPath, lValue, Edit.showMessage); } }); } @@ -161,7 +160,7 @@ var CloudCmd, Util, DOM, CloudFunc, JsDiff, ace; if (!Msg) { DOM.cssSet({ id : 'msg-css', - inner : '.msg {' + + inner : '#view .msg {' + 'z-index' + ': 1;' + 'background-color' + ': #7285B7;' + 'color' + ': #D1F1A9;' + diff --git a/lib/client/help.js b/lib/client/help.js index e6a54f28..5229cd08 100644 --- a/lib/client/help.js +++ b/lib/client/help.js @@ -9,7 +9,7 @@ var CloudCmd, Util, DOM; Images = DOM.Images, Help = this; - this.init = function(pCallBack){ + this.init = function(pCallBack) { Util.loadOnLoad([ Help.show, CloudCmd.View, @@ -21,12 +21,26 @@ var CloudCmd, Util, DOM; delete Help.init; }; - this.show = function(){ + this.show = function() { Images.showLoad({top:true}); + + DOM.cssSet({ + id : 'help-css', + inner : '#help {' + + 'white-space' + ': normal;' + + 'margin' + ': 25px;' + + '}' + + + '#help li {' + + 'list-style-type' + ': disc;' + + '}' + }); + DOM.ajax({ url: '/HELP.md', - success: function (pData){ + success: function (pData) { var lData = {text: pData}; + DOM.ajax({ method : 'post', url : 'https://api.github.com/markdown', @@ -34,7 +48,7 @@ var CloudCmd, Util, DOM; success:function(pResult){ var lDiv = DOM.anyload({ name : 'div', - style : 'white-space: normal;', + id : 'help', inner : pResult.toString() }); @@ -50,10 +64,11 @@ var CloudCmd, Util, DOM; }); }; + this.hide = function() { + CloudCmd.View.hide(); + }; - this.hide = CloudCmd.View.hide; - - function listener(pEvent){ + function listener(pEvent) { var lF1 = Key.F1, lIsBind = Key.isBind(), lKey = pEvent.keyCode; diff --git a/lib/client/key.js b/lib/client/key.js index ef6ef032..b8d91b74 100644 --- a/lib/client/key.js +++ b/lib/client/key.js @@ -39,6 +39,7 @@ var CloudCmd, Util, DOM; F7 : 118, F8 : 119, F9 : 120, + F10 : 121, TRA : 192 /* Typewritten Reverse Apostrophe (`) */ }; @@ -112,7 +113,7 @@ var CloudCmd, Util, DOM; if ( DOM.isCurrentIsDir(lCurrent) ) lUrl += '?dir'; - DOM.RESTfull.delete(lUrl, function() { + DOM.RESTful.delete(lUrl, function() { DOM.deleteCurrent(lCurrent); }); } @@ -163,6 +164,12 @@ var CloudCmd, Util, DOM; break; + case Key.F10: + Util.exec(CloudCmd.Config); + DOM.preventDefault(pEvent); + + break; + case Key.TRA: DOM.Images.showLoad({top: true}); Util.exec(CloudCmd.Console); diff --git a/lib/client/listeners.js b/lib/client/listeners.js index a509ec0e..72cb59db 100644 --- a/lib/client/listeners.js +++ b/lib/client/listeners.js @@ -16,7 +16,7 @@ var Util, DOM, CloudCmd; online = config.online; if (analytics && online) { - Events.addOneTime('mousemove', function(){ + Events.addOnce('mousemove', function(){ var FIVE_SECONDS = 5000, lUrl = CloudCmd.LIBDIRCLIENT + 'analytics.js'; @@ -43,24 +43,25 @@ var Util, DOM, CloudCmd; lFuncs =[ null, - CloudCmd.Help, /* f1 */ - DOM.renameCurrent, /* f2 */ - CloudCmd.View, /* f3 */ - CloudCmd.Edit, /* f4 */ - DOM.copyCurrent, /* f5 */ - DOM.moveCurrent, /* f6 */ - DOM.promptNewDir, /* f7 */ - DOM.promptDeleteSelected, /* f8 */ - CloudCmd.Menu, /* f9 */ + CloudCmd.Help, /* f1 */ + DOM.renameCurrent, /* f2 */ + CloudCmd.View, /* f3 */ + CloudCmd.Edit, /* f4 */ + DOM.copyCurrent, /* f5 */ + DOM.moveCurrent, /* f6 */ + DOM.promptNewDir, /* f7 */ + DOM.promptDeleteSelected, /* f8 */ + CloudCmd.Menu, /* f9 */ + CloudCmd.Config, /* f10 */ ]; - for (i = 1; i <= 9; i++) { + for (i = 1; i <= 10; i++) { lButton = 'f' + i, lEl = DOM.getById('f' + i); lKeysPanel[lButton] = lEl; - if (i === 1 || i === 3 || i === 4 || i === 9) - Events.addOneTime('click', lFuncs[i], lEl); + if (i === 1 || i === 3 || i === 4 || i === 9 || i === 10) + Events.addOnce('click', lFuncs[i], lEl); else Events.addClick(lFuncs[i], lEl); } @@ -68,7 +69,7 @@ var Util, DOM, CloudCmd; lButton = '~', lEl = DOM.getById('~'); lKeysPanel[lButton] = lEl; - Events.addOneTime('click', CloudCmd.Console, lEl); + Events.addOnce('click', CloudCmd.Console, lEl); return lKeysPanel; }; @@ -232,7 +233,7 @@ var Util, DOM, CloudCmd; var path = dir + file.name, data = event.target.result; - DOM.RESTfull.save(path, data, CloudCmd.refresh); + DOM.RESTful.save(path, data, CloudCmd.refresh); }; }; @@ -291,7 +292,7 @@ var Util, DOM, CloudCmd; } function online() { - var cssSet = Util.retExec(DOM.cssSet, { + var cssSet = Util.retFunc(DOM.cssSet, { id :'local-droids-font', element : document.head, inner : '@font-face {font-family: "Droid Sans Mono";' + @@ -301,7 +302,7 @@ var Util, DOM, CloudCmd; }); if (navigator.onLine) - Events.addOneTime('offline', cssSet); + Events.addOnce('offline', cssSet); else cssSet(); } diff --git a/lib/client/menu.js b/lib/client/menu.js index d35f51bb..392d61bb 100644 --- a/lib/client/menu.js +++ b/lib/client/menu.js @@ -174,12 +174,12 @@ var CloudCmd, Util, DOM, CloudFunc, $; function getConfig (){ var lRet, lMenuItems = { - 'View' : Util.retExec(show, 'View'), - 'Edit' : Util.retExec(show, 'Edit'), + 'View' : Util.retFunc(show, 'View'), + 'Edit' : Util.retFunc(show, 'Edit'), 'Rename' : function(){ - setTimeout( Util.retExec(DOM.renameCurrent), 100); + setTimeout( Util.retFunc(DOM.renameCurrent), 100); }, - 'Delete' : Util.retExec(DOM.promptDeleteSelected), + 'Delete' : Util.retFunc(DOM.promptDeleteSelected), '(Un)Select All': DOM.toggleAllSelectedFiles, 'Zip file' : DOM.zipFile }; @@ -187,7 +187,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; if (UploadToItemNames.length) lMenuItems['Upload to'] = getUploadToItems(UploadToItemNames); - lMenuItems.Download = Util.retExec(downloadFromMenu); + lMenuItems.Download = Util.retFunc(downloadFromMenu); lMenuItems.New = { 'File' : DOM.promptNewFile, @@ -197,7 +197,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; CloudCmd.execFromModule('FilePicker', 'saveFile', function(pName, pData){ var lPath = DOM.getCurrentDirPath() + pName; - DOM.RESTfull.save(lPath, pData, CloudCmd.refresh); + DOM.RESTful.save(lPath, pData, CloudCmd.refresh); }); } }; diff --git a/lib/client/socket.js b/lib/client/socket.js index f3ac82fe..600c45a2 100644 --- a/lib/client/socket.js +++ b/lib/client/socket.js @@ -1,6 +1,6 @@ /* module make possible connectoin thrue socket.io on a client */ var CloudCmd, Util, DOM, io; -(function(CloudCmd, Util, DOM){ +(function(CloudCmd, Util, DOM) { 'use strict'; var Messages = [], @@ -11,24 +11,22 @@ var CloudCmd, Util, DOM, io; 'npm i socket.io'; DOM.jsload('/socket.io/lib/socket.io.js', { - onerror : Util.retExec(Util.log, ERROR_MSG), + onerror : Util.retFunc(Util.log, ERROR_MSG), onload : connect }); function connect() { + var FIVE_SECONDS = 5000; + socket = io.connect(CloudCmd.HOST, { - 'reconnect' : true, - 'reconnection delay' : 500, 'max reconnection attempts' : Math.pow(2, 32), - 'reconnect_failed' : function() { - Util.log('Could not reconnect. Reload page.'); - } + 'reconnection limit' : FIVE_SECONDS }); CloudCmd.Socket = socket; socket.on('connect', function () { - outToTerminal({stdout: 'socket connected'}); + outToTerminal({stdout: 'socket connected\n'}); }); socket.on('message', function (msg) { @@ -39,28 +37,32 @@ var CloudCmd, Util, DOM, io; }); socket.on('disconnect', function () { - outToTerminal({stderr: 'socket disconected'}); + outToTerminal({stderr: 'socket disconected\n'}); + }); + + socket.on('reconnect_failed', function () { + Util.log('Could not reconnect. Reload page.'); }); } - function outToTerminal(pMsg){ + function outToTerminal(pMsg) { var i, n, lResult, lStdout, lStderr, lConsole = CloudCmd.Console; DOM.Images.hideLoad(); - if( Util.isObject(lConsole) ){ - if(Messages.length){ + if (Util.isObject(lConsole)) { + if (Messages.length) { /* show oll msg from buffer */ - for(i = 0, n = Messages.length; i < n; i++){ + for (i = 0, n = Messages.length; i < n; i++) { lStdout = Messages[i].stdout; lStderr = Messages[i].stderr; - if(lStdout) + if (lStdout) lConsole.log(lStdout); - if(lStderr){ + if (lStderr) { /* if it's object - convert is to string' */ - if( Util.isObject(lStderr) ) + if (Util.isObject(lStderr)) lStderr = Util.stringifyJSON(lStderr); lConsole.error(lStderr); @@ -72,11 +74,11 @@ var CloudCmd, Util, DOM, io; lStdout = pMsg.stdout; lStderr = pMsg.stderr; - if(lStdout) + if (lStdout) lResult = lConsole.log(lStdout); - if(lStderr && lStderr.code !== 1) - lResult = lConsole.error(lStderr.toString()); + if (lStderr) + lResult = lConsole.error(lStderr); } else /* if term not accesable save msg to buffer */ diff --git a/lib/client/view.js b/lib/client/view.js index d550280d..2f4a702d 100644 --- a/lib/client/view.js +++ b/lib/client/view.js @@ -42,7 +42,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; padding : 0 }; - this.init = function(pCallBack){ + this.init = function(pCallBack) { var lFunc, lIsFunc, lIsCallBack; Loading = true; @@ -71,9 +71,9 @@ var CloudCmd, Util, DOM, CloudFunc, $; /** * function shows FancyBox */ - this.show = function(pData, pCallBack){ - var lPath, lElement, - lAfterFunc, lFunc; + this.show = function(pData, pCallBack, pConfig) { + var lPath, lElement, lAfterFunc, lFunc, name, + config = {}; if (!Loading) { Element = $('
'); @@ -87,7 +87,12 @@ var CloudCmd, Util, DOM, CloudFunc, $; Config.afterShow = lFunc; - $.fancybox(lElement, Config); + Util.copyObj(Config, config); + + for (name in pConfig) + config[name] = pConfig[name]; + + $.fancybox(lElement, config); } else { lPath = CloudFunc.FS + DOM.getCurrentPath(); @@ -103,7 +108,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; } }; - this.hide = function(){ + this.hide = function() { $.fancybox.close(); }; @@ -112,7 +117,7 @@ var CloudCmd, Util, DOM, CloudFunc, $; * @pParent - this * @pCallBack - executes, when everything loaded */ - function load(pCallBack){ + function load(pCallBack) { Util.time(Name + ' load'); var lDir = CloudCmd.LIBDIRCLIENT + 'view/fancyBox/source/', lFiles = [ lDir + 'jquery.fancybox.css', @@ -147,12 +152,12 @@ var CloudCmd, Util, DOM, CloudFunc, $; } - function view(){ + function view() { Images.showLoad(); View.show(); } - function listener(pEvent){ + function listener(pEvent) { var lF3 = Key.F3, lIsBind = Key.isBind(), lKey = pEvent.keyCode; diff --git a/lib/cloudfunc.js b/lib/cloudfunc.js index 207c89fb..5a9cab15 100644 --- a/lib/cloudfunc.js +++ b/lib/cloudfunc.js @@ -21,7 +21,7 @@ var Util, exports, CloudFunc = {}; Util = global.cloudcmd.main.util; CloudFunc = exports; } - + /* Путь с которым мы сейчас работаем */ CloudFunc.Path = ''; @@ -43,7 +43,8 @@ var Util, exports, CloudFunc = {}; CloudFunc.formatMsg = function(pMsg, pName, pStatus) { var status = pStatus || 'ok', - msg = pMsg + ': ' + status + '("' + pName + '")'; + name = !pName ? '': '("' + pName + '")', + msg = pMsg + ': ' + status + name; return msg; }; diff --git a/lib/server.js b/lib/server.js index a9eaad10..8a0e83ca 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,7 +1,7 @@ (function() { 'use strict'; - if(!global.cloudcmd) + if (!global.cloudcmd) return console.log( '# server.js' + '\n' + '# -----------' + '\n' + @@ -20,30 +20,24 @@ Querystring = main.querystring, Minify = main.minify, + CloudFunc = main.cloudfunc, AppCache = main.appcache, Socket = main.socket, http = main.http, https = main.https, Util = main.util, + express = main.express, + expressApp = express.getApp(controller), - Server, Rest, Route, Minimize; + Server, Rest, Route; /* базовая инициализация */ function init(pAppCachProcessing) { - var lConfig = main.config, - lMinifyAllowed = lConfig.minify; - - /* Change default parameters of - * js/css/html minification - */ - Minify.setAllowed(lMinifyAllowed); - - /* Если нужно минимизируем скрипты */ - Util.exec(Minimize, lMinifyAllowed); + var config = main.config; /* создаём файл app cache */ - if( lConfig.appcache && AppCache && lConfig.server ) + if (config.appcache && AppCache && config.server ) Util.exec( pAppCachProcessing ); } @@ -56,12 +50,11 @@ function start(pProcessing) { var lConfig = main.config; - if(!pProcessing) + if (!pProcessing) pProcessing = {}; Rest = pProcessing.rest; Route = pProcessing.route; - Minimize = pProcessing.minimize; init(pProcessing.appcache); @@ -69,7 +62,7 @@ process.env.app_port || /* nodester */ process.env.VCAP_APP_PORT || /* cloudfoundry */ lConfig.port, - + lIP = process.env.IP || /* c9 */ lConfig.ip || (main.WIN32 ? '127.0.0.1' : '0.0.0.0'), @@ -80,15 +73,19 @@ lHTTPS = 'https://', lSockets = function(pServer) { - var lListen; - if(lConfig.socket && Socket) + var lListen, msg, status; + + if (lConfig.socket && Socket) lListen = Socket.listen(pServer); - Util.log('* Sockets ' + (lListen ? 'running' : 'disabled')); + status = lListen ? 'on' : 'off'; + msg = CloudFunc.formatMsg('sockets', '', status); + + Util.log(msg); }, lHTTPServer = function() { - Server = http.createServer( controller ); + Server = http.createServer(expressApp || controller); Server.on('error', Util.log); Server.listen(lPort, lIP); lServerLog(lHTTP, lPort); @@ -127,10 +124,9 @@ Server.listen(lSSLPort, lIP); lServerLog(lHTTPS, lSSLPort); - } - else + } else lHTTPServer(); - }else + } else Util.log('Cloud Commander testing mode'); } @@ -146,13 +142,14 @@ var lRet, lName, lMin, lExt, lResult, lConfig = main.config, lParsedUrl = URL.parse(pReq.url), + lQuery = lParsedUrl.search || '', lPath = lParsedUrl.pathname; /* added supporting of Russian language in directory names */ lPath = Querystring.unescape(lPath); - Util.log('pathname: ' + lPath); - Util.log("request for " + lPath + " received..."); + if (!expressApp) + Util.log(pReq.method + ' ' + lPath + lQuery); var lData = { name : lPath, @@ -160,24 +157,21 @@ response : pRes }; - if( lConfig.rest ) + if (lConfig.rest ) lRet = Util.exec(Rest, lData); - if( !lRet && Route) + if (!lRet && Route) lRet = Util.exec(Route, lData); - if(!lRet) { + if (!lRet) { lName = lData.name; - Util.log('reading ' + lName); /* watching is file changed */ - if(lConfig.appcache) + if (lConfig.appcache) AppCache.watch(lName); - Util.log(Path.basename(lName)); - lName = Path.join(DIR, lName); - lMin = Minify.allowed, + lMin = lConfig.minify, lExt = Util.getExtension(lName), lResult = lMin && Util.strCmp(lExt, ['.js', '.css', '.html']); diff --git a/lib/server/commander.js b/lib/server/commander.js index ea8de4ab..c2a50924 100644 --- a/lib/server/commander.js +++ b/lib/server/commander.js @@ -1,7 +1,7 @@ -(function(){ +(function() { 'use strict'; - if(!global.cloudcmd) + if (!global.cloudcmd) return console.log( '# commander.js' + '\n' + '# -----------' + '\n' + @@ -14,9 +14,10 @@ fs = main.fs, Util = main.util; - exports.getDirContent = function(pPath, pCallBack){ + exports.getDirContent = function(pPath, pCallBack) { var lRet = Util.isString(pPath); - if( lRet ) + + if (lRet) fs.readdir(pPath, Util.call(readDir, { callback: pCallBack, path : pPath @@ -33,16 +34,17 @@ * @param pError * @param pFiles */ - function readDir(pParams){ + function readDir(pParams) { var lRet = checkParams(pParams); lRet = lRet && Util.checkObj(pParams.params, ['path']); - if(lRet){ + + if (lRet) { var p = pParams, c = pParams.params, lFiles = p.data, lDirPath = getDirPath(c.path); - if(!p.error && lFiles){ + if (!p.error && lFiles) { lFiles.data = lFiles.sort(); /* Получаем информацию о файлах */ @@ -55,12 +57,10 @@ path : c.path }, - lFill = function(){ - fillJSON(lFilesData); - }; + lFill = Util.retFunc(fillJSON, lFilesData); - if(n){ - for(var i = 0; i < n; i++){ + if (n) + for (var i = 0; i < n; i++) { var lName = lDirPath + lFiles[i], lParams = { callback : lFill, @@ -69,13 +69,11 @@ stats : lStats, }; - fs.stat( lName, Util.call(getFilesStat, lParams) ); + fs.stat(lName, Util.call(getFilesStat, lParams)); } - } else fillJSON(lFilesData); - } - else + } else Util.exec(c.callback, p.error.toString()); } } @@ -84,12 +82,12 @@ * async getting file states * and putting it to lStats object */ - function getFilesStat(pParams){ + function getFilesStat(pParams) { var lRet = checkParams(pParams); lRet = lRet && Util.checkObjTrue(pParams.params, ['callback', 'stats', 'name', 'count']); - if(lRet){ + if (lRet) { var p = pParams, c = p.params; @@ -99,7 +97,7 @@ 'isDirectory' : Util.retFalse }; - if(c.count === Object.keys(c.stats).length) + if (c.count === Object.keys(c.stats).length) Util.exec(c.callback); } } @@ -112,11 +110,10 @@ * * @param pFiles - array of files of current directory */ - function fillJSON(pParams){ + function fillJSON(pParams) { var lRet = Util.checkObjTrue(pParams, ['files', 'stats', 'path']); - if(lRet) - { + if (lRet) { var p = pParams, i, n = p.files.length || 0, @@ -131,12 +128,12 @@ }; var lName, lStats, lMode, lIsDir; - for( i = 0; i < n; i++ ){ + for (i = 0; i < n; i++ ) { /* Переводим права доступа в 8-ричную систему */ lName = p.files[i], lStats = p.stats[lName]; - if(lStats){ + if (lStats) { lMode = (lStats.mode - 0).toString(8), lIsDir = lStats.isDirectory(); } @@ -158,14 +155,14 @@ } } - function checkParams(pParams){ + function checkParams(pParams) { return Util.checkObj(pParams, ['error', 'data', 'params']); } - function getDirPath(pPath){ + function getDirPath(pPath) { var lRet = pPath; - if(lRet !== '/') + if (lRet !== '/') lRet += '/'; return lRet; diff --git a/lib/server/dir.js b/lib/server/dir.js index 817e7517..46db3d8b 100644 --- a/lib/server/dir.js +++ b/lib/server/dir.js @@ -29,8 +29,7 @@ lTotal += lSize; } - processDir(pDir, calcSize, function(){ - Util.log(pDir + ' -> ' + lTotal); + processDir(pDir, calcSize, function() { Util.exec(pCallBack, null, lTotal); }); }; @@ -80,7 +79,7 @@ for (var i = 0; i < n; i++) { lDirPath = path.join(lPath, pFiles[i]); - process.nextTick( Util.retExec(getDirInfo, lDirPath) ); + process.nextTick(Util.retFunc(getDirInfo, lDirPath)); } } diff --git a/lib/server/express.js b/lib/server/express.js new file mode 100644 index 00000000..c52cb822 --- /dev/null +++ b/lib/server/express.js @@ -0,0 +1,23 @@ +(function() { + 'use strict'; + + if (!global.cloudcmd) + return console.log( + '# express.js' + '\n' + + '# -----------' + '\n' + + '# Module is part of Cloud Commander,' + '\n' + + '# easy to use web server.' + '\n' + + '# http://cloudcmd.io' + '\n'); + + var main = global.cloudcmd.main, + express = main.require('express'), + app = express && express(); + + exports.getApp = function(controller) { + if (app) + app.use(express.logger('dev')) + .all('*', controller); + + return app; + }; +})(); diff --git a/lib/server/main.js b/lib/server/main.js index 49c5d2bf..df3f02ac 100644 --- a/lib/server/main.js +++ b/lib/server/main.js @@ -1,4 +1,4 @@ -(function(){ +(function() { 'use strict'; /* Global var accessible from any loaded module */ @@ -11,7 +11,7 @@ SLASH, ISWIN32, ext, - path, fs, zlib, url, pipe, + path, fs, zlib, url, pipe, CloudFunc, OK, FILE_NOT_FOUND, MOVED_PERMANENTLY, REQUEST, RESPONSE, @@ -101,11 +101,12 @@ exports.VOLUMES = getVolumes(), /* Additional Modules */ + exports.cloudfunc = CloudFunc = librequire('cloudfunc'), exports.pipe = pipe = srvrequire('pipe'), exports.socket = srvrequire('socket'), + exports.express = srvrequire('express'), exports.auth = srvrequire('auth').auth, exports.appcache = srvrequire('appcache'), - exports.cloudfunc = librequire('cloudfunc'), exports.dir = srvrequire('dir'), exports.rest = srvrequire('rest').api, exports.update = srvrequire('update'), @@ -121,49 +122,51 @@ * function do safe require of needed module * @param {Strin} pSrc */ - function mrequire(pSrc){ - var lModule, - lError = Util.tryCatch(function(){ - lModule = require(pSrc); - }); + function mrequire(pSrc) { + var lModule, msg, + lError = Util.tryCatch(function() { + lModule = require(pSrc); + }); - if(lError) - Util.log('Module ' + pSrc + ' not connected'); + if (lError) + msg = CloudFunc.formatMsg('require', pSrc, 'no'); + + Util.log(msg); return lModule; } - function quietrequire(pSrc){ + function quietrequire(pSrc) { var lModule; - Util.tryCatch(function(){ + Util.tryCatch(function() { lModule = require(pSrc); }); return lModule; } - function rootrequire(pSrc){ return mrequire(DIR + pSrc); } + function rootrequire(pSrc) { return mrequire(DIR + pSrc); } - function librequire(pSrc){ return mrequire(LIBDIR + pSrc); } + function librequire(pSrc) { return mrequire(LIBDIR + pSrc); } - function srvrequire(pSrc){ return mrequire(SRVDIR + pSrc); } + function srvrequire(pSrc) { return mrequire(SRVDIR + pSrc); } - function jsonrequire(pSrc){ return mrequire(JSONDIR + pSrc);} + function jsonrequire(pSrc) { return mrequire(JSONDIR + pSrc);} /** * function check is current platform is win32 */ - function isWin32(){ return process.platform === 'win32'; } + function isWin32() { return process.platform === 'win32'; } /** * get volumes if win32 or get nothing if nix */ - function getVolumes(){ + function getVolumes() { var lRet = ISWIN32 ? [] : '/'; - if(ISWIN32) - srvrequire('win').getVolumes(function(pVolumes){ + if (ISWIN32) + srvrequire('win').getVolumes(function(pVolumes) { console.log(pVolumes); exports.VOLUMES = pVolumes; }); @@ -181,20 +184,20 @@ * query * https://developers.google.com/speed/docs/best-practices/caching?hl=ru#LeverageProxyCaching */ - function generateHeaders(pParams){ + function generateHeaders(pParams) { var lRet = Util.checkObjTrue(pParams, ['name']); - if(lRet){ + if (lRet) { var p = pParams, lExt = Util.getExtension(p.name), lType = ext[lExt] || 'text/plain', lContentEncoding = ''; /* if type of file any, but img - then we shoud specify charset */ - if( !Util.isContainStr(lType, 'img') ) + if (!Util.isContainStr(lType, 'img')) lContentEncoding = '; charset=UTF-8'; - if( Util.isContainStr(p.query, 'download') ) + if (Util.isContainStr(p.query, 'download')) lType = 'application/octet-stream'; lRet = { @@ -204,10 +207,10 @@ 'Vary' : 'Accept-Encoding' }; - if( !Util.strCmp(lExt, '.appcache') && p.cache) + if (!Util.strCmp(lExt, '.appcache') && p.cache) lRet['cache-control'] = 'max-age=' + 31337 * 21; - if(p.gzip) + if (p.gzip) lRet['content-encoding'] = 'gzip'; } @@ -221,29 +224,37 @@ * @param pName - имя файла * @param pGzip - данные сжаты gzip'ом */ - function sendFile(pParams){ - var lRet = checkParams(pParams); + function sendFile(pParams) { + var header, lRet = checkParams(pParams); + if (lRet) { var p = pParams, lGzip = isGZIP(p.request) && p.gzip; - - p.response.writeHead(OK, generateHeaders({ - name : p.name, - cache : p.cache, - gzip : lGzip, - query : getQuery(p.request) - }) ); - pipe.create({ - from: p.name, - write: p.response, - zip : lGzip && !p.gziped, - callback: function(pError) { - var lError = pError && pError.toString(); - if (pError) { - p.response.writeHead(FILE_NOT_FOUND, 'OK'); - p.response.end(lError); - } + fs.stat(p.name, function(error, stat) { + if (error) + sendError(pParams, error); + else { + header = generateHeaders({ + name : p.name, + cache : p.cache, + gzip : lGzip, + query : getQuery(p.request) + }); + + //p.response.writeHead(OK, header); + setHeader(header, p.response); + p.response.statusCode = p.status || OK; + + pipe.create({ + from : p.name, + write : p.response, + zip : lGzip && !p.gziped, + callback: function(error) { + if (error) + sendError(pParams, error); + } + }); } }); } @@ -258,13 +269,12 @@ * @param Data - данные * @param pName - имя отсылаемого файла */ - function sendResponse(pParams, pData){ + function sendResponse(pParams, pData, pNotLog) { var lRet = checkParams(pParams); - if(lRet){ - var p = pParams; - - var lQuery = getQuery(p.request), + if (lRet) { + var p = pParams, + lQuery = getQuery(p.request), /* download, json */ lGzip = isGZIP(p.request), lHead = generateHeaders({ @@ -273,21 +283,24 @@ gzip : lGzip, query : lQuery }); - + + setHeader(lHead, p.response); + + if (!pNotLog) + Util.log(pData || p.data); + /* если браузер поддерживает gzip-сжатие - сжимаем данные*/ Util.ifExec(!lGzip, function(pParams) { var lRet = Util.checkObj(pParams, ['data']); - if(lRet) { + if (lRet) { p.status = pParams.status || p.status; p.data = pParams.data; } - p.response.writeHead(p.status || OK, lHead); + p.response.statusCode = p.status || OK; p.response.end(p.data); - - Util.log( p.name + ' sended'); }, function(pCallBack) { @@ -302,14 +315,19 @@ /** * redirect to another URL */ - function redirect(pParams){ - var lRet = Util.checkObjTrue(pParams, - [RESPONSE]); + function redirect(pParams) { + var p, header, + lRet = Util.checkObjTrue(pParams, [RESPONSE]); - if(lRet){ - var p = pParams; + if (lRet) { + p = pParams; - p.response.writeHead(MOVED_PERMANENTLY, {'Location': p.url}); + header = { + 'Location': p.url + }, + + setHeader(header, p.response); + p.response.statusCode = MOVED_PERMANENTLY; p.response.end(); } } @@ -337,18 +355,18 @@ * @param pHeader - заголовок файла * @pName */ - function gzipData(pParams){ + function gzipData(pParams) { var lRet = checkCallBackParams(pParams), p = pParams; - if(lRet) + if (lRet) lRet = Util.checkObj(pParams.params, ['callback']); - if(lRet){ + if (lRet) { var lCallBack = p.params.callback, lParams = {}; - if(!p.error) + if (!p.error) lParams.data = p.data; else{ lParams.status = FILE_NOT_FOUND; @@ -360,39 +378,46 @@ } - function checkCallBackParams(pParams){ + function checkCallBackParams(pParams) { return Util.checkObj(pParams, ['error', 'data', 'params']); } - function readFiles(pFiles, pCallBack){ + function readFiles(pFiles, pCallBack) { var lDone = [], lFiles, lErrors, lReadedFiles = {}, - lDoneFunc = function (pParams){ - var lRet = Util.checkObj(pParams, ['error', 'data', 'params']); + lDoneFunc = function (pParams) { + var msg, status, + lRet = Util.checkObj(pParams, ['error', 'data', 'params']); - if(lRet){ + if (lRet) { lDone.pop(); var p = pParams, lName = p.params; - if(p.error){ - if(!lErrors) lErrors = {}; + if (p.error) { + status = 'error'; + if (!lErrors) lErrors = {}; lErrors[lName] = p.error; } else{ - Util.log(lName + ' readed'); + status = 'ok'; lReadedFiles[lName] = p.data; } - if( !lDone.length ) + lName = path.basename(lName); + msg = CloudFunc.formatMsg('read', lName, status); + + Util.log(msg); + + if ( !lDone.length ) Util.exec(pCallBack, lErrors, lReadedFiles); } }; - if( Util.isArray(pFiles) ) + if ( Util.isArray(pFiles) ) lFiles = pFiles; else lFiles = [pFiles]; @@ -405,7 +430,7 @@ } } - function checkParams(pParams, pAdditional){ + function checkParams(pParams, pAdditional) { var lRet = Util.checkObjTrue( pParams, ['name', REQUEST, RESPONSE] ); if (lRet && pAdditional) @@ -414,7 +439,7 @@ return lRet; } - function getQuery(pReq){ + function getQuery(pReq) { var lQuery, lParsedUrl; if (pReq) { @@ -425,7 +450,7 @@ return lQuery; } - function isGZIP(pReq){ + function isGZIP(pReq) { var lEnc, lGZIP; if (pReq) { lEnc = pReq.headers['accept-encoding'] || ''; @@ -435,4 +460,12 @@ return lGZIP; } + function setHeader(header, response) { + var name; + + if (Util.isObject(header)) + for (name in header) + response.setHeader(name, header[name]); + } + })(); diff --git a/lib/server/minify.js b/lib/server/minify.js index 9e971e6b..90d54745 100644 --- a/lib/server/minify.js +++ b/lib/server/minify.js @@ -28,48 +28,24 @@ exports.Minify = { /* pathes to directories */ INDEX : HTMLDIR + 'index.html', - /* приватный переключатель минимизации */ - allowed : true, - - /* функция разрешает или - * запрещает минимизировать - * css/js/html - * @pAllowed: - структура, в которой - * передаються параметры - * минификации, вида - * {js:true,css:true,html:false; img:true} - * img отвечает за перевод картинок в base64 - * и сохранение их в css-файл - */ - setAllowed :function(pAllowed) { - this.allowed = pAllowed && Minify; - }, optimize: function(pName, pParams) { var lRet; - if (Minify) { + if (!Minify) + Util.log(COULD_NOT_MINIFY); + else { pParams.name = Minify.getName(pName); - lRet = this.allowed; - - if(!this.MinFolder) + if (!this.MinFolder) this.MinFolder = Minify.MinFolder; - if(pParams && pParams.force) - Minify.optimize(pName, pParams); - else if(lRet) - IsChanged.isFileChanged(pName, function(pChanged) { - if(pChanged) - Minify.optimize(pName, pParams); - else - Util.exec(pParams.callback, pParams); - }); - } - else { - this.allowed = false; - - Util.log(COULD_NOT_MINIFY); + IsChanged.isFileChanged(pName, function(pChanged) { + if(pChanged) + Minify.optimize(pName, pParams); + else + Util.exec(pParams.callback, pParams); + }); } return lRet; diff --git a/lib/server/rest.js b/lib/server/rest.js index ea27d266..14a3f0f1 100644 --- a/lib/server/rest.js +++ b/lib/server/rest.js @@ -1,4 +1,4 @@ -/* RESTfull module */ +/* RESTful module */ (function() { 'use strict'; @@ -20,7 +20,10 @@ pipe = main.pipe, CloudFunc = main.cloudfunc, dir = main.dir, + JSONDIR = main.JSONDIR, OK = 200, + sendError = main.sendError, + sendResponse= main.sendResponse, Header = main.generateHeaders({ name:'api.json' }); @@ -38,8 +41,8 @@ lRet = Util.isContainStr(p.name, lAPIURL); if (lRet) { - p.name = Util.removeStrOneTime(p.name, lAPIURL); - sendData( pParams); + p.name = Util.removeStrOneTime(p.name, lAPIURL) || '/'; + sendData(pParams); } } return lRet; @@ -106,42 +109,41 @@ case 'GET': if (Util.strCmp(lQuery, 'size')) dir.getSize(p.name, function(pErr, pSize) { - if (!pErr){ + if (pErr) + sendError(p, pErr); + else { lSize = CloudFunc.getShortSize(pSize); - Util.log(lSize); - main.sendResponse(p, lSize); + sendResponse(p, lSize); } - else - main.sendError(p, pErr); + }); else fs.stat(p.name, function(pError, pStat) { - if (!pError) - if (pStat.isDirectory()) + if (pError) + sendError(p, pError); + else + if (!pStat.isDirectory()) + main.sendFile(p); + else main.commander.getDirContent(p.name, function(pError, pData) { - if (!pError){ + if (pError) + sendError(p, pError); + else { p.name += '.json'; p.data = Util.stringifyJSON(pData); - main.sendResponse(p); + sendResponse(p); } - else - main.sendError(p, pError); }); - else - main.sendFile(p); - else - main.sendError(p, pError); - }); break; case 'PUT': if (lQuery === 'dir') fs.mkdir(p.name, function(pError) { - if (!pError) - sendMsg(pParams, 'make dir', p.name); + if (pError) + sendError(pParams, pError); else - main.sendError(pParams, pError); + sendMsg(pParams, 'make dir', p.name); }); else @@ -151,10 +153,8 @@ callback : function(pError) { var lName; - if (pError) { - Util.log(pError); - main.sendError(pParams, pError); - } + if (pError) + sendError(pParams, pError); else { lName = path.basename(p.name); sendMsg(pParams, 'save', lName); @@ -166,17 +166,17 @@ case 'DELETE': if (lQuery === 'dir') fs.rmdir(p.name, function(pError){ - if (!pError) - sendMsg(pParams, 'delete', p.name); + if (pError) + sendError(pParams, pError); else - main.sendError(pParams, pError); + sendMsg(pParams, 'delete', p.name); }); else if (lQuery === 'files') { getBody(p.request, function(pBody) { var lFiles = Util.parseJSON(pBody), n = lFiles.length, lDir = p.name, - log = Util.retExec(Util.log), + log = Util.log, lAssync = 0; function stat(pStat) { @@ -190,8 +190,8 @@ ++lAssync; if (p.error){ - main.sendError(pParams, p.error); - Util.log(p.error); + sendError(pParams, p.error); + log(p.error); } else if (p.data.isDirectory()) @@ -216,10 +216,10 @@ }); }else fs.unlink(p.name, function(pError) { - if (!pError) - sendMsg(pParams, 'delete', p.name); + if (pError) + sendError(pParams, pError); else - main.sendError(pParams, pError); + sendMsg(pParams, 'delete', p.name); }); break; @@ -247,10 +247,6 @@ }; send(p); break; - - case 'proxy': - - break; case 'zip': main.sendFile(pParams); @@ -281,7 +277,9 @@ * @param pParams {command, method, body, requrest, response} */ function onPUT(pParams) { - var lRet = main.checkParams(pParams, ['body']); + var name, data, json, config, + lRet = main.checkParams(pParams, ['body']); + if (lRet) { var p = pParams, lCmd = p.command, @@ -301,22 +299,22 @@ main.child_process.exec(p.body, function(pError, pStdout, pStderr) { var lError = pError || pStderr; if (!lError) - main.sendResponse(pParams, pStdout); + sendResponse(pParams, pStdout); else - main.sendError(pParams, lError); + sendError(pParams, lError); }); break; case 'mv': if( Util.checkObjTrue(lFiles, ['from', 'to']) ) fs.rename(lFiles.from, lFiles.to, function(pError) { - if(!pError) - main.sendResponse(pParams); + if (pError) + sendError(pParams, pError); else - main.sendError(pParams, pError); + sendResponse(pParams); }); else - main.sendError(pParams, p.data); + sendError(pParams, p.data); break; case 'cp': @@ -326,13 +324,13 @@ to : lFiles.to, callback : function(pError) { if (pError) - main.sendError(pParams, pError); + sendError(pParams, pError); else sendMsg(pParams, 'copy', lFiles.to); } }); else - main.sendError(pParams, p.data); + sendError(pParams, p.data); break; case 'zip': @@ -345,7 +343,7 @@ var lName; if (pError) - main.sendError(pParams, pError); + sendError(pParams, pError); else { lName = path.basename(lFiles.from); sendMsg(pParams, 'zip', lName); @@ -353,7 +351,24 @@ } }); else - main.sendError(pParams, p.data); + sendError(pParams, p.data); + break; + + case 'config': + config = main.config; + + for (name in lFiles) + config[name] = lFiles[name]; + + json = Util.stringifyJSON(config) + '\n'; + + fs.writeFile(JSONDIR + 'config.json', json, function(error) { + if (error) + sendError(pParams, error); + else + sendMsg(pParams, 'config', name); + }); + break; default: @@ -385,7 +400,7 @@ function sendMsg(pParams, pMsg, pName) { var msg = CloudFunc.formatMsg(pMsg, pName); - main.sendResponse(pParams, msg); + sendResponse(pParams, msg); } })(); diff --git a/lib/server/socket.js b/lib/server/socket.js index 04dd4412..32fa379c 100644 --- a/lib/server/socket.js +++ b/lib/server/socket.js @@ -1,6 +1,6 @@ /* module make possible connectoin thru socket.io on a server */ -(function(){ +(function() { 'use strict'; var main = global.cloudcmd.main, @@ -39,10 +39,10 @@ * function listen on servers port * @pServer {Object} started server object */ - exports.listen = function(pServer){ + exports.listen = function(pServer) { var lRet, lListen, lConnNum, lMsg, lConn_func; - if(io){ + if (io) { lListen = io.listen(pServer), lConnNum = 0; @@ -63,18 +63,23 @@ lListen.set('transports', [ 'websocket', - 'flashsocket', 'htmlfile', 'xhr-polling', 'jsonp-polling' ]); - lRet = lListen.sockets.on('connection', function (socket){ + lRet = lListen.sockets.on('connection', function (socket) { + var lJSON; ++lConnNum; if(!OnMessageFuncs[lConnNum]) { - lMsg = log(lConnNum, 'connected'); - socket.send('{"stdout":"' + lMsg + '"}'); + lMsg = log(lConnNum, 'connected\n'); + lJSON = { + stdout : lMsg + }; + lMsg = Util.stringifyJSON(lJSON); + + socket.send(lMsg); OnMessageFuncs[lConnNum] = onMessage(lConnNum, socket); lConn_func = OnMessageFuncs[lConnNum]; @@ -93,7 +98,7 @@ return lRet; }; - function disconnect(pParams){ + function disconnect(pParams) { var lConnNum, lRet = Util.checkObj(pParams, ['params']); if(lRet) { @@ -112,17 +117,17 @@ * * @param pConnNum, pSocket */ - function onMessage(pConnNum, pSocket){ + function onMessage(pConnNum, pSocket) { return function(pCommand) { var lMsg, lJSON, lWinCommand, lExec_func, lDir, - lHome, lError, lRet; + lHome, lError, lRet, lExecSymbols, isContain; Util.log('#' + pConnNum + ': ' + pCommand); - if( Util.isContainStrAtBegin(pCommand, CLOUDCMD) ) { + if (Util.isContainStrAtBegin(pCommand, CLOUDCMD)) { pCommand = Util.removeStr(pCommand, CLOUDCMD); - if( Util.isContainStrAtBegin(pCommand, ' ') ){ + if( Util.isContainStrAtBegin(pCommand, ' ') ) { pCommand = Util.removeStr(pCommand, ' '); if( Util.isContainStrAtBegin(pCommand, 'update') && update ) @@ -154,7 +159,7 @@ if ( Util.isContainStr(lDir, '~') ) lDir = Util.replaceStr(lDir, '~', lHome); - lError = Util.tryCatchLog(function(){ + lError = Util.tryCatchLog(function() { process.chdir(lDir); }); @@ -176,7 +181,7 @@ * change code page to unicode becouse * windows use unicode on non English versions */ - if(WIN32){ + if(WIN32) { lWinCommand = pCommand.toUpperCase(); if( Win32Commands.indexOf(lWinCommand) >= 0 ) @@ -186,9 +191,14 @@ if(!ClientFuncs[pConnNum]) ClientFuncs[pConnNum] = getExec(pSocket, pConnNum); - lExec_func = ClientFuncs[pConnNum]; + lExec_func = ClientFuncs[pConnNum]; + lExecSymbols = ['*','#', '&', '{', '}', '|', '\'', '"']; + isContain = Util.isContainStr(pCommand, lExecSymbols); - exec(pCommand, lExec_func); + if (pCommand[0] === ' ' || isContain) + exec(pCommand, lExec_func); + else + getSpawn(pSocket, pConnNum, pCommand); } }; } @@ -198,24 +208,26 @@ * function send result of command to client * @param pSocket */ - function getExec(pSocket, pConnNum){ + function getExec(pSocket, pConnNum) { return function(pError, pStdout, pStderr) { var lErrorStr, lExecStr, lExec, lError = pStderr || pError; - - if (lError) - if ( Util.isString(lError) ) + if (lError) { + if (Util.isString(lError)) lErrorStr = lError; else - lErrorStr = Util.stringifyJSON( lError ); + lErrorStr = lError.toString(); + + lErrorStr = Util.addNewLine(lErrorStr); + } lExec = { stdout : pStdout, - stderr : lError + stderr : lErrorStr || lError }; - lExecStr = JSON.stringify(lExec); + lExecStr = Util.stringifyJSON(lExec); log(pConnNum, pError, 'error'); log(pConnNum, pStderr, 'stderror'); @@ -224,7 +236,38 @@ }; } - function log(pConnNum, pStr, pType){ + function getSpawn(pSocket, pConnNum, pCommand) { + var send, cmd, spawn, + args = pCommand.split(' '); + + pCommand = args.shift(); + + spawn = main.child_process.spawn; + cmd = spawn(pCommand, args); + send = function(data, isError) { + var lExecStr, + lExec = {}, + msg = data.toString(); + + if (isError) + lExec.stderr = msg; + else + lExec.stdout = msg; + + lExecStr = JSON.stringify(lExec); + pSocket.send(lExecStr); + }; + + cmd.stdout.on('data', send); + + cmd.stderr.on('data', function(data) { + send(data, true); + }); + + cmd.on('error', Util.retFalse); + } + + function log(pConnNum, pStr, pType) { var lRet, lType = ' '; if (pStr) { diff --git a/lib/util.js b/lib/util.js index 9ed142a2..5918902f 100644 --- a/lib/util.js +++ b/lib/util.js @@ -12,30 +12,54 @@ Util = exports || {}; Util.asyncCall = function(pFuncs, pOnLoad, pContext) { var i, element, name, func, - n = pFuncs.length, + funcsCount = pFuncs.length, count = 0, data = []; - for (i = 0; i < n; i++) { + for (i = 0; i < funcsCount; i++) { func = pFuncs[i]; callCheckFunc(i, func); } function checkFunc(pNum, pData) { - ++count; - data[pNum] = pData; + var i, m = pData.length, + params = []; - if (count === n) + ++count; + + if (m >= 2) { + for (i = 0; i < m; i++) + params[i] = pData[i]; + + data[pNum] = params; + } else + data[pNum] = pData[0]; + + if (count === funcsCount) pOnLoad.apply(pContext, data); } function callCheckFunc(pNum, pFunc) { - Util.exec(pFunc, function(pData){ - checkFunc(pNum, pData); + Util.exec(pFunc, function() { + checkFunc(pNum, arguments); }); } }, + /** + * ad new line (if it's not) + * @param {string} pText + */ + Util.addNewLine = function(pText){ + var lNewLine = '', + n = pText && pText.length; + + if(n && pText[n-1] !== '\n') + lNewLine = '\n'; + + return pText + lNewLine; + }; + /** setting function context * @param {function} pFunction * @param {object} pContext @@ -119,6 +143,7 @@ Util = exports || {}; var lProp = pPropArr[i]; lRet = pObj.hasOwnProperty( lProp ); if (!lRet) { + console.trace(); Util.logError(lProp + ' not in Obj!'); Util.log(pObj); break; @@ -152,6 +177,7 @@ Util = exports || {}; lRet = pObj[lProp]; if (!lRet) { + console.trace(); Util.logError(lProp + ' not true!'); Util.log(pObj); break; @@ -171,15 +197,10 @@ Util = exports || {}; */ Util.copyObj = function(pFromObj, pToObj, pProps) { var lRet = pToObj || pProps || {}, - copy = function(name, obj) { - var value = obj[name]; - - if (value) - pToObj[name] = obj[name]; - }, + forIn = function(obj) { Util.forIn(obj, function(name) { - copy(name, obj); + pToObj[name] = obj[name]; }); }; @@ -395,7 +416,7 @@ Util = exports || {}; lShift = Util.bind([].shift, lArg), lJoin = Util.bind([].join, lArg); - if (lConsole && lArg.length) { + if (lConsole && lArg.length && lArg[0]) { lUnShift(lDate); lConsole.log.apply(lConsole, lArg); lShift(); diff --git a/package.json b/package.json index cbdedebf..e27a1069 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "cloudcmd", - "version": "0.5.0", + "version": "0.6.0", "author": "coderaiser (https://github.com/coderaiser)", "description": "Cloud Commander - file manager with console and editor", - "homepage": "https://github.com/coderaiser/cloudcmd", + "homepage": "http://cloudcmd.io", "repository": { "type": "git", "url": "git://github.com/coderaiser/cloudcmd.git" @@ -15,14 +15,14 @@ "test": "sh ./test/test.sh", "start": "cloudcmd.js" }, - "node": "0.6.17", "subdomain": "cloudcmd", "dependencies": { - "dropbox": "0.10.1", - "minify": "0.2.2", - "socket.io": "0.9.16" + "dropbox": "0.10.2", + "minify": "0.2.3", + "socket.io": "0.9.16", + "express": "3.4.x" }, - "devDependencies": {}, + "license": "MIT", "engines": { "node": ">=0.4.x" }, diff --git a/shell/log.sh b/shell/log.sh index 7f79a617..2f42a8e5 100755 --- a/shell/log.sh +++ b/shell/log.sh @@ -3,7 +3,7 @@ if test -z $1 then echo "log.sh " else - git log $1..HEAD --pretty=format:"* %s" --grep feature - git log $1..HEAD --pretty=format:"* %s" --grep fix - git log $1..HEAD --pretty=format:"* %s" --grep refactor + git log $1..HEAD --pretty=format:"- %s" --grep feature + git log $1..HEAD --pretty=format:"- %s" --grep fix + git log $1..HEAD --pretty=format:"- %s" --grep refactor fi \ No newline at end of file