From d7d385ac3445f2d61c417d73397045667df169f7 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 23 Jul 2012 16:36:28 +0300 Subject: [PATCH] minor changes --- client.js | 1238 ++++++++++++++++++++--------------------------------- 1 file changed, 474 insertions(+), 764 deletions(-) diff --git a/client.js b/client.js index 2213110d..0d081dc5 100644 --- a/client.js +++ b/client.js @@ -1,783 +1,493 @@ -/* Функция которая возвратит обьект CloudCommander - * @window - обьект window - * @document - обьект document - * @CloudFunc - обьект содержащий общий функционал - * клиентский и серверный - */ - -var CloudCommander=(function(){ "use strict"; +/* Модуль, содержащий функции, которые будут работать + * и на клиенте и на сервере + */ -/* Клиентский обьект, содержащий функциональную часть*/ -var CloudClient={ - /* Конструктор CloudClient, который - * выполняет весь функционал по - * инициализации - */ - init :function(){}, +var CloudFunc={ + /* Путь с которым мы сейчас работаем */ + Path :'', + /* КОНСТАНТЫ (общие для клиента и сервера)*/ + /* название программы */ + NAME :'Cloud Commander', + /* если в ссылке будет эта строка - + * в браузере js отключен + */ + NOJS : '/no-js', + FS : '/fs', + /* название css-класа кнопки обновления файловой структуры*/ + REFRESHICON : 'refresh-icon', + /* id панелей с файлами */ + LEFTPANEL : 'left', + RIGHTPANEL : 'right', + /* length of longest + * file name + */ + SHORTNAMELENGTH : 16 +}; + +/* + * Функция убирает последний слеш, + * если он - последний символ строки + */ +CloudFunc.removeLastSlash = function(pPath){ + if(typeof pPath==='string') + return (pPath.lastIndexOf('/')===pPath.length-1)? + pPath.substr(pPath, pPath.length-1):pPath; + else return pPath; +}; + +/* Функция возвращает заголовок веб страницы */ +CloudFunc.setTitle = function(){ - keyBinding :function(){},/* функция нажатий обработки клавишь */ - Editor :function(){},/* function loads and shows editor */ - keyBinded :false,/* оброботка нажатий клавишь установлена*/ - _loadDir :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 != pSize-0) return pSize; + + /* Константы размеров, что используются + * внутри функции + */ + var l1BMAX=1024; + var l1KBMAX=1048576; + var l1MBMAX=1073741824; + var l1GBMAX=1099511627776; + var l1TBMAX=1125899906842624; + + var lShorted; + + if(pSize CloudFunc.SHORTNAMELENGTH ? + (pName.substr(pName,16) + '..'): + pName); +}; + + +/* Функция парсит 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=''; + var lHrefEnd=''; + + 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='
  • '; + lHeader+=''; + for(var i=0;i'+ + lStr+ + ''; + } + lHeader+='
  • '; + + return lHeader; +}; + +/* + * Функция строит таблицу файлв из JSON-информации о файлах + * @pJSON - информация о файлах + * @pKeyBinded - если клавиши назначены, выделяем верхний файл + * [{path:'путь',size:'dir'}, + * {name:'имя',size:'размер',mode:'права доступа'}] + */ +CloudFunc.buildFromJSON=function(pJSON,pKeyBinded) +{ + var files; + /* + * если пропарсить стандартными + * функциями нельзя - + * пробуем eval, + */ /* - * Функция привязываеться ко всем ссылкам и - * загружает содержимое каталогов + * Если мы на клиенте и нет JSON - + * через eval парсим. + * Если-же мы на сервере, + * или на клиенте всё есть + * парсим стандарным методом */ - /* Обьект для работы с кэшем */ - Cashe :{}, - - /* ПРИВАТНЫЕ ФУНКЦИИ */ - /* функция загружает json-данные о файловой системе */ - _ajaxLoad :function(){}, - /* Функция генерирует JSON из html-таблицы файлов */ - _getJSONfromFileTable :function(){}, - /* функция меняет ссыки на ajax-овые */ - _changeLinks :function(){}, - /* ОБЬЕКТЫ */ - /* обьект, который содержит функции для отображения картинок*/ - _images :{}, - /* КОНСТАНТЫ*/ - /* название css-класа текущего файла*/ - CURRENT_FILE :'current-file', - LIBDIR :'/lib/', - LIBDIRCLIENT :'/lib/client/' -}; - -/* - * Обьект для работы с кэшем - * в него будут включены функции для - * работы с LocalStorage, webdb, - * idexed db etc. - */ -CloudClient.Cache={ - _allowed :true, /* приватный переключатель возможности работы с кэшем */ - /* функция проверяет возможно ли работать с кэшем каким-либо образом */ - isAllowed :function(){}, - /* Тип кэша, который доступен*/ - type :{}, - /* Функция устанавливает кэш, если выбранный вид поддерживаеться браузером*/ - set :function(){}, - /* Функция достаёт кэш, если выбранный вид поддерживаеться браузером*/ - get :function(){}, - /* функция чистит весь кэш для всех каталогов*/ - clear :function(){} -}; - -/* Обьект, который содержит - * функции для отображения - * картинок - */ -CloudClient._images={ - /* Функция создаёт картинку загрузки*/ - loading :function(){ - var e=document.createElement('span'); - e.className='icon loading'; - e.id='loading-image'; - return e; -}, - - /* Функция создаёт картинку ошибки загрузки*/ - error :function(){ - var e=document.createElement('span'); - e.className='icon error'; - e.id='error-image'; - return e; - } -}; - -/* функция проверяет поддерживаеться ли localStorage */ -CloudClient.Cache.isAllowed=(function(){ - if(window.localStorage && - localStorage.setItem && - localStorage.getItem){ - CloudClient.Cache._allowed=true; - }else - { - CloudClient.Cache._allowed=false; - /* загружаем PolyFill для localStorage, - * если он не поддерживаеться браузером - * https://gist.github.com/350433 - */ - /* - CloudClient.jsload('https://raw.github.com/gist/350433/c9d3834ace63e5f5d7c8e1f6e3e2874d477cb9c1/gistfile1.js', - function(){CloudClient.Cache._allowed=true; - }); - */ - } -}); - /* если доступен localStorage и - * в нём есть нужная нам директория - - * записываем данные в него - */ -CloudClient.Cache.set=(function(pName, pData){ - if(CloudClient.Cache._allowed && pName && pData){ - localStorage.setItem(pName,pData); - } -}); -/* Если доступен Cache принимаем из него данные*/ -CloudClient.Cache.get=(function(pName){ - if(CloudClient.Cache._allowed && pName){ - return localStorage.getItem(pName); - } - else return null; -}); -/* Функция очищает кэш*/ -CloudClient.Cache.clear=(function(){ - if(CloudClient.Cache._allowed){ - localStorage.clear(); - } -}); - - -/* функция обработки нажатий клавишь */ -CloudClient.keyBinding=(function(){ - /* loading keyBinding module and start it */ - CloudClient.jsload(CloudClient.LIBDIRCLIENT+'keyBinding.js',function(){ - CloudCommander.keyBinding(); - }); -}); - -/* function loads and shows editor */ -CloudClient.Editor = (function(){ - /* loading CloudMirror plagin */ - CloudClient.jsload(CloudClient.LIBDIRCLIENT + 'editor.js',{ - onload:(function(){ - CloudCommander.Editor.Keys(); - }) - }); -}); -/* - * Функция привязываеться ко всем ссылкам и - * загружает содержимое каталогов - */ -CloudClient._loadDir=(function(pLink,pNeedRefresh){ - /* @pElem - элемент, - * для которого нужно - * выполнить загрузку + + /* По скольку мы прописали заголовок application/json + * нет необходимости его конвертировать, + * но она есть, если мы вытягиваем данные из + * localStorage */ - return function(){ - /* показываем гиф загрузки возле пути папки сверху*/ - LoadingImage.className='icon loading';/* показываем загрузку*/ - ErrorImage.className='icon error hidden';/* прячем ошибку */ - /* если элемент задан - - * работаем с ним - */ - /* если мы попали сюда с таблицы файлов*/ - try{ - this.firstChild.nextSibling.appendChild(LoadingImage); - }catch(error){ - /* если + - * кнопка обновления - */ - try{this.firstChild.parentElement.appendChild(LoadingImage);} - catch(error){console.log(error);} - } - - var lCurrentFile=document.getElementsByClassName(CloudClient.CURRENT_FILE); - /* получаем имя каталога в котором находимся*/ - var lHref; - try{ - lHref=lCurrentFile[0].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+'/',''); - - /* загружаем содержимое каталога*/ - CloudClient._ajaxLoad(pLink, pNeedRefresh); - - /* получаем все элементы выделенной папки*/ - /* при этом, если мы нажали обновить - * или +R - ссылок мы ненайдём - * и заходить не будем - */ - var lA=this.getElementsByTagName('a'); - /* если нажали на ссылку на верхний каталог*/ - if(lA.length>0 && lA[0].textContent==='..' && - lHref!=='/'){ - /* функция устанавливает курсор на каталог - * с которого мы пришли, если мы поднялись - * в верх по файловой структуре и если - * длина названия папки больше - * CloudFunc.SHORTNAMELENGTH уменьшает его - */ - lHref = CloudFunc.getShortedName(lHref); - CloudClient._currentToParent(lHref); - } - - /* что бы не переходить по ссылкам - * а грузить всё ajax'ом, - * возвращаем false на событие - * onclick - */ - return false; - }; - }); + files=pJSON; + /* сохраняем путь каталога в котором мы сейчас находимся*/ + var lPath=files[0].path; -/* Функция устанавливает текущим файлом, тот - * на который кликнули единожды - */ -CloudClient._setCurrent=(function(){ - /* - * @pFromEnter - если мы сюда попали - * из события нажатия на энтер - - * вызоветься _loadDir - */ - return function(pFromEnter){ - var lCurrentFile=document.getElementsByClassName(CloudClient.CURRENT_FILE); - if(lCurrentFile && lCurrentFile.length > 0){ - /* если мы находимся не на - * пути и не на заголовках - */ - if(this.className!=='path' && - this.className!=='fm_header'){ - - lCurrentFile[0].className=''; - /* устанавливаем курсор на файл, - * на который нажали */ - this.className=CloudClient.CURRENT_FILE; - } - } - /* если мы попали сюда с энтера*/ - if(pFromEnter===true){ - this.ondblclick(this); - }/* если мы попали сюда от клика мышки */ - else{pFromEnter.returnValue=false;} - - /* что бы не переходить по ссылкам - * а грузить всё ajax'ом, - * возвращаем false на событие - * onclick - */ - return false; - }; - }); + /* сохраняем путь */ + CloudFunc.Path=lPath; -/* функция устанавливает курсор на каталог - * с которого мы пришли, если мы поднялись - * в верх по файловой структуре - * @pDirName - имя каталога с которого мы пришли - */ -CloudClient._currentToParent = (function(pDirName){ - /* опредиляем в какой мы панели: - * правой или левой - */ - var lCurrentFile=document.getElementsByClassName(CloudClient.CURRENT_FILE); - var lPanel; - try{ - lPanel=lCurrentFile[0].parentElement.id; - }catch(error){console.log("Current file not found\n"+error);} - /* убираем слэш с имени каталога*/ - pDirName=pDirName.replace('/',''); - /* ищем файл с таким именем*/ - lPanel=document.getElementById(lPanel); - if(!lPanel)return; - - var lLi=lPanel.getElementsByTagName('li'); - for(var i=0;i0)lCurrentFile[0].className=''; + /* + * Строим путь каталога в котором мы находимся + * со всеми подкаталогами + */ + var lHtmlPath=CloudFunc._getDirPath(lPath); - lLi[i].className=CloudClient.CURRENT_FILE; - } - } -}); - -/* глобальные переменные */ -var LoadingImage; -var ErrorImage; - -var CloudFunc; -/* Конструктор CloudClient, который - * выполняет весь функционал по - * инициализации - */ -CloudClient.init=(function() -{ - /* меняем title - * если js включен - имена папок отображать необязательно... - * а может и обязательно при переходе, можно будет это сделать + /* Убираем последний слэш + * с пути для кнопки обновить страницу + * если он есть */ - var lTitle=document.getElementsByTagName('title'); - if(lTitle.length>0)lTitle[0].textContent='Cloud Commander'; + var lRefreshPath=CloudFunc.removeLastSlash(lPath); - /* загружаем jquery: */ - CloudClient.jsload('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',{ - onerror: function(){ - CloudClient.jsload('lib/client/jquery.js'); - - CloudClient.cssSet({id:'local-droids-font', - element : document.head, - inner : '@font-face {font-family: "Droid Sans Mono";' + - 'font-style: normal;font-weight: normal;' + - 'src: local("Droid Sans Mono"), local("DroidSansMono"),'+ - ' url("font/DroidSansMono.woff") format("woff");}' - }); - } - }); - - /* загружаем общие функции для клиента и сервера*/ - CloudClient.jsload(CloudClient.LIBDIR+'cloudfunc.js',function(){ - /* берём из обьекта 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()); - } - ); - - LoadingImage=CloudClient._images.loading(); - /* загружаем иконку загрузки возле кнопки обновления дерева каталогов*/ - try{ - document.getElementsByClassName('path')[0].getElementsByTagName('a')[0].appendChild(LoadingImage); - LoadingImage.className+=' hidden'; /* прячем её */ - }catch(error){console.log(error);} - ErrorImage=CloudClient._images.error(); - - /* устанавливаем размер высоты таблицы файлов - * исходя из размеров разрешения экрана - */ - - /* выделяем строку с первым файлом */ - var lFmHeader=document.getElementsByClassName('fm_header'); - if(lFmHeader && lFmHeader[0].nextSibling) - lFmHeader[0].nextSibling.className=CloudClient.CURRENT_FILE; - - /* показываем элементы, которые будут работать только, если есть js */ - var lFM=document.getElementById('fm'); - if(lFM)lFM.className='localstorage'; - - /* если есть js - показываем правую панель*/ - var lRight=document.getElementById('right'); - if(lRight)lRight.className=lRight.className.replace('hidden',''); - - /* формируем и округляем высоту экрана - * при разрешениии 1024x1280: - * 658 -> 700 - */ - - var lHeight=window.screen.height - (window.screen.height/3).toFixed(); - lHeight=(lHeight/100).toFixed()*100; - - CloudClient.cssSet({id:'show_2panels', - element:document.head, - inner:'#left{width:46%;}' + - '.panel{height:' + lHeight +'px' - }); -}); - -/* функция меняет ссыки на ajax-овые */ -CloudClient._changeLinks = function(pPanelID) -{ - /* назначаем кнопку очистить кэш и показываем её*/ - var lClearcache=document.getElementById('clear-cache'); - if(lClearcache)lClearcache.onclick=CloudClient.Cache.clear; - - /* меняем ссылки на ajax-запросы */ - var lPanel=document.getElementById(pPanelID); - var a=lPanel.getElementsByTagName('a'); - - /* Если нажмут на кнопку перезагрузить страниц - её нужно будет обязательно - * перезагрузить + /* путь в ссылке, который говорит + * что js отключен */ - /* номер ссылки очистки кэша*/ - //var lCLEARICON=0; - /* номер ссылки иконки обновления страницы */ - var lREFRESHICON=0; + var lNoJS_s=CloudFunc.NOJS; + var lFS_s=CloudFunc.FS; + + var lFileTable='
  • '+ + ''+ + ''+ + '' + + ''+ + ''+ + ''+lHtmlPath+''+ + '
  • '; + + 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='/'; - /* путь в ссылке, который говорит - * что js отключен - */ - var lNoJS_s = CloudFunc.NOJS; - var lFS_s = CloudFunc.FS; - - for(var i=0;i' + + '' + + '' + + ''+".." + + '' + + '<dir>'+ + '.' + + '' + + ''; } + var lLength=files.length; + + for(var i=1;i'; + lFileTable +=''; + lFileTable +='' + + ' CloudFunc.SHORTNAMELENGTH? + ' title="' + files[i].name + '">' + + CloudFunc.getShortedName(files[i].name): + '>' + files[i].name) + + "" + + ''; + /* если папка - не выводим размер */ + lFileTable +='' + + (files[i].size==='dir'? + '<dir>': + /* если это файл - получаем + * короткий размер + */ + CloudFunc.getShortedSize( + files[i].size)); + lFileTable +='' + + '' + + (!files[i].uid?'root':files[i].uid) + + '' + + '' + + /* конвертируем названия разрешений + * из числового формата в буквенный + * при этом корневой каталог не трогаем + * по скольку в нём и так всё уже + * установлено еще на сервере + */ + (//lPath==='/'?files[i].mode: + CloudFunc.convertPermissionsToSymbolic(files[i].mode)) + + ''; + lFileTable +=''; + } + + /* если клавиши назначены и + * мы в корневом каталоге и + * верхний файл еще не выделен - + * выделяем верхний файл + */ + if(pKeyBinded && lPath==='/'&& + lFileTable.indexOf('
  • ')<0){ + lFileTable=lFileTable.replace('
  • ','
  • '); + } + + + + return lFileTable; }; /* - * Функция загружает json-данные о Файловой Системе - * через ajax-запрос. - * @path - каталог для чтения - * @pNeedRefresh - необходимость обновить данные о каталоге + * Если мы на стороне сервера - + * прописываем экспортируемые функции */ -CloudClient._ajaxLoad=function(path, pNeedRefresh) -{ - /* Отображаем красивые пути */ - /* added supporting of russian language */ - var lPath=decodeURI(path); - var lFS_s=CloudFunc.FS; - if(lPath.indexOf(lFS_s)===0){ - lPath=lPath.replace(lFS_s,''); - if(lPath==='')lPath='/'; - } - console.log ('reading dir: "'+lPath+'";'); - - /* если доступен localStorage и - * в нём есть нужная нам директория - - * читаем данные с него и - * выходим - * если стоит поле обязательной перезагрузки - - * перезагружаемся - */ - - /* опредиляем в какой мы панели: - * правой или левой - */ - var lPanel; - try{ - lPanel=document.getElementsByClassName(CloudClient.CURRENT_FILE)[0].parentElement.id; - }catch(error){console.log("Current file not found\n"+error);} - - if(pNeedRefresh===undefined && lPanel){ - var lJSON=CloudClient.Cache.get(lPath); - if (lJSON!==null){ - /* переводим из текста в JSON */ - if(window && !window.JSON){ - try{ - lJSON=eval('('+lJSON+')'); - }catch(err){ - console.log(err); - } - }else lJSON=JSON.parse(lJSON); - CloudClient._createFileTable(lPanel,lJSON); - CloudClient._changeLinks(lPanel); - return; - } - } - - /* ######################## */ - try{ - $.ajax({ - url: path, - error: function(jqXHR, textStatus, errorThrown){ - console.log(textStatus+' : '+errorThrown); - var lLoading=document.getElementById('loading-image'); - ErrorImage.className='icon error'; - ErrorImage.title=errorThrown; - lLoading.parentElement.appendChild(ErrorImage); - lLoading.className='hidden'; - //document.getElementsByClassName('path')[0].appendChild(ErrorImage); - - }, - success:function(data, textStatus, jqXHR){ - /* если такой папки (или файла) нет - * прячем загрузку и показываем ошибку - */ - /* для совместимости с firefox меняем data - * на jqXHR, он воспринимает data к Document - * когда возвращаеться ошибка, о том, что - * нет файла или нет доступа - */ - - var lLoading; - if(!jqXHR.responseText.indexOf('Error:')){ - /* если файла не существует*/ - if(!jqXHR.responseText.indexOf('Error: ENOENT, ')){ - ErrorImage.title=jqXHR.responseText.replace('Error: ENOENT, n','N'); - } - /* если не хватает прав для чтения файла*/ - else if(!jqXHR.responseText.indexOf('Error: EACCES,')){ - ErrorImage.title=jqXHR.responseText.replace('Error: EACCES, p','P'); - } - ErrorImage.className='icon error'; - lLoading=document.getElementById('loading-image'); - lLoading.parentElement.appendChild(ErrorImage); - lLoading.className='hidden'; - - return; - } - CloudClient._createFileTable(lPanel,data); - CloudClient._changeLinks(lPanel); - - /* Сохраняем структуру каталогов в localStorage, - * если он поддерживаеться браузером - */ - /* переводим таблицу файлов в строку, для - * сохранения в localStorage - */ - var lJSON_s=JSON.stringify(data); - console.log(lJSON_s.length); - - /* если размер данных не очень бошьой - * сохраняем их в кэше - */ - if(lJSON_s.length<50000) - CloudClient.Cache.set(lPath,lJSON_s); - } - }); - }catch(err){console.log(err);} -}; - -/* - * Функция строит файловую таблицу - * @pEleme - родительский элемент - * @pJSON - данные о файлах - */ -CloudClient._createFileTable = function(pElem,pJSON) -{ - var lElem=document.getElementById(pElem); - /* говорим построителю, - * что бы он в нужный момент - * выделил строку с первым файлом - */ - - /* очищаем панель */ - var i = lElem.childNodes.length; - while(i--){ - lElem.removeChild(lElem.lastChild); - } - - /* заполняем панель новыми элементами */ - lElem.innerHTML=CloudFunc.buildFromJSON(pJSON,true); -}; - -/* - * Функция создаёт элемент и - * загружает файл с src. - * @pName - название тэга - * @pSrc - путь к файлу - * @pFunc - обьект, содержаий одну из функций - * или сразу две onload и onerror - * {onload: function(){}, onerror: function();} - * @pStyle - стиль - * @pId - id - * @pElement - элемент, дочерним которо будет этот - */ -CloudClient._anyload = function(pName,pSrc,pFunc,pStyle,pId,pElement) -{ - //если скрипт еще не загружен - /* убираем путь к файлу, оставляя только название файла */ - var lID; - if(pId===undefined){ - lID=pSrc.replace(pSrc.substr(pSrc,pSrc.lastIndexOf('/')+1),''); - /* убираем точку*/ - lID=lID.replace('.','_'); - }else lID=pId; - if(!document.getElementById(lID)) - { - var element = document.createElement(pName); - /* if working with external css - * using href in any other case - * using src - */ - pName === 'link' ? - element.href = pSrc - : element.src = pSrc; - element.id=lID; - if(arguments.length>=3){ - /* if passed arguments function - * then it's onload by default - */ - if(pFunc) - 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 && pStyle){ - element.style.cssText=pStyle; - } - } - (pElement || document.body).appendChild(element); - return element; - } - /* если js-файл уже загружен - * запускаем функцию onload - */ - else if(pFunc){ - try{ - pFunc(); - }catch(error){console.log(error);} - } -}; - -/* Функция загружает js-файл */ -CloudClient.jsload = function(pSrc,pFunc,pStyle,pId) -{ - CloudClient._anyload('script',pSrc,pFunc,pStyle,pId,document.body); -}; -/* Функция создаёт елемент style и записывает туда стили - * @pParams_o - структура параметров, заполняеться таким - * образом: {src: ' ',func: '', id: '', element: '', inner: ''} - * все параметры опциональны - */ -CloudClient.cssSet = function(pParams_o){ - var lElem=CloudClient._anyload('style', - pParams_o.src, - pParams_o.func, - pParams_o.style, - pParams_o.id, - pParams_o.element || document.head); - - pParams_o.inner && - (lElem.innerHTML = pParams_o.inner); -}; -/* Function loads external css files - * @pParams_o - структура параметров, заполняеться таким - * образом: {src: ' ',func: '', id: '', element: '', inner: ''} - * все параметры опциональны - */ -CloudClient.cssLoad = function(pParams_o){ - var lElem=CloudClient._anyload('link', - pParams_o.src, - pParams_o.func, - pParams_o.style, - pParams_o.id, - pParams_o.element || document.head); - - lElem.rel = "stylesheet"; - - pParams_o.inner && - (lElem.innerHTML = pParams_o.inner); -}; - - - -/* - * Функция генерирует JSON из html-таблицы файлов - */ -/* - * Используеться при первом заходе в корень - */ -CloudClient._getJSONfromFileTable=function() -{ - var lLeft=document.getElementById('left'); - var lPath=document.getElementsByClassName('path')[0].textContent; - var lFileTable=[{path:lPath,size:'dir'}]; - var lLI=lLeft.getElementsByTagName('li'); - - var j=1;/* счётчик реальных файлов */ - var i=1;/* счётчик элементов файлов в DOM */ - /* Если путь отличный от корневного - * второй элемент li - это ссылка на верхний - * каталог '..' - */ - i=2;/* пропускам Path и Header*/ - - - for(;i