Initial implementation of javascript drilldown tree
Initial implementation of javascript drilldown tree

--- a/css/gitphp.css
+++ b/css/gitphp.css
@@ -46,7 +46,6 @@
 tr.dark:hover { background-color:#edece6; }
 td { padding:2px 5px; font-size:12px; vertical-align:top; }
 td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
-td.filesize { text-align: right; }
 div.pre { font-family:monospace; font-size:12px; white-space:pre; }
 div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
 div.index_header { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
@@ -158,4 +157,9 @@
 #blobData .de1, #blobData .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
 #blobData  {font-family:monospace;}
 #blobData li, #blobData .li1 {font-weight: normal; vertical-align:top;}
+table.treeTable { padding: 0px 0px; width: 600px; }
+table.treeTable td.subTree { padding:0px 0px; }
+table.treeTable td.perms { width: 75px; }
+table.treeTable td.filesize { text-align: right; width: 40px; }
+table.treeTable td.link { width: 125px; text-align: right; }
 

--- a/include/controller/Controller_Tree.class.php
+++ b/include/controller/Controller_Tree.class.php
@@ -45,6 +45,9 @@
 	 */
 	protected function GetTemplate()
 	{
+		if (isset($this->params['js']) && $this->params['js']) {
+			return 'treelist.tpl';
+		}
 		return 'tree.tpl';
 	}
 
@@ -97,6 +100,11 @@
 		if (!(isset($this->params['hashbase']) || isset($this->params['hash']))) {
 			$this->params['hashbase'] = 'HEAD';
 		}
+
+		if (isset($_GET['o']) && ($_GET['o'] == 'js')) {
+			$this->params['js'] = true;
+			GitPHP_Log::GetInstance()->SetEnabled(false);
+		}
 	}
 
 	/**
@@ -133,6 +141,8 @@
 			$tree->SetPath($this->params['file']);
 		}
 		$this->tpl->assign('tree', $tree);
+
+		$this->tpl->assign('extrascripts', array('js/tree.js'));
 	}
 
 }

file:b/js/tree.js (new)
--- /dev/null
+++ b/js/tree.js
@@ -1,1 +1,68 @@
+/*
+ * GitPHP javascript tree
+ * 
+ * Load subtree data into tree page asynchronously
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Javascript
+ */
 
+function initTree() {
+	var project = window.location.href.match(/p=([^&]+)/);
+	if (!project) {
+		return;
+	}
+	project = unescape(project[1]);
+
+	$('a.jsTree').live('click', function() {
+		var treeHash = $(this).attr('href').match(/h=([0-9a-fA-F]{40}|HEAD)/);
+		if (!treeHash) {
+			return;
+		}
+
+		treeHash = treeHash[1];
+
+		var treeTable = $('table#' + treeHash);
+		if (treeTable && treeTable.size() > 0) {
+			if (treeTable.is(':visible'))
+				treeTable.slideUp('fast');
+			else
+				treeTable.slideDown('fast');
+		} else {
+			var row = jQuery(document.createElement('tr'));
+
+			var cell = jQuery(document.createElement('td'));
+			cell.attr('colspan', '4');
+			cell.attr('id', 'td' + treeHash);
+			cell.addClass('subTree');
+			cell.appendTo(row);
+
+			$(this).parent().parent().after(row);
+
+			var par = $(this).parent();
+			var htm = par.html();
+			var indent = par.html().match(/^(—+)/);
+			if (indent)
+				indent = indent[1];
+			else
+				indent = '';
+			indent += '—';
+
+			$.get($(this).attr('href'), { o: 'js' },
+			function(data) {
+				var subTable = jQuery(data);
+				subTable.find('td.fileName').prepend(indent);
+				$('#td' + treeHash).html(subTable);
+			});
+		}
+
+		return false;
+	});
+}
+
+$(document).ready(function() {
+	initTree();
+});
+

--- a/templates/tree.tpl
+++ b/templates/tree.tpl
@@ -19,9 +19,7 @@
  
  <div class="page_body">
    {* List files *}
-   <table cellspacing="0">
      {include file='treelist.tpl'}
-   </table>
  </div>
 
  {include file='footer.tpl'}

--- a/templates/treelist.tpl
+++ b/templates/treelist.tpl
@@ -9,12 +9,13 @@
  * @subpackage Template
  *}
 
+<table cellspacing="0" id="{$tree->GetHash()}" class="treeTable">
 {foreach from=$tree->GetContents() item=treeitem}
   <tr class="{cycle values="light,dark"}">
-    <td class="monospace">{$treeitem->GetModeString()}</td>
+    <td class="monospace perms">{$treeitem->GetModeString()}</td>
     {if $treeitem instanceof GitPHP_Blob}
       <td class="filesize">{$treeitem->GetSize()}</td>
-      <td class="list">
+      <td class="list fileName">
         <a href="{$SCRIPT_NAME}?p={$project->GetProject()|urlencode}&amp;a=blob&amp;h={$treeitem->GetHash()}&amp;hb={$commit->GetHash()}&amp;f={$treeitem->GetPath()}" class="list">{$treeitem->GetName()}</a>
       </td>
       <td class="link">
@@ -25,9 +26,9 @@
 	<a href="{$SCRIPT_NAME}?p={$project->GetProject()|urlencode}&amp;a=blob_plain&amp;h={$treeitem->GetHash()}&amp;f={$treeitem->GetPath()}">{t}plain{/t}</a>
       </td>
     {elseif $treeitem instanceof GitPHP_Tree}
-      <td></td>
-      <td class="list">
-        <a href="{$SCRIPT_NAME}?p={$project->GetProject()|urlencode}&amp;a=tree&amp;h={$treeitem->GetHash()}&amp;hb={$commit->GetHash()}&amp;f={$treeitem->GetPath()}">{$treeitem->GetName()}</a>
+      <td class="filesize"></td>
+      <td class="list fileName">
+        <a href="{$SCRIPT_NAME}?p={$project->GetProject()|urlencode}&amp;a=tree&amp;h={$treeitem->GetHash()}&amp;hb={$commit->GetHash()}&amp;f={$treeitem->GetPath()}" class="jsTree">{$treeitem->GetName()}</a>
       </td>
       <td class="link">
         <a href="{$SCRIPT_NAME}?p={$project->GetProject()|urlencode}&amp;a=tree&amp;h={$treeitem->GetHash()}&amp;hb={$commit->GetHash()}&amp;f={$treeitem->GetPath()}">{t}tree{/t}</a>
@@ -37,4 +38,5 @@
     {/if}
   </tr>
 {/foreach}
+</table>
 

comments