Ticket #7074: 7074-directory-expand-and-nav.2.patch
| File 7074-directory-expand-and-nav.2.patch, 9.4 KB (added by cboos, 4 years ago) |
|---|
-
trac/htdocs/js/keyboard_nav.js
5 5 $(document).keydown(function(event) { 6 6 if (!ENABLE_KEY_NAV) 7 7 return true; 8 if (event.ctrlKey) 9 return true; // let CTRL+R do its job 8 10 var selection = SELECTED_FILE_ELEM; 9 11 switch (event.keyCode) { 10 case 74: // j 12 case 74: // j - next line 11 13 if (selection == null) { 12 14 selection = $('#f0'); 15 if ( !selection.length ) 16 selection = $($("#dirlist tr").get(1)) 13 17 } else { 14 18 do { 15 19 selection = selection.next(); 16 20 } while (selection.length > 0 && selection.css('display') == 'none'); 17 21 } 18 22 break; 19 case 75: // k 23 case 75: // k - previous line 20 24 if (selection == null) { 21 25 selection = $('#f0'); 22 26 } else { … … 26 30 } 27 31 break; 28 32 case 13: // Enter 29 case 79: // o 33 case 65: // 'a'nnotate 34 case 79: // 'o'pen 35 case 82: // 'r'eload 30 36 if (selection != null) { 31 37 var expander = selection.find('.expander'); 32 38 if (expander.length > 0) { 39 if (event.keyCode == 82) { 40 selection.removeClass("expanded").removeClass("collapsed") 41 .siblings("tr."+selection.get(0).id).not(selection).remove(); 42 } 33 43 expander.click(); 34 44 } else { 35 window.location = selection.find('a.file').attr('href'); 45 var href = selection.find('a.file').attr('href'); 46 if (href) { 47 if (event.keyCode == 65) 48 href += '?annotate=blame'; 49 } else { 50 href = selection.find('a.parent').attr('href'); 51 } 52 if (href) 53 window.location = href; 36 54 } 37 55 } 38 56 return false; 39 57 break; 58 case 76: // 'l'og 59 if (selection != null) { 60 window.location = selection.find('td.rev a').attr('href'); 61 } 62 break; 40 63 default: 41 64 return true; 42 65 } -
trac/htdocs/js/trac.js
47 47 }); 48 48 } 49 49 50 $.template = function(str, dict) { 51 return str.replace(/\${?(\w+)}?/g, function(_, k) { return dict[k]; }); 52 } 53 50 54 // Used for dynamically updating the height of a textarea 51 55 window.resizeTextArea = function (id, rows) { 52 56 var textarea = $("#" + id).get(0); … … 72 76 return $(elem).parents(tagName).get(0); 73 77 } 74 78 75 })(jQuery); 76 No newline at end of file 79 })(jQuery); -
trac/htdocs/js/expand_dir.js
4 4 var FOLDERID_COUNTER = 0; 5 5 var SUBFOLDER_INDENT = 20; 6 6 7 // enableExpandDir adds the capability to folder rows to be expanded and folded 7 // enableExpandDir adds the capability to ''folder'' rows in a table 8 // to be expanded and folded. 9 // 8 10 // It also teach the rows about their ancestors. It expects: 9 11 // - `parent_tr`, the logical parent row (`null` if there's no ancestor) 10 12 // - a `rows` jQuery object matching the newly created entry rows 11 13 // - `qargs`, additional parameters to send to the server when expanding 14 // - `autoexpand`, an optional array corresponding to a splitted sub-path 15 // of entries that will be expanded automatically. 12 16 13 window.enableExpandDir = function(parent_tr, rows, qargs ) {17 window.enableExpandDir = function(parent_tr, rows, qargs, autoexpand) { 14 18 // the ancestors folder ids are present in the parent_tr class attribute 15 19 var ancestor_folderids = []; 16 if (parent_tr) 20 21 if (parent_tr) // rows are logical children of the parent_tr row 17 22 ancestor_folderids = $.grep(parent_tr.attr("class").split(" "), 18 23 function(c) { return c.match(/^f\d+$/)}); 24 else { // rows are toplevel rows, this is the initial call 25 var anchor = window.location.hash.substr(1); 26 if (anchor) 27 autoexpand = anchor.split("/"); 28 } 29 30 var autoexpand_expander = null; 19 31 rows.each(function () { 20 32 var a = $(this).find("a.dir"); 21 33 … … 26 38 $(this).addClass(folderid); 27 39 28 40 // add the expander icon 29 a.wrap('<div></div>'); 30 var expander = a.before('<span class="expander"> </span>').prev(); 31 expander.attr("title", "Expand sub-directory in place") 32 .click(function() { toggleDir($(this), qargs); }); 41 var expander = $('<span class="expander"> </span>') 42 .attr("title", "Expand sub-directory in place") 43 .click(function() { toggleDir($(this), qargs); }) 44 a.wrap('<div></div>').before(expander); 45 if (autoexpand && a.text() == autoexpand[0]) 46 autoexpand_expander = expander; 33 47 } 34 48 35 49 // tie that row to ancestor folders 36 50 if (parent_tr) 37 51 $(this).addClass(ancestor_folderids.join(" ")); 38 52 }); 53 54 if ( autoexpand_expander ) 55 toggleDir(autoexpand_expander, qargs, autoexpand.slice(1)); 39 56 } 40 57 41 58 // handler for click event on the expander icons 42 window.toggleDir = function(expander, qargs ) {59 window.toggleDir = function(expander, qargs, autoexpand) { 43 60 var tr = expander.parents("tr:first"); 44 61 var folderid = tr.get(0).id; 45 62 46 if ( tr.filter(".expanded").length ) { // then *fold* 47 tr.removeClass("expanded").addClass("collapsed"); 48 tr.siblings("tr."+folderid).hide(); 63 if ( tr.hasClass("expanded") ) { // then *fold* 64 tr.removeClass("expanded"); 65 if (tr.next().hasClass("error")) { 66 tr.next().remove(); 67 } else { 68 tr.addClass("collapsed"); 69 tr.siblings("tr."+folderid).hide(); 70 } 49 71 expander.attr("title", "Re-expand directory"); 50 72 return; 51 73 } 52 53 if ( tr.filter(".collapsed").length ) { // then *expand* 74 75 // update location, unless autoexpand in progress 76 var a = expander.next("a"); 77 if ( !autoexpand ) 78 window.location.hash = a.attr("href") 79 .substr(window.location.pathname.length+1) 80 .replace(/([^?]*)(\?.*)?$/, '$1'); 81 82 if ( tr.hasClass("collapsed") ) { // then *expand* 54 83 tr.removeClass("collapsed").addClass("expanded"); 55 84 tr.siblings("tr."+folderid).show(); 56 // Note that the above will show all the already fetched subtree ,85 // Note that the above will show all the already fetched subtrees, 57 86 // so we have to fold again the folders which were already collapsed. 58 87 tr.siblings("tr.collapsed").each(function() { 59 88 tr.siblings("tr."+this.id).not(this).hide(); … … 61 90 } else { // then *fetch* 62 91 var td = expander.parents("td"); 63 92 var td_class = td.attr("class"); 64 var a = expander.next("a");65 93 var depth = 66 94 parseFloat(td.css("padding-left").replace(/^(\d*\.\d*).*$/, "$1")) + 67 95 SUBFOLDER_INDENT; 68 96 69 97 tr.addClass("expanded"); 70 98 // insert "Loading ..." row 71 tr.after('<tr><td><span class="loading"></span></td></tr>'); 72 var loading_row = tr.next(); 73 loading_row.children("td").addClass(td_class) 74 .attr("colspan", tr.children("td").length) 75 .css("padding-left", depth); 76 loading_row.find("span.loading").text("Loading " + a.text() + "..."); 99 var loading_row = $($.template( 100 '<tr>'+ 101 ' <td class="$td_class" colspan="$colspan" '+ 102 ' style="padding-left: ${depth}px">'+ 103 ' <span class="loading">Loading $entry...</span>'+ 104 ' </td>'+ 105 '</tr>', { 106 td_class: td_class, 107 colspan: tr.children("td").length, 108 depth: depth, 109 entry: a.text() 110 })); 111 tr.after(loading_row); 77 112 78 113 // XHR for getting the rows corresponding to the folder entries 79 114 $.ajax({ … … 91 126 row = $(this+"</tr>"); 92 127 row.children("td."+td_class).css("padding-left", depth); 93 128 // make all entry rows collapsible but only subdir rows expandable 94 enableExpandDir(tr, row, qargs);95 129 loading_row.before(row); 130 enableExpandDir(tr, row, qargs, autoexpand); 96 131 }); 97 132 // remove "Loading ..." row 98 133 loading_row.remove(); 99 134 } else { 100 loading_row.find("span.loading").text("").append("<i>(empty)</i>") 101 .removeClass("loading"); 102 // make the (empty) row collapsible 103 enableExpandDir(tr, loading_row, qargs); 135 loading_row.find("span.loading") 136 .text("").append("<i>(empty)</i>").removeClass("loading"); 137 enableExpandDir(tr, loading_row, qargs); // make it collapsible 104 138 } 105 139 }, 106 140 error: function(req, err, exc) { 107 loading_row.find("span.loading").text("").append("<i>(error)</i>") 108 .removeClass("loading"); 109 enableExpandDir(tr, loading_row, qargs); 141 loading_row.find("span.loading") 142 .text("").append("<i>(error)</i>").removeClass("loading"); 143 loading_row.addClass("error"); 144 enableExpandDir(tr, loading_row, qargs); // make it collapsible 110 145 } 111 146 }); 112 147 }
