full reload

This commit is contained in:
coderaiser 2012-07-05 04:08:15 -04:00
parent 0d6327b05d
commit dc23669f83
18 changed files with 2952 additions and 0 deletions

5
lib/README.md Normal file
View file

@ -0,0 +1,5 @@
Cloud Commander Libraries
===============
**Cloud Commander Libraries** - dir thet contains scripts, thet uses
on client and server side, and modules, wich is not necessary
for CloudCommander work, but they adds some sugor.

248
lib/client/keyBinding.js Normal file
View file

@ -0,0 +1,248 @@
var CloudCommander;
var CloudFunc;
CloudCommander.keyBinding=(function(){
"use strict";
var key_event=function(event){
/*
* Делаем допущение что перезагружать Cloud Commander
* посетителям не придёться, в любом случае, параметр
* должен быть опциональным и должна быть возможность
* его отключить. В любом случае, кроме хакеров и
* разработчиков (при чём сомнительно, что хакерам
* это пригодиться), функция перезагрузки никому не
* нужна, поскольку загружать весь дополнительный
* контент снова (js,css) в готовой версии нет
* необходимости.
*
*/
//console.log(event.keyCode);
var lCurrentFile;
var lName;
/* если клавиши можно обрабатывать*/
if(CloudCommander.keyBinded){
/* если нажали таб:
* переносим курсор на
* правую панель, если
* мы были на левой и
* наоборот
*/
if(event.keyCode===9){
console.log('Tab pressed');
try{
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE)[0];
}catch(error){console.log(error);}
}
/* навигация по таблице файлов*/
/* если нажали клавишу вверх*/
else if(event.keyCode===38){
/* получаем выдленный файл*/
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE);
/* если ненайдены выделенные файлы - выходим*/
if(lCurrentFile.length===0)return;
lCurrentFile=lCurrentFile[0];
/* если это строка существет и
* если она не заголовок
* файловой таблицы
*/
if(lCurrentFile.previousSibling &&
lCurrentFile.previousSibling.className!=='fm_header' ){
/* убираем выделение с текущего элемента */
lCurrentFile.className='';
/* и выделяем предыдущую строку*/
lCurrentFile.previousSibling.className=CloudCommander.CURRENT_FILE;
event.preventDefault();
}
}
/* если нажали клавишу в низ*/
else if(event.keyCode===40){
/* получаем выдленный файл*/
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE);
/* если ненайдены выделенные файлы - выходим*/
if(lCurrentFile.length===0)return;
lCurrentFile=lCurrentFile[0];
/* если это не последняя строка */
if(lCurrentFile.nextSibling){
/* убираем с него выделение */
lCurrentFile.className='';
/* выделяем следующую строку*/
lCurrentFile.nextSibling.className=CloudCommander.CURRENT_FILE;
event.preventDefault();
}
}
/* если нажали клавишу page up или Home
* переходим к самому верхнему
* элементу
*/
else if(/*event.keyCode===33 ||*/ event.keyCode===36){
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE)[0];
/* убираем выделение с текущего файла*/
lCurrentFile.className='';
/* получаем первый элемент*/
lCurrentFile.parentElement.firstElementChild
/* пропускаем путь и заголовки столбиков*/
.nextElementSibling.nextElementSibling
/* выделяем верхий файл */
.className=CloudCommander.CURRENT_FILE;
}
/* если нажали клавишу page down или End
* выделяем последний элемент
*/
else if(/*event.keyCode===34 ||*/ event.keyCode===35){
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE)[0];
/* снимаем выделение с текущего файла*/
lCurrentFile.className='';
/* выделяем самый нижний файл */
lCurrentFile.parentElement.lastElementChild.className=CloudCommander.CURRENT_FILE;
}
/* если нажали Enter - открываем папку*/
else if(event.keyCode===13){
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE);
/* если ненайдены выделенные файлы - выходим*/
if(!lCurrentFile.length)return;
lCurrentFile=lCurrentFile[0];
/* из него достаём спан с именем файла*/
lName=lCurrentFile.getElementsByClassName('name');
/* если нету (что вряд ли) - выходим*/
if(!lName)return false;
/* достаём все ссылки*/
var lATag=lName[0].getElementsByTagName('a');
/* если нету - выходим */
if(!lATag)return false;
/* получаем ссылку на каталог,
* что на уровень выше
*/
/* получаем имя каталога в котором находимся*/
var lHref;
try{
lHref=lCurrentFile.parentElement.getElementsByClassName('path')[0].textContent;
}catch(error){console.log('error');}
lHref=CloudFunc.removeLastSlash(lHref);
var lSubstr=lHref.substr(lHref,lHref.lastIndexOf('/'));
lHref=lHref.replace(lSubstr+'/','');
/* вызываем ajaxload привязанный через changelinks
* пробулем нажать на ссылку, если не получиться
* (opera, ie), вызываем событие onclick,
* которое пока не прописано у файлов
*/
if(lCurrentFile.onclick)lCurrentFile.onclick(true);
else try{
lATag[0].click();
}
catch(error){
console.log(error);
}
}
/* если нажали <ctr>+r */
else if(event.keyCode===82 &&
event.ctrlKey){
console.log('<ctrl>+r pressed');
console.log('reloading page...');
console.log('press <alt>+q to remove all key-handlers');
/* обновляем страницу, */
/* Загружаем содержимое каталога
* при этом данные берём всегда из
* сервера, а не из кэша
* (обновляем кэш)
*/
/* Программно нажимаем на кнопку перезагрузки
* содержимого каталога
*/
var lRefreshIcon=document.getElementsByClassName(CloudFunc.REFRESHICON);
if(lRefreshIcon)lRefreshIcon=lRefreshIcon[0];
if(lRefreshIcon){
/* находим файл который сейчас выделен */
lCurrentFile=document.getElementsByClassName(CloudCommander.CURRENT_FILE);
if(lCurrentFile.length>0)lCurrentFile=lCurrentFile[0];
/* получаем название файла*/
var lSelectedName=lCurrentFile.getElementsByTagName('a')[0].textContent;
/* если нашли элемент нажимаем него
* а если не можем - нажимаем на
* ссылку, на которую повешен eventHandler
* onclick
*/
if(lRefreshIcon.click)lRefreshIcon.parentElement.click();
else lRefreshIcon.parentElement.onclick();
/* перебираем файлы левой панели
* в поисках подсвеченого файла
*/
var lLeft=document.getElementById('left');
if(lLeft){
/* перебираем все файлы в панели */
var lLi=lLeft.getElementsByTagName('li');
lCurrentFile.className='';
/* начинаем с 2-ух, по скольку
* 0 - это путь
* 1 - это заголовок файловой таблицы
*/
for(var i=2;i<lLi.length;i++){
lName=lLi[i].getElementsByTagName('a')[0].textContent;
if(lSelectedName.length===lName.length &&
!lSelectedName.indexOf(lName)){
lLi[i].className=CloudCommander.CURRENT_FILE;
break;
}
}
}
event.preventDefault();//запрет на дальнейшее действие
}
}
/* если нажали <ctrl>+d чистим кэш */
else if(event.keyCode===68 &&
event.ctrlKey){
console.log('<ctrl>+d pressed');
console.log('clearing cache...');
console.log('press <alt>+q to remove all key-handlers');
var lClearCache=document.getElementById('clear-cache');
if(lClearCache && lClearCache.onclick)lClearCache.onclick();
event.preventDefault();//запрет на дальнейшее действие
}
/* если нажали <alt>+q
* убираем все обработчики
* нажатий клавиш
*/
else if(event.keyCode===81 &&
event.altKey){
//document.removeEventListener('keydown', key_event,false);
console.log('<alt>+q pressed');
console.log('<ctrl>+r reload key-handerl - removed');
console.log('<ctrl>+s clear cache key-handler - removed');
console.log('press <alt>+s to to set them');
/* обработчик нажатий клавиш снят*/
CloudCommander.keyBinded=false;
}
}
/* если нажали <alt>+s
* устанавливаем все обработчики
* нажатий клавиш
*/
else if(event.keyCode===83 &&
event.altKey){
/*
document.addEventListener('keydown', key_event,false);
*/
/* обрабатываем нажатия на клавиши*/
CloudCommander.keyBinded=true;
console.log('<alt>+s pressed');
console.log('<ctrl>+r reload key-handerl - set');
console.log('<ctrl>+s clear cache key-handler - set');
console.log('press <alt>+q to remove them');
}
return false;
};
/* добавляем обработчик клавишь */
if(document.addEventListener)
document.addEventListener('keydown', key_event,false);
else document.onkeypress=key_event;
/* клавиши назначены*/
CloudCommander.keyBinded=true;
});

504
lib/cloudfunc.js Normal file
View file

@ -0,0 +1,504 @@
"use strict";
/* Модуль, содержащий функции, которые будут работать
* и на клиенте и на сервере
*
* Правила названий:
* varName - имя функции
* lVarName - имя локальной переменной
* pVarName - имя параметра
* fVarName - имя функции созданной внутри функции
* VARNAME - имя константы
*
* Типы переменных:
* varNameS - строка
* varNameN - число
* varNameO - обьект
* varNameM - массив
*/
var CloudFunc={
/* Путь с которым мы сейчас работаем */
Path :'',
/* КОНСТАНТЫ (общие для клиента и сервера)*/
/* название программы */
NAME :'Cloud Commander',
/* если в ссылке будет эта строка -
* в браузере js отключен
*/
NOJS : '/no-js',
FS : '/c/f/s',
/* название css-класа кнопки обновления файловой структуры*/
REFRESHICON : 'refresh-icon',
/* id панелей с файлами */
LEFTPANEL : 'left',
RIGHTPANEL : 'right'
/* name of direcotory with libs */
};
/*
* Функция убирает последний слеш,
* если он - последний символ строки
*/
CloudFunc.removeLastSlash = function(pPath){
if(typeof pPath==='string')
return (pPath.lastIndexOf('/')===pPath.length-1)?
pPath.substr(pPath, pPath.length-1):pPath;
else return pPath;
};
/*
* Функция меняет код символа пробела на пробел
* в переданной строке
* @pPath - строка
*/
CloudFunc.replaceSpaces = function(pPath){
if(pPath.indexOf('%20')>0){
do{
pPath=pPath.replace('%20',' ');
}while(pPath.indexOf('%20')>0);
}
return pPath;
};
/* Функция возвращает заголовок веб страницы */
CloudFunc.setTitle = function(){
return CloudFunc.Path===''?CloudFunc.NAME:
CloudFunc.Path +
' - ' +
CloudFunc.NAME;
};
/* Функция переводит права из цыфрового вида в символьный
* @pPerm_s - строка с правами доступа
* к файлу в 8-миричной системе
*/
CloudFunc.convertPermissionsToSymbolic= function(pPerm_s){
/*
S_IRUSR 0000400 protection: readable by owner
S_IWUSR 0000200 writable by owner
S_IXUSR 0000100 executable by owner
S_IRGRP 0000040 readable by group
S_IWGRP 0000020 writable by group
S_IXGRP 0000010 executable by group
S_IROTH 0000004 readable by all
S_IWOTH 0000002 writable by all
S_IXOTH 0000001 executable by all
*/
if(pPerm_s===undefined) return;
/* тип файла */
var lType=pPerm_s.charAt(0);
switch (lType-0) {
case 1: /* обычный файл */
lType='-';
break;
case 2: /* байт-ориентированное (символьное) устройство*/
lType='c';
break;
case 4: /* каталог */
lType='d';
break;
default:
lType='-';
}
/* оставляем последние 3 символа*/
pPerm_s=pPerm_s.length>5?pPerm_s.substr(3):pPerm_s.substr(2);
/* Рекомендации гугла советуют вместо string[3]
* использовать string.charAt(3)
*/
/*
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Standards_features#Standards_features
Always preferred over non-standards featuresFor
maximum portability and compatibility, always
prefer standards features over non-standards
features (e.g., string.charAt(3) over string[3]
and element access with DOM functions instead
of using an application-specific shorthand).
*/
/* Переводим в двоичную систему */
var lOwner=(pPerm_s[0]-0).toString(2);
var lGroup=(pPerm_s[1]-0).toString(2);
var lAll =(pPerm_s[2]-0).toString(2);
/*
console.log(lOwner+' '+lGroup+' '+lAll);
*/
/* переводим в символьную систему*/
var lPermissions=//lType+' '+
(lOwner[0]-0>0?'r':'-')+
(lOwner[1]-0>0?'w':'-')+
(lOwner[2]-0>0?'x':'-')+
' ' +
(lGroup[0]-0>0?'r':'-')+
(lGroup[1]-0>0?'w':'-')+
(lGroup[2]-0>0?'x':'-')+
' ' +
(lAll[0]-0>0?'r':'-')+
(lAll[1]-0>0?'w':'-')+
(lAll[2]-0>0?'x':'-');
/*
console.log(lPermissions);
*/
return lPermissions;
};
/* Функция конвертирует права доступа к файлам из символьного вида
* в цыфровой
*/
CloudFunc.convertPermissionsToNumberic= function(pPerm_s){
/* если передана правильная строка, конвертированная
* функциец convertPermissionsToSymbolic
*/
if(!pPerm_s || pPerm_s.length!==11)return pPerm_s;
var lOwner= (pPerm_s[0]==='r'?4:0) +
(pPerm_s[1]==='w'?2:0) +
(pPerm_s[2]==='x'?1:0);
var lGroup= (pPerm_s[4]==='r'?4:0) +
(pPerm_s[5]==='w'?2:0) +
(pPerm_s[6]==='x'?1:0);
var lAll = (pPerm_s[8]==='r'?4:0) +
(pPerm_s[9]==='w'?2:0) +
(pPerm_s[10]==='x'?1:0);
/* добавляем 2 цыфры до 5 */
return '00'+lOwner+lGroup+lAll;
};
/* Функция получает короткие размеры
* конвертируя байт в килобайты, мегабойты,
* гигайбайты и терабайты
* @pSize - размер в байтах
*/
CloudFunc.getShortedSize=function(pSize){
/* if pSize=0 - return it */
if(!pSize)return pSize;
/* Константы размеров, что используются
* внутри функции
*/
var l1BMAX=1024;
var l1KBMAX=1048576;
var l1MBMAX=1073741824;
var l1GBMAX=1099511627776;
var l1TBMAX=1125899906842624;
var lShorted;
if(pSize<l1BMAX)lShorted=pSize+'b';
else if(pSize<l1KBMAX)lShorted=(pSize/l1BMAX) .toFixed(2)+'kb';
else if(pSize<l1MBMAX)lShorted=(pSize/l1KBMAX).toFixed(2)+'mb';
else if(pSize<l1GBMAX)lShorted=(pSize/l1MBMAX).toFixed(2)+'gb';
else if(pSize<l1TBMAX)lShorted=(pSize/l1GBMAX).toFixed(2)+'tb';
return lShorted;
};
/* Функция парсит uid и имена пользователей
* из переданного в строке вычитаного файла /etc/passwd
* и возвращает массив обьектов имён и uid пользователей
* @pPasswd_s - строка, в которой находиться файл /etc/passwd
*/
CloudFunc.getUserUIDsAndNames=function(pPasswd_s){
var lUsers={name:'',uid:''};
var lUsersData=[];
var i=0;
do{
/* получаем первую строку */
var lLine=pPasswd_s.substr(pPasswd_s,pPasswd_s.indexOf('\n')+1);
if(lLine){
/* удаляем первую строку из /etc/passwd*/
pPasswd_s=pPasswd_s.replace(lLine,'');
/* получаем первое слово строки */
var lName=lLine.substr(lLine,lLine.indexOf(':'));
lLine=lLine.replace(lName+':x:','');
/* получаем uid*/
var lUID=lLine.substr(lLine,lLine.indexOf(':'));
if((lUID-0).toString()!=='NaN'){
lUsers.name=lName;
lUsers.uid=lUID;
lUsersData[i++]=lUsers;
console.log('uid='+lUID+' name='+lName);
}
}
}while(pPasswd_s!=='');
return lUsersData;
};
/* Функция получает адреса каждого каталога в пути
* возвращаеться массив каталогов
* @url - адрес каталога
*/
CloudFunc._getDirPath=function(url)
{
var folders=[];
var i=0;
do{
folders[i++]=url; url=url.substr(url,url.lastIndexOf('/'));
}while(url!=='');
/* сохраяем адрес предыдущего каталога */
/*
if(i>2){
if(folders[0].lastIndexOf('/')===folders[0].length)
LPrevDir=folders[1];
else LPrevDir=folders[2];
}else LPrevDir='/';
*/
/* ################################### */
/* Формируем ссылки на каждый каталог в пути */
var lHref='<a class=links href=';
var lTitle=' title=';
var _l='>';
var lHrefEnd='</a>';
var lHtmlPath;
/* путь в ссылке, который говорит
* что js отключен
*/
var lNoJS_s=CloudFunc.NOJS;
var lFS_s=CloudFunc.FS;
/* корневой каталог */
lHtmlPath=lHref+lFS_s+lNoJS_s+lTitle+'"/"'+_l+'/'+lHrefEnd;
for(i=folders.length-1;i>0;i--)
{
var lUrl=folders[i];
var lShortName=lUrl.replace(lUrl.substr(lUrl,lUrl.lastIndexOf('/')+1),'');
if(i!==1)
{
lHtmlPath+=lHref+lFS_s+lNoJS_s+lUrl+lTitle+lUrl+_l+lShortName+lHrefEnd+'/';
}
else
lHtmlPath+=lShortName+'/';
}
/* *** */
return lHtmlPath;
};
/*
* Функция ищет в имени файла расширение
* и если находит возвращает true
* @pName - получает имя файла
* @pExt - расширение
*/
CloudFunc.checkExtension=function(pName,pExt)
{
/* если длина имени больше
* длинны расширения -
* имеет смысл продолжать
*/
if(pName.length>pExt.length){
var lLength=pName.length; /* длина имени*/
var lExtNum=pName.lastIndexOf(pExt);/* последнее вхождение расширения*/
var lExtSub=lLength-lExtNum; /* длина расширения*/
/* если pExt - расширение pName */
if(lExtSub===pExt.length)
return true;
else
return false;
}
else return false;
};
/*
* Функция формирует заголовки столбиков
* @pFileTableTitles - массив названий столбиков
*/
CloudFunc._getFileTableHeader=function(pFileTableTitles)
{
var lHeader='<li class=fm_header>';
lHeader+='<span class=mini-icon></span>';
for(var i=0;i<pFileTableTitles.length;i++)
{
var lStr=pFileTableTitles[i];
lHeader+='<span class='+lStr+'>'+
lStr+
'</span>';
}
lHeader+='</li>';
return lHeader;
};
/*
* Функция строит таблицу файлв из JSON-информации о файлах
* @pJSON - информация о файлах
* @pKeyBinded - если клавиши назначены, выделяем верхний файл
* [{path:'путь',size:'dir'},
* {name:'имя',size:'размер',mode:'права доступа'}]
*/
CloudFunc.buildFromJSON=function(pJSON,pKeyBinded)
{
var files;
/*
* если пропарсить стандартными
* функциями нельзя -
* пробуем eval,
*/
/*
* Если мы на клиенте и нет JSON -
* через eval парсим.
* Если-же мы на сервере,
* или на клиенте всё есть
* парсим стандарным методом
*/
/* По скольку мы прописали заголовок application/json
* нет необходимости его конвертировать,
* но она есть, если мы вытягиваем данные из
* localStorage
*/
files=pJSON;
/* сохраняем путь каталога в котором мы сейчас находимся*/
var lPath=files[0].path;
/* сохраняем путь */
CloudFunc.Path=lPath;
/*
* Строим путь каталога в котором мы находимся
* со всеми подкаталогами
*/
var lHtmlPath=CloudFunc._getDirPath(lPath);
/* Убираем последний слэш
* с пути для кнопки обновить страницу
* если он есть
*/
var lRefreshPath=CloudFunc.removeLastSlash(lPath);
/* путь в ссылке, который говорит
* что js отключен
*/
var lNoJS_s=CloudFunc.NOJS;
var lFS_s=CloudFunc.FS;
var lFileTable='<li class=path>'+
'<span class="path_icon clear-cache" id=clear-cache title="clear cache (Ctrl+D)"></span>'+
'<a href="'+lFS_s+lNoJS_s+lRefreshPath+'">'+
'<span class="path_icon ' + CloudFunc.REFRESHICON + '"' +
' title="refresh (Ctrl+R)">' +
'</span>'+
'</a>'+
'<span>'+lHtmlPath+'</span>'+
'</li>';
var fileTableTitles=['name','size','owner','mode'];
lFileTable+=CloudFunc._getFileTableHeader(fileTableTitles);
/* Если мы не в корне */
if(lPath!=='/'){
/* ссылка на верхний каталог*/
var lDotDot;
/* убираем последний слеш и каталог в котором мы сейчас находимся*/
lDotDot=lPath.substr(lPath,lPath.lastIndexOf('/'));
lDotDot=lDotDot.substr(lDotDot,lDotDot.lastIndexOf('/'));
/* Если предыдущий каталог корневой */
if(lDotDot==='')lDotDot='/';
/* Сохраняем путь к каталогу верхнего уровня*/
lFileTable += '<li class=current-file>'+
'<span class="mini-icon directory">' +
'</span>' +
'<span class=name>' +
'<a href="'+lFS_s+lNoJS_s +
lDotDot +
'">'+"..</a>" +
'</span>' +
'<span class=size>&lt;dir&gt;</span>'+
'<span class=owner>.</span>' +
'<span class=mode></span>' +
'</li>';
}
var lLength=files.length;
for(var i=1;i<lLength;i++){
lFileTable +='<li class>';
lFileTable += '<span class="mini-icon ';
/* если папка - выводим другую иконку */
lFileTable += (files[i].size==='dir'?
'directory':'text-file') +
'">';
lFileTable +='</span>';
lFileTable +='<span class=name>' +
'<a href="'+lFS_s+lNoJS_s +
lPath+files[i].name +
'"' +
/* открываем файлы */
/*в новой вкладке */
(files[i].size==='dir'?'': ' target="_blank"')+
/* если длина имени файла больше 16 символов
* отрезаем лишнее, оставляя лишь 16,
* и добавляем две точки и тайтл
*/
(files[i].name.length>16?
' title="'+files[i].name+'">' +
files[i].name.substr(
files[i].name,16)+
'..':'>'+files[i].name) +
"</a>" +
'</span>';
/* если папка - не выводим размер */
lFileTable +='<span class=size>' +
(files[i].size==='dir'?
'&lt;dir&gt;':
/* если это файл - получаем
* короткий размер
*/
CloudFunc.getShortedSize(
files[i].size));
lFileTable +='</span>' +
'<span class=owner>' +
(!files[i].uid?'root':files[i].uid) +
'</span>' +
'<span class=mode>' +
/* конвертируем названия разрешений
* из числового формата в буквенный
* при этом корневой каталог не трогаем
* по скольку в нём и так всё уже
* установлено еще на сервере
*/
(//lPath==='/'?files[i].mode:
CloudFunc.convertPermissionsToSymbolic(files[i].mode)) +
'</span>';
lFileTable +='</li>';
}
/* если клавиши назначены и
* мы в корневом каталоге и
* верхний файл еще не выделен -
* выделяем верхний файл
*/
if(pKeyBinded && lPath==='/'&&
lFileTable.indexOf('<li class=current-file>')<0){
lFileTable=lFileTable.replace('<li class>','<li class=current-file>');
}
return lFileTable;
};
/*
* Если мы на стороне сервера -
* прописываем экспортируемые функции
*/
try{
if(exports){
/* экспортируемые функции */
exports.checkExtension = CloudFunc.checkExtension;
exports.buildFromJSON = CloudFunc.buildFromJSON;
exports.replaceSpaces = CloudFunc.replaceSpaces;
exports.setTitle = CloudFunc.setTitle;
exports.convertPermissions = CloudFunc.convertPermissions;
exports.getUserUIDsAndNames = CloudFunc.getUserUIDsAndNames;
/* константы*/
exports.Name = CloudFunc.NAME;
exports.NOJS = CloudFunc.NOJS;
exports.FS =CloudFunc.FS;
console.log('cloudfunc.js loaded...');
}
}catch(err){
/* если мы на клиенте */
}

279
lib/server/minify.js Normal file
View file

@ -0,0 +1,279 @@
/* Модуль сжатия js-скриптов и css*/
/* функция сжимает js-скрипты
* и сохраняет их с именем .min.js
*/
var fs = require('fs');
/* CONSTANTS */
/* dir contains css-files */
var CSSDIR = 'css/';
exports.jsScripts=function jsScripts(){
'use strict';
/* подключаем модуль uglify-js
* если его нет - дальнейшая
* работа функции не имеет смысла
*/
try{
var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;
}catch(error){
console.log('can\'n load uglify-js\n' +
'to use js-minification you need to install uglify-js\n' +
'npm install uglify-js\n' +
'https://github.com/mishoo/UglifyJS');
return false;
}
/* Константы */
var CLIENT_JS='client.js';
var CLOUDFUNC_JS='lib/cloudfunc.js';
var CLIENT_KEYBINDING_JS='lib/client/keyBinding.js';
var dataReaded_f=function(pFileName, pData){
console.log('file ' + pFileName + ' readed');
/*********************************/
/* сжимаем код через uglify-js */
var uglify_js=function(pDdata){
var orig_code = pDdata.toString();
var ast = jsp.parse(orig_code); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var result_code = pro.gen_code(ast); // compressed code here
return result_code;
};
/*********************************/
var final_code=uglify_js(pData);
var minFileName=pFileName.replace('.js','.min.js');
/* если мы сжимаем client.js -
* меняем строку cloudfunc.js на
* cloudfunc.min.js и выводим сообщение
*
* меняем строку keyBinding.js на
* keyBinding.min.js
* если другой файл - ничего не деалем
*/
if(pFileName===CLIENT_JS)
console.log('file name of ' +
CLOUDFUNC_JS +
' in ' +
CLIENT_JS +
' changed. size:',
(final_code=final_code
.replace('cloudfunc.js','cloudfunc.min.js')
.replace('keyBinding.js','keyBinding.min.js')).length);
/* записываем сжатый js-скрипт*/
fs.writeFile(minFileName, final_code, fileWrited(minFileName));
};
console.log('reading file ' + CLIENT_JS+'...');
fs.readFile(CLIENT_JS,fileReaded(CLIENT_JS,dataReaded_f));
console.log('reading file ' + CLOUDFUNC_JS+'...');
fs.readFile(CLOUDFUNC_JS,fileReaded(CLOUDFUNC_JS,dataReaded_f));
console.log('reading file ' + CLIENT_KEYBINDING_JS+'...');
fs.readFile(CLIENT_KEYBINDING_JS, fileReaded(CLIENT_KEYBINDING_JS,dataReaded_f));
return true;
};
/* функция сжимает css-стили
* и сохраняет их с именем .min.css
* @pImgConvertToBase64_b - булевый признак,
* который отвечает за то, что быконвертировать
* картинки в base64 и поместить в выходной css файл
*/
exports.cssStyles=function cssStyles(pImgConvertToBase64_b){
'use strict';
/* connecting cleanCSS,
* if we can't find it -
* return false
*/
var cleanCSS;
try{
cleanCSS = require('clean-css');
}catch(error){
console.log('can\'n load clean-css \n' +
'to use css-minification you need to install clean-css \n' +
'npm install clean-css\n' +
'https://github.com/GoalSmashers/clean-css');
return false;
}
/* Константы */
var STYLE_CSS = CSSDIR+'style.css';
var RESET_CSS = CSSDIR+'reset.css';
var lAllStyle='';
var lResetCssDone=false;
var lStyleCssDone=false;
var dataReaded_f=function(pFileName, pData){
console.log('file ' + pFileName + ' readed');
/*********************************/
/* сжимаем код через clean-css */
var clean_css=function(pData){
/* Сохраняем весь стиль в одну переменную*/
return cleanCSS.process(pData);
};
/*********************************/
var final_code=clean_css(pData);
lAllStyle+=final_code;
var minFileName=pFileName.replace('.css','.min.css');
if(pFileName===STYLE_CSS)lStyleCssDone=true;
if(pFileName===RESET_CSS)lResetCssDone=true;
/* if all files writed we
* save all minimized css
* to one file all.min.css
*/
if(lStyleCssDone && lResetCssDone){
/* если включена конвертация картинок в base64
* вызываем её
*/
if(pImgConvertToBase64_b)
base64_images(lAllStyle);
else
fs.writeFile(CSSDIR+'all.min.css', lAllStyle, fileWrited('all.min.css'));
}
/* в другом случае - записываем сжатый css файл*/
else fs.writeFile(minFileName, final_code, fileWrited(minFileName));
};
console.log('reading file ' + STYLE_CSS+'...');
fs.readFile(STYLE_CSS,fileReaded(STYLE_CSS,dataReaded_f));
console.log('reading file ' + RESET_CSS+'...');
fs.readFile(RESET_CSS,fileReaded(RESET_CSS,dataReaded_f));
return true;
};
/* функция сжимает css-стили
* и сохраняет их с именем .min.css
*/
exports.html=function(){
'use strict';
/* connecting cleanCSS,
* if we can't find it -
* return false
*/
var htmlMinifier;
try{
htmlMinifier = require('html-minifier');
}catch(error){
console.log('can\'n load html-minifier \n' +
'to use html-minification you need to install html-minifier\n' +
'npm install html-minifier\n' +
'https://github.com/kangax/html-minifier');
return false;
}
/* Константы */
var INDEX_HTML='index.html';
var dataReaded_f=function(pFileName, pData){
console.log('file ' + pFileName + ' readed');
/*********************************/
/* сжимаем код через clean-css */
var html_minify=function(pData){
/* Сохраняем весь стиль в одну переменную*/
var lOptions={
removeComments: true,
removeCommentsFromCDATA: true,
removeCDATASectionsFromCDATA: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
/* оставляем, поскольку у нас
* в элемент fm генерируеться
* таблица файлов
*/
removeEmptyElements: false,
removeOptionalTags: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
};
return htmlMinifier.minify(pData,lOptions);
};
/*********************************/
var final_code=html_minify(pData);
var minFileName=pFileName.replace('.html','.min.html');
/* записываем сжатый html файл*/
fs.writeFile(minFileName, final_code, fileWrited(minFileName));
};
console.log('reading file ' + INDEX_HTML+'...');
fs.readFile(INDEX_HTML,fileReaded(INDEX_HTML,dataReaded_f));
return true;
};
/* функция переводит картинки в base64 и записывает в css-файл*/
function base64_images(pFileContent_s){
'use strict';
var b64img;
try{
b64img = require('css-b64-images');
}catch(error){
console.log('can\'n load clean-css \n' +
'to use images to base64 convertation you need to install css-base64-images \n' +
'npm install -g css-b64-images\n' +
'https://github.com/Filirom1/css-base64-images');
return false;
}
b64img.fromString(pFileContent_s, '.','', function(err, css){
console.log('images converted to base64 and saved in css file');
fs.writeFile(CSSDIR+'all.min.css', css, fileWrited('all.min.css'));
});
}
/* Функция создаёт асинхроную версию
* для чтения файла
* @pFileName - имя считываемого файла
*/
function fileReaded(pFileName,pCompressFunc){
"use strict";
return function(pError,pData){
/* функция в которую мы попадаем,
* если данные считались
*
* если ошибка - показываем её
* иначе если переданная функция -
* функция запускаем её
*/
if(!pError)
if (pCompressFunc && typeof pCompressFunc==="function")
pCompressFunc(pFileName,pData.toString());
else console.log(pError);
};
}
/*
* Функция вызываеться после записи файла
* и выводит ошибку или сообщает,
* что файл успешно записан
*/
function fileWrited(pFileName){
"use strict";
return function(error){
console.log(error?error:('file '+pFileName+' writed...'));
};
}