You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

117 lines
4.4 KiB

  1. // Enable expanding/folding folders in TracBrowser
  2. (function($){
  3. var FOLDERID_COUNTER = 0;
  4. var SUBFOLDER_INDENT = 20;
  5. // enableExpandDir adds the capability to folder rows to be expanded and folded
  6. // It also teach the rows about their ancestors. It expects:
  7. // - `parent_tr`, the logical parent row (`null` if there's no ancestor)
  8. // - a `rows` jQuery object matching the newly created entry rows
  9. // - `qargs`, additional parameters to send to the server when expanding
  10. window.enableExpandDir = function(parent_tr, rows, qargs) {
  11. // the ancestors folder ids are present in the parent_tr class attribute
  12. var ancestor_folderids = [];
  13. if (parent_tr)
  14. ancestor_folderids = $.grep(parent_tr.attr("class").split(" "),
  15. function(c) { return c.match(/^f\d+$/)});
  16. rows.each(function () {
  17. var a = $(this).find("a.dir");
  18. if (a.length) { // then the entry is a folder
  19. // create new folder id
  20. var folderid = "f" + FOLDERID_COUNTER++;
  21. this.id = folderid;
  22. $(this).addClass(folderid);
  23. // add the expander icon
  24. a.wrap('<div></div>');
  25. var expander = a.before('<span class="expander">&nbsp;</span>').prev();
  26. expander.attr("title", "Expand sub-directory in place")
  27. .click(function() { toggleDir($(this), qargs); });
  28. }
  29. // tie that row to ancestor folders
  30. if (parent_tr)
  31. $(this).addClass(ancestor_folderids.join(" "));
  32. });
  33. }
  34. // handler for click event on the expander icons
  35. window.toggleDir = function(expander, qargs) {
  36. var tr = expander.parents("tr");
  37. var folderid = tr.get(0).id;
  38. if ( tr.filter(".expanded").length ) { // then *fold*
  39. tr.removeClass("expanded").addClass("collapsed");
  40. tr.siblings("tr."+folderid).hide();
  41. expander.attr("title", "Re-expand directory");
  42. return;
  43. }
  44. if ( tr.filter(".collapsed").length ) { // then *expand*
  45. tr.removeClass("collapsed").addClass("expanded");
  46. tr.siblings("tr."+folderid).show();
  47. // Note that the above will show all the already fetched subtree,
  48. // so we have to fold again the folders which were already collapsed.
  49. tr.siblings("tr.collapsed").each(function() {
  50. tr.siblings("tr."+this.id).not(this).hide();
  51. });
  52. } else { // then *fetch*
  53. var td = expander.parents("td");
  54. var td_class = td.attr("class");
  55. var a = expander.next("a");
  56. var depth =
  57. parseFloat(td.css("padding-left").replace(/^(\d*\.\d*).*$/, "$1")) +
  58. SUBFOLDER_INDENT;
  59. tr.addClass("expanded");
  60. // insert "Loading ..." row
  61. tr.after('<tr><td><span class="loading"></span></td></tr>');
  62. var loading_row = tr.next();
  63. loading_row.children("td").addClass(td_class)
  64. .attr("colspan", tr.children("td").length)
  65. .css("padding-left", depth);
  66. loading_row.find("span.loading").text("Loading " + a.text() + "...");
  67. // XHR for getting the rows corresponding to the folder entries
  68. $.ajax({
  69. type: "GET",
  70. url: a.attr("href"),
  71. data: qargs,
  72. dataType: "html",
  73. success: function(data) {
  74. // Safari 3.1.1 has some trouble reconstructing HTML snippets
  75. // bigger than 50k - splitting in rows before building DOM nodes
  76. var rows = data.replace(/^<!DOCTYPE[^>]+>/, "").split("</tr>");
  77. if (rows.length) {
  78. // insert entry rows
  79. $(rows).each(function() {
  80. row = $(this+"</tr>");
  81. row.children("td."+td_class).css("padding-left", depth);
  82. // make all entry rows collapsible but only subdir rows expandable
  83. enableExpandDir(tr, row, qargs);
  84. loading_row.before(row);
  85. });
  86. // remove "Loading ..." row
  87. loading_row.remove();
  88. } else {
  89. loading_row.find("span.loading").text("").append("<i>(empty)</i>")
  90. .removeClass("loading");
  91. // make the (empty) row collapsible
  92. enableExpandDir(tr, loading_row, qargs);
  93. }
  94. },
  95. error: function(req, err, exc) {
  96. loading_row.find("span.loading").text("").append("<i>(error)</i>")
  97. .removeClass("loading");
  98. enableExpandDir(tr, loading_row, qargs);
  99. }
  100. });
  101. }
  102. expander.attr("title", "Fold directory");
  103. }
  104. })(jQuery);