(function(global, $){ var codiad = global.codiad; $(window).load(function() { codiad.finder.init(); }); ////////////////////////////////////////////////////////////////// // // Search utility to quickly filter the directory tree // according to multiple matching strategies // ////////////////////////////////////////////////////////////////// codiad.finder = { // Create DOM node for a particular tree element _makeDomNode: function(name, obj){ var str, path, ext, chStr; str = "
  • 0) str += " ext-"+s[s.length -1]; str += "'"; } str += " data-path='"+obj.path+"' data-type='"+ obj.type +"' >" + name + ""; chStr = ""; for (key in obj.children){ chStr += this._makeDomNode(key, obj.children[key]); } if (chStr.length > 0){ str += ""; } str += "
  • "; return str; }, // Construct DOM tree from internal data-structure representing // the filtered directory tree _makeDomTree: function(tree){ var str = ""; //console.debug("DOM tree :", str); return str; }, // Construct internal representation for filtered directory tree // from array returned by server _makeHierarchy: function(data){ data = data.index; //console.log('data : ', data); var tree = {}, fpathArr, i, j, fragment, curLevel, type; for (i = 0; i < data.length; i++){ curLevel = tree; if(codiad.project.isAbsPath(data[i].path)) { fpathArr = data[i].path.replace(this._rootPath, this._rootName).split('/'); } else { fpathArr = data[i].path.split('/'); } for (j = 0; j < fpathArr.length; j++){ fragment = fpathArr[j]; if (fragment === "") continue; if (! curLevel[fragment]){ type = j < fpathArr.length -1 ? 'directory' : data[i].type; curLevel[fragment] = { type: type, children: {} } if (type === 'file'){ curLevel[fragment].path = data[i].path; } else { if(codiad.project.isAbsPath(data[i].path)) { curLevel[fragment].path = fpathArr.slice(0, j+1).join('/').replace(this._rootName, this._rootPath); } else { curLevel[fragment].path = fpathArr.slice(0, j+1).join('/'); } } } curLevel = curLevel[fragment].children; } } //console.log('tree : ', tree, JSON.stringify(tree)); return tree; }, // Use query response returned by server to filter the directory tree _filterTree: function(data){ var tree = this._makeHierarchy(data); var domTree = this._makeDomTree(tree); $('#file-manager').html(domTree); $('#file-manager>ul>li:first-child>span').remove(); $('#file-manager>ul>li:first-child>a').attr({ id: 'project-root', 'data-type': 'root', 'data-path': this._rootPath }); }, // Clear all filters applied and restore the tree to its original state _clearFilters: function(){ //console.info("Reloading initial tree state "); if (this._htmlStash) $('#file-manager').html(this._htmlStash); this._htmlStash = null; $('#finder').attr('value', ''); }, // Empty the tree and notify that no files were found _emptyTree: function(){ $('#file-manager').html("No files found ."); }, // Check finder for changes in the user entered query _checkFinder: function(){ var fentry = $('#finder').attr('value'); var _this = this; fentry = fentry.replace(/^\s+|\s+$/g, ''); if (! fentry || fentry == this._lastEntry) return; /*else if (fentry.substring(0, this._lastEntry.length) === this._lastEntry) { // TODO : Scope for optimization // // User has added characters to query - so unless the // query is a regexp - the filtered results can be // deduced locally if last ajax request had completed. // Not implementing this currently because this is // not very beneficial practically for decent // typing speed. }*/ else{ // Stop currently ongoing request if (this._xhr) this._xhr.abort(); // Query the server for results //console.log("Finder query changed"); this._lastEntry = fentry; this._xhr = $.ajax({ url: 'components/filemanager/controller.php', type: 'GET', dataType: 'json', data: { query: fentry, action: 'find', path: this._rootPath, options: this._options }, success: function(data){ if (data.status == 'success'){ _this._filterTree(data.data); } else { _this._emptyTree(); } } }); } }, ////////////////////////////////////////////////////////////////// // // Expand the finder box (Textbox through which the directory tree // can be searched for matching files) and focus on it. // ////////////////////////////////////////////////////////////////// expandFinder: function(){ this._isFinderExpanded = true; //console.info("Saving tree state : "); this._htmlStash = $('#file-manager').html(); this._rootPath = $('#project-root').attr('data-path'); this._rootName = $('#project-root').html(); $("#finder-wrapper").show(); $("#sb-left-title h2").hide(); var _this = this; this._lastEntry = null; this._poller = setInterval(function(){ _this._checkFinder(); }, 500); $("#finder").focus(); $("#finder-quick").hide(); $("#sb-left-title").addClass('active'); $("#tree-search") .removeClass('icon-search') .addClass('icon-cancel-squared active'); }, // Contract the finder box contractFinder: function(){ this._isFinderExpanded = false; $("#finder-wrapper").hide('fast'); $("#sb-left-title h2").show('fast'); clearInterval(this._poller); this.finderMenu.hide(); this._clearFilters(); $("#finder-quick").show(); $("#sb-left-title").removeClass('active'); $("#tree-search") .removeClass('icon-cancel-squared active') .addClass('icon-search'); }, // Setup finder init: function(){ var _this = this; var isExpanded = false; this._options = {}; $('#tree-search').click(function(){ if (! _this._isFinderExpanded) { _this.expandFinder(); } else { _this.contractFinder(); } }); $('#finder-label').click(function(){ _this.expandFinder(); }); this.finderMenu = finderMenu = $('#finder-options-menu') .appendTo($('#sb-left')) .hide(); $finderOptionsMenu = $('#finder-options-menu'); $('#finder-options').click(function(){ finderMenu.toggle(); }); // Setup the menu for selection of finding strategy $finderOptionsMenu.bind('click', 'a', function(e){ $target = $(e.target); var strategy = $target.attr('data-option'); var action = $target.attr('data-action'); if (strategy){ _this._options.strategy = strategy; $finderOptionsMenu .find('li.chosen') .removeClass('chosen'); $target.parent('li').addClass('chosen'); } else if (action){ codiad.filemanager[action](codiad.project.getCurrent()); _this.contractFinder(); } $finderOptionsMenu.hide(); }); // Setup the menu for selection of finding strategy $('#finder-quick').click(function(e){ codiad.filemanager['search'](codiad.project.getCurrent()); _this.contractFinder(); }); /* TODO: provide configuration option to automatically collapse finder -- The code below does exactly that -- $('#sb-left').mouseleave(function(){ _this.finderSustainFocus = false; if (! $('#finder').is(':focus')){ _this.contractFinder(); } }).mouseenter(function(){ _this.finderSustainFocus = true; }); $('#finder').blur(function(){ if (! _this.finderSustainFocus) _this.contractFinder(); }); */ } } })(this, jQuery);