/* Функция которая возвратит обьект CloudCommander * @window - обьект window * @document - обьект document * @CloudFunc - обьект содержащий общий функционал * клиентский и серверный */ var CloudCommander=(function(){ "use strict"; /* Клиентский обьект, содержащий функциональную часть*/ var CloudClient={ /* Конструктор CloudClient, который * выполняет весь функционал по * инициализации */ init :function(){}, keyBinding :function(){},/* функция нажатий обработки клавишь */ Editor :function(){},/* function loads and shows editor */ keyBinded :false,/* оброботка нажатий клавишь установлена*/ _loadDir :function(){}, /* * Функция привязываеться ко всем ссылкам и * загружает содержимое каталогов */ /* Обьект для работы с кэшем */ 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 - элемент, * для которого нужно * выполнить загрузку */ 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!=='/'){ /* функция устанавливает курсор на каталог * с которого мы пришли, если мы поднялись * в верх по файловой структуре */ CloudClient._currentToParent(lHref); } /* что бы не переходить по ссылкам * а грузить всё ajax'ом, * возвращаем false на событие * onclick */ return false; }; }); /* Функция устанавливает текущим файлом, тот * на который кликнули единожды */ 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; }; }); /* функция устанавливает курсор на каталог * с которого мы пришли, если мы поднялись * в верх по файловой структуре * @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=''; 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'; /* загружаем 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; /* меняем ссылки на 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'); /* Если нажмут на кнопку перезагрузить страниц - её нужно будет обязательно * перезагрузить */ /* номер ссылки очистки кэша*/ //var lCLEARICON=0; /* номер ссылки иконки обновления страницы */ var lREFRESHICON=0; /* путь в ссылке, который говорит * что js отключен */ var lNoJS_s = CloudFunc.NOJS; var lFS_s = CloudFunc.FS; for(var i=0;i=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