diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..0f2a8f47 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,20 @@ +Version 0.1.1 + +* 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 css-lint to travis ci. + +* 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 +post-processing functions passed like this {'client.js': function(){}} + +* Added ability to read file data from Minify Cache, without writing to disk + +* Changed the passing MoreProcessing agrument to jsScripts function Minify module, +no it passes with a file name, and js file name writing only once. \ No newline at end of file diff --git a/README.md b/README.md index 42b5024d..49b19bb8 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,19 @@ Installing **Cloud Commander** installing is very easy. All you need it's just clone repository from github. Install and start, just 3 commands: - git clone git://github.com/coderaiser/cloudcmd.git - cd cloudcmd - node server.js + git clone git://github.com/coderaiser/cloudcmd.git --recursive +Starting +--------------- +To start **Cloud Commander** only one command neaded: + node server.js +After thet Cloud Commander reads config file **config.json** and start server +on 31337 port, if none of port varibles(*cloud9*, *cloudfoundry* and *nodester*) +isn't exist. +Then type in browser + http://127.0.0.1:31337 +or + http://localhost:31337 Updating --------------- **Cloud Commander** is very buggy and alfa so it's very often updated. For update @@ -56,11 +65,29 @@ you can just type in cloudcmd directory: Additional modules: --------------- -**Cloud Commander** not using additional modules for main functionality. +**Cloud Commander's Server Side** not using additional modules for main functionality. But for minification and optimization tricks optional can be -assingned (and installed) module: [Minify] (https://github.com/coderaiser/minify "Minify") +assingned (and installed) module: [Minify] (https://github.com/coderaiser/minify "Minify"). Install addtitional modules: git submodule init - git submodule update \ No newline at end of file + git submodule update + +**Cloud Commander's Client Side** use module jquery for ajaxing. +We could not use this module, but this way is fast: +- google cdn +- gzip +- cache + +Perhaps in the future, it will not be used, but so far it has no effect on +start loading of Cloud Commander Client Side and do things fast and stable +it is using now. + +Contributing +--------------- +If you would like to contribute - send pull request to dev branch. +Getting dev version of **Cloud Commander**: + + git clone cloudcmd --recursive + git checkout dev \ No newline at end of file diff --git a/client.js b/client.js index a071c62d..cadd6682 100644 --- a/client.js +++ b/client.js @@ -133,7 +133,7 @@ CloudClient.Cache.clear=(function(){ CloudClient.keyBinding=(function(){ /* loading keyBinding module and start it */ CloudClient.jsload(CloudClient.LIBDIRCLIENT+'keyBinding.js',function(){ - CloudCommander.keyBinding(); + CloudCommander.keyBinding(); }); }); @@ -282,7 +282,6 @@ CloudClient._currentToParent = (function(pDirName){ var LoadingImage; var ErrorImage; -var $; var CloudFunc; /* Конструктор CloudClient, который * выполняет весь функционал по @@ -298,28 +297,25 @@ CloudClient.init=(function() if(lTitle.length>0)lTitle[0].textContent='Cloud Commander'; /* загружаем jquery: */ - CloudClient.jsload('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',function(){ - /* сохраняем переменную jQuery себе в область видимости */ - $=window.jQuery; - if(!window.jQuery)CloudClient.jsload('jquery.min.js', - function(){ - $=window.jQuery; - }); + CloudClient.jsload('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',{ + onerror: function(){ + CloudClient.jsload('lib/client/jquery.js'); + } }); /* загружаем общие функции для клиента и сервера*/ CloudClient.jsload(CloudClient.LIBDIR+'cloudfunc.js',function(){ - /* берём из обьекта window общий с сервером функционал */ - CloudFunc=window.CloudFunc; + /* берём из обьекта window общий с сервером функционал */ + CloudFunc=window.CloudFunc; - /* меняем ссылки на ajax'овые*/ - CloudClient._changeLinks(CloudFunc.LEFTPANEL); - CloudClient._changeLinks(CloudFunc.RIGHTPANEL); - - /* устанавливаем переменную доступности кэша*/ - CloudClient.Cache.isAllowed(); - /* Устанавливаем кэш корневого каталога */ - if(!CloudClient.Cache.get('/'))CloudClient.Cache.set('/',CloudClient._getJSONfromFileTable()); + /* меняем ссылки на ajax'овые*/ + CloudClient._changeLinks(CloudFunc.LEFTPANEL); + CloudClient._changeLinks(CloudFunc.RIGHTPANEL); + + /* устанавливаем переменную доступности кэша*/ + CloudClient.Cache.isAllowed(); + /* Устанавливаем кэш корневого каталога */ + if(!CloudClient.Cache.get('/'))CloudClient.Cache.set('/',CloudClient._getJSONfromFileTable()); } ); @@ -570,7 +566,9 @@ CloudClient._createFileTable = function(pElem,pJSON) * загружает файл с src. * @pName - название тэга * @pSrc - путь к файлу - * @pFunc - функци + * @pFunc - обьект, содержаий одну из функций + * или сразу две onload и onerror + * {onload: function(){}, onerror: function();} * @pStyle - стиль * @pId - id * @pElement - элемент, дочерним которо будет этот @@ -589,16 +587,24 @@ CloudClient._anyload = function(pName,pSrc,pFunc,pStyle,pId,pElement) { var element = document.createElement(pName); element.src = pSrc; - element.id=lID; + element.id=lID; if(arguments.length>=3){ - element.onload=pFunc; + /* if passed arguments function + * then it's onload by default + */ + if(typeof pFunc === 'function'){ + element.onload=pFunc; + /* if object - then onload or onerror */ + }else if (typeof pFunc === 'object'){ + if(pFunc.onload)element.onload = pFunc.onload; + if(pFunc.onerror)element.onerror=pFunc.onerror; + } if(arguments.length>=4){ element.style.cssText=pStyle; } - } - //document.body - pElement.appendChild(element); - return element;//'elem '+src+' loaded'; + } + pElement.appendChild(element); + return element; } /* если js-файл уже загружен * запускаем функцию onload @@ -683,20 +689,22 @@ CloudClient._getJSONfromFileTable=function() * можна заменить на любой другой код */ if(!document.getElementsByClassName){ - CloudClient.jsload('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',function(){ - /* сохраняем переменную jQuery себе в область видимости */ - document.getElementsByClassName=function(pClassName){ - return $('.'+pClassName)[0]; - }; - $=window.jQuery; - if(!window.jQuery)CloudClient.jsload('jquery.min.js', - function(){ - $=window.jQuery; - document.getElementsByClassName=function(pClassName){ - return $('.'+pClassName)[0]; - }; - }); - }); + CloudClient.jsload('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',{ + onload: function(){ + /* сохраняем переменную jQuery себе в область видимости */ + document.getElementsByClassName=function(pClassName){ + return window.jQuery('.'+pClassName)[0]; + }; + }, + onerror: function(){ + CloudClient.jsload(CloudClient.LIBDIRCLIENT + 'jquery.js', + function(){ + document.getElementsByClassName=function(pClassName){ + return window.jQuery('.'+pClassName)[0]; + }; + }); + } + }); } return CloudClient; diff --git a/lib/server/minify b/lib/server/minify index 9a18a323..cc198d1d 160000 --- a/lib/server/minify +++ b/lib/server/minify @@ -1 +1 @@ -Subproject commit 9a18a3234de35fed52ebb5d5b6211503ad774934 +Subproject commit cc198d1df010fb6db406383293e8234c5c6a1ede diff --git a/package.json b/package.json index c3804fe5..9a2f1a0c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "0.1.0", + "version": "0.1.1", "author": "coderaiser (https://github.com/coderaiser)", "description": "two-panels file manager, totally writed on js", "homepage": "http://github.com/coderaiser/cloudcmd", diff --git a/server.js b/server.js index dc7efa69..f3c17b50 100644 --- a/server.js +++ b/server.js @@ -63,7 +63,7 @@ var CloudServer={ CSSDIR :'./css', Port :31337, /* server port */ - IP :'127.0.0.1' + IP :'127.0.0.1' }; /* @@ -157,40 +157,47 @@ CloudServer.Minify={ try{ lMinify = require(CloudServer.LIBDIRSERVER+'/minify'); }catch(pError){ - console.log('Could not minify withou minify module\n' + + return console.log('Could not minify withou minify module\n' + 'for fixing type:\n' + 'git submodule init\n' + 'git submodule update'); } + /* + * temporary changed dir path, + * becouse directory lib is write + * protected by others by default + * so if node process is started + * from other user (root for example + * in nodester) we can not write + * minified versions + */ this.MinFolder = '/' + lMinify.MinFolder; + var lMinFolder=this.MinFolder; + + /* post processing function for file + * client.js + */ + var lPostProcessing_f = function(pFinalCode){ + console.log('file name of ' + + 'cloudfunc.js' + + ' in ' + + 'client.js' + + ' changed. size:', + (pFinalCode = pFinalCode + .replace('cloudfunc.js','cloudfunc.min.js') + .replace('keyBinding.js','keyBinding.min.js') + .replace('/lib/', lMinFolder) + .replace('/lib/client/', lMinFolder)).length); + return pFinalCode; + }; this.done.js=this._allowed.js? - lMinify.jsScripts(['client.js', + lMinify.jsScripts([{ + 'client.js': lPostProcessing_f}, 'lib/cloudfunc.js', 'lib/client/keyBinding.js'], - {Name: 'client.js', - /* - * temporary changed dir path, - * becouse directory lib is write - * protected by others by default - * so if node process is started - * from other user (root for example - * in nodester) we can not write - * minified versions - */ - Func: function(pFinalCode){ - console.log('file name of ' + - 'cloudfunc.js' + - ' in ' + - 'client.js' + - ' changed. size:', - (pFinalCode = pFinalCode - .replace('cloudfunc.js','cloudfunc.min.js') - .replace('keyBinding.js','keyBinding.min.js') - .replace('/lib/', this.MinFolder) - .replace('/lib/client/', this.MinFolder)).length); - }}) - :false; + true) + :false; this.done.html=this._allowed.html? lMinify.html(CloudServer.INDEX):false; @@ -198,14 +205,17 @@ CloudServer.Minify={ this.done.css=this._allowed.css? lMinify.cssStyles([CloudServer.CSSDIR + '/style.css', CloudServer.CSSDIR + '/reset.css'], - this._allowed.img):false; + this._allowed.img):false; + + this.Cache = lMinify.Cache; } }), /* свойство показывающее случилась ли ошибка*/ done:{js: false,css: false, html:false}, /* minification folder name */ - MinFolder:'' + MinFolder :'', + Cache :{} }; @@ -276,7 +286,7 @@ CloudServer.init=(function(){ */ CloudServer.Minify.setAllowed(CloudServer.Config.minification); /* Если нужно минимизируем скрипты */ - CloudServer.Minify.doit(); + CloudServer.Minify.doit(); }); @@ -406,7 +416,6 @@ CloudServer._controller=function(pReq, pRes) var lNoJS_s=CloudFunc.NOJS; var lFS_s=CloudFunc.FS; - console.log(pathname); if(pathname!=='/favicon.ico') { console.log("request for " + pathname + " received..."); @@ -435,18 +444,43 @@ CloudServer._controller=function(pReq, pRes) * не сжатый - в обратном случае */ var lFileData=CloudServer.Cache.get(CloudServer.Gzip?(lName+'_gzip'):lName); - + console.log(Path.basename(lName)); + + var lMinify=CloudServer.Minify; + + /* object thet contains information + * about the source of file data + */ + var lFromCache_o={'cache': true}; + + /* if cache is empty and Cache allowed and Minify_allowed + * and in Minifys cache is files, so save it to + * CloudServer cache + */ + if(!lFileData && + lMinify._allowed){ + console.log('trying to read data from Minify.Cache'); + lFromCache_o.cache=false; + lFileData = CloudServer.Minify.Cache[ + Path.basename(lName)]; + } var lReadFileFunc_f=CloudServer.getReadFileFunc(lName); /* если там что-то есть передаём данные в функцию * readFile */ - if(lFileData){ - console.log('readed from cache'); + if(lFileData){ + /* if file readed not from cache - he readed from minified cache */ + if(lFromCache_o.cache===false) + lFromCache_o.minify=true; + else + lFromCache_o.minify=false; + + console.log(lName + ' readed from cache'); /* передаём данные с кэша, * если gzip включен - сжатые * в обратном случае - несжатые */ - lReadFileFunc_f(undefined,lFileData,true); + lReadFileFunc_f(undefined,lFileData,lFromCache_o); } else Fs.readFile(lName,lReadFileFunc_f); @@ -674,11 +708,13 @@ CloudServer._readDir=function (pError, pFiles) */ CloudServer.getReadFileFunc = function(pName){ /* - * @pError - ошибка - * @pData - данные - * @pFromFile - прочитано с файла bool + * @pError - ошибка + * @pData - данные + * @pFromCache_o - прочитано с файла, + * или из одного из кешей + * Пример {cache: false, minify: true} */ - var lReadFile=function(pError,pData,pFromCache_b){ + var lReadFile=function(pError, pData, pFromCache_o){ if (!pError){ console.log('file ' + pName + ' readed'); @@ -686,7 +722,7 @@ CloudServer.getReadFileFunc = function(pName){ * если их нет в кэше - * сохраняем */ - if(!pFromCache_b && CloudServer.Cache.isAllowed) + if(pFromCache_o && !pFromCache_o.cache && CloudServer.Cache.isAllowed) CloudServer.Cache.set(pName,pData); /* если кэш есть * сохраняем его в переменную @@ -697,7 +733,7 @@ CloudServer.getReadFileFunc = function(pName){ var lHeader=CloudServer.generateHeaders(pName,CloudServer.Gzip); /* если браузер поддерживает gzip-сжатие - сжимаем данные*/ - if(CloudServer.Gzip &&!pFromCache_b){ + if( CloudServer.Gzip && !(pFromCache_o && pFromCache_o.cache) ){ /* сжимаем содержимое */ Zlib.gzip(pData,CloudServer.getGzipDataFunc(lHeader,pName)); } diff --git a/test/test.sh b/test/test.sh index c0c6414b..66f739a5 100644 --- a/test/test.sh +++ b/test/test.sh @@ -1,4 +1,5 @@ #!/bin/sh +#linting js files npm i jshint -g echo "jshint server.js client.js lib/cloudfunc.js" jshint --config ./.jshintrc ./server.js ./client.js @@ -7,5 +8,9 @@ jshint --config ./.jshintrc ./lib/cloudfunc.js ./lib/server/minify/minify.js ./l echo "jshint ./package.json ./config.json" jshint --config ./.jshintrc ./package.json ./config.json npm i uglify-js clean-css html-minifier css-b64-images +#linting css files +npm i recess -g +echo "recess ./css/*.css" +recess css/*.css node server.js test ls ./min \ No newline at end of file