Allow side by side commitdiff TOC to show the chosen diff and hide the
Allow side by side commitdiff TOC to show the chosen diff and hide the
rest

--- a/css/gitphp.css
+++ b/css/gitphp.css
@@ -131,6 +131,14 @@
 	width: 50%;
 }
 
+/*
+ * side-by-side commitdiff
+ */
+div.commitDiffSBS div.SBSTOC .showAll
+{
+	display: none;
+}
+
 
 /*
  * Geshi styles

--- a/css/gitphpskin.css
+++ b/css/gitphpskin.css
@@ -400,6 +400,55 @@
 	border-right: 1px solid #d9d8d1;
 }
 
+/*
+ * side-by-side commitdiff
+ */
+div.commitDiffSBS
+{
+	width: 100%;
+	border-top: 2px solid #edece6;
+}
+
+div.commitDiffSBS div.SBSTOC
+{
+	float: left;
+	width: 19%;
+	word-wrap: break-word;
+}
+
+div.commitDiffSBS div.SBSTOC a
+{
+	text-decoration: none;
+}
+
+div.commitDiffSBS div.SBSTOC ul
+{
+	margin-left: 8px;
+	padding-left: 8px;
+}
+
+div.commitDiffSBS div.SBSTOC .listcount
+{
+	list-style-type: none;
+}
+
+div.commitDiffSBS div.SBSTOC .activeItem
+{
+	background-color: #edece6;
+}
+
+div.commitDiffSBS .SBSContent
+{
+	float: right;
+	width: 80%;
+	border-left: 1px solid #edece6;
+}
+
+div.commitDiffSBS .SBSFooter
+{
+	clear: both;
+}
+
 
 /*
  * Blob/blame display

--- a/include/controller/Controller_Commitdiff.class.php
+++ b/include/controller/Controller_Commitdiff.class.php
@@ -138,6 +138,7 @@
 
 		if (isset($this->params['sidebyside']) && ($this->params['sidebyside'] === true)) {
 			$this->tpl->assign('sidebyside', true);
+			$this->tpl->assign('extrascripts', array('commitdiff'));
 		}
 
 		$treediff = new GitPHP_TreeDiff($this->project, $this->params['hash'], (isset($this->params['hashparent']) ? $this->params['hashparent'] : ''));

--- a/include/git/FileDiff.class.php
+++ b/include/git/FileDiff.class.php
@@ -351,6 +351,38 @@
 	}
 
 	/**
+	 * GetFromBlob
+	 *
+	 * Gets the from file blob
+	 *
+	 * @access public
+	 * @return mixed blob object
+	 */
+	public function GetFromBlob()
+	{
+		if (empty($this->fromHash))
+			return null;
+
+		return $this->project->GetBlob($this->fromHash);
+	}
+
+	/**
+	 * GetToBlob
+	 *
+	 * Gets the to file blob
+	 *
+	 * @access public
+	 * @return mixed blob object
+	 */
+	public function GetToBlob()
+	{
+		if (empty($this->toHash))
+			return null;
+
+		return $this->project->GetBlob($this->toHash);
+	}
+
+	/**
 	 * GetStatus
 	 *
 	 * Gets the status of the change
@@ -556,7 +588,7 @@
 		$toName = null;
 
 		if ((empty($this->status)) || ($this->status == 'D') || ($this->status == 'M')) {
-			$fromBlob = $this->project->GetBlob($this->fromHash);
+			$fromBlob = $this->GetFromBlob();
 			$fromTmpFile = 'gitphp_' . $pid . '_from';
 			$tmpdir->AddFile($fromTmpFile, $fromBlob->GetData());
 
@@ -571,7 +603,7 @@
 		}
 
 		if ((empty($this->status)) || ($this->status == 'A') || ($this->status == 'M')) {
-			$toBlob = $this->project->GetBlob($this->toHash);
+			$toBlob = $this->GetToBlob();
 			$toTmpFile = 'gitphp_' . $pid . '_to';
 			$tmpdir->AddFile($toTmpFile, $toBlob->GetData());
 

file:b/js/commitdiff.js (new)
--- /dev/null
+++ b/js/commitdiff.js
@@ -1,1 +1,77 @@
+/*
+ * GitPHP javascript commitdiff
+ * 
+ * Javascript enhancements to make side-by-side
+ * commitdiff more usable
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2011 Christopher Han
+ * @package GitPHP
+ */
 
+var TOCYloc = null;
+var TOCposition = null;
+var TOCtop = null;
+
+function initSBSCommitDiff() {
+	var sbsTOC = $('div.commitDiffSBS div.SBSTOC');
+	if (sbsTOC.size() < 1) {
+		return;
+	}
+
+	TOCYloc = sbsTOC.position().top;
+	TOCposition = sbsTOC.css('position');
+	TOCtop = sbsTOC.css('top');
+	$(window).scroll(function() {
+		var windowYloc = $(document).scrollTop();
+		if (windowYloc > TOCYloc) {
+			sbsTOC.css('position', 'fixed');
+			sbsTOC.css('top', '0px');
+		} else {
+			sbsTOC.css('position', TOCposition);
+			sbsTOC.css('top', TOCtop);
+		}
+	});
+
+	$('a.SBSTOCItem').click(function() {
+		var clickedItem = $(this).get(0);
+		$('a.SBSTOCItem').each(function(index, value) {
+			if (clickedItem == value) {
+				$(this).parent().addClass('activeItem');
+			} else {
+				$(this).parent().removeClass('activeItem');
+			}
+		});
+		var clickedId = $(this).attr('href').substring(1);
+		$('div.diffBlob').each(function() {
+			if ($(this).attr('id') == clickedId) {
+				$(this).slideDown('fast');
+			} else {
+				$(this).slideUp('fast');
+			}
+		});
+		$('a.showAll').show();
+		if ($(document).scrollTop() > $('div.SBSContent').offset().top) {
+			$('html, body').animate({
+				scrollTop: $('div.SBSContent').offset().top
+			}, 200);
+		}
+		return false;
+	});
+	$('a.showAll').click(function() {
+		$('a.SBSTOCItem').parent().removeClass('activeItem');
+		$('div.diffBlob').slideDown('fast');
+		$(this).hide();
+		if ($(document).scrollTop() > $('div.SBSContent').offset().top) {
+			$('html, body').animate({
+				scrollTop: $('div.SBSContent').offset().top
+			}, 200);
+		}
+		return false;
+	});
+};
+
+$(document).ready(function() {
+	initSBSCommitDiff();
+});
+

--- a/templates/commitdiff.tpl
+++ b/templates/commitdiff.tpl
@@ -31,8 +31,46 @@
      {$line|htmlspecialchars|buglink:$bugpattern:$bugurl}<br />
    {/foreach}
    <br />
+
+   {if $sidebyside && ($treediff->Count() > 1)}
+    <div class="commitDiffSBS">
+
+     <div class="SBSTOC">
+       <ul>
+       <li class="listcount">
+       {t count=$treediff->Count() 1=$treediff->Count() plural="%1 files changed:"}%1 file changed:{/t} <a href="#" class="showAll">(show all)</a></li>
+       {foreach from=$treediff item=filediff}
+       <li>
+       <a href="#{$filediff->GetFromHash()}_{$filediff->GetToHash()}" class="SBSTOCItem">
+       {if $filediff->GetStatus() == 'A'}
+         {if $filediff->GetToFile()}{$filediff->GetToFile()}{else}{$filediff->GetToHash()}{/if} {t}(new){/t}
+       {elseif $filediff->GetStatus() == 'D'}
+         {if $filediff->GetFromFile()}{$filediff->GetFromFile()}{else}{$filediff->GetToFile()}{/if} {t}(deleted){/t}
+       {elseif $filediff->GetStatus() == 'M'}
+         {if $filediff->GetFromFile()}
+	   {assign var=fromfilename value=$filediff->GetFromFile()}
+	 {else}
+	   {assign var=fromfilename value=$filediff->GetFromHash()}
+	 {/if}
+	 {if $filediff->GetToFile()}
+	   {assign var=tofilename value=$filediff->GetToFile()}
+	 {else}
+	   {assign var=tofilename value=$filediff->GetToHash()}
+	 {/if}
+	 {$fromfilename}{if $fromfilename != $tofilename} -&gt; {$tofilename}{/if}
+       {/if}
+       </a>
+       </li>
+       {/foreach}
+       </ul>
+     </div>
+
+     <div class="SBSContent">
+   {/if}
+
    {* Diff each file changed *}
    {foreach from=$treediff item=filediff}
+     <div class="diffBlob" id="{$filediff->GetFromHash()}_{$filediff->GetToHash()}">
      <div class="diff_info">
      {if ($filediff->GetStatus() == 'D') || ($filediff->GetStatus() == 'M')}
        {assign var=localfromtype value=$filediff->GetFromFileType(1)}
@@ -60,7 +98,17 @@
      {else}
         {include file='filediff.tpl' diff=$filediff->GetDiff('', true, true)}
      {/if}
+     </div>
    {/foreach}
+
+   {if $sidebyside && ($treediff->Count() > 1)}
+     </div>
+     <div class="SBSFooter"></div>
+
+    </div>
+   {/if}
+
+
  </div>
 
  {include file='footer.tpl'}

--- a/templates/filediffsidebyside.tpl
+++ b/templates/filediffsidebyside.tpl
@@ -10,19 +10,37 @@
  * @subpackage Template
  *}
 <table class="diffTable">
-  {foreach from=$diffsplit item=lineinfo}
-    {if $lineinfo[0]=='added'}
-    <tr class="diff-added">
-    {elseif $lineinfo[0]=='deleted'}
-    <tr class="diff-deleted">
-    {elseif $lineinfo[0]=='modified'}
-    <tr class="diff-modified">
-    {else}
-    <tr>
-    {/if}
-      <td class="diff-left">{if $lineinfo[1]}{$lineinfo[1]|escape}{else}&nbsp;{/if}</td>
-      <td>{if $lineinfo[2]}{$lineinfo[2]|escape}{else}&nbsp;{/if}</td>
-    </tr>
-  {/foreach}
+  {if $filediff->GetStatus() == 'D'}
+    {assign var=delblob value=$filediff->GetFromBlob()}
+    {foreach from=$delblob->GetData(true) item=blobline}
+      <tr class="diff-deleted">
+        <td class="diff-left">{$blobline|escape}</td>
+	<td>&nbsp;</td>
+      </tr>
+    {/foreach}
+  {elseif $filediff->GetStatus() == 'A'}
+    {assign var=newblob value=$filediff->GetToBlob()}
+    {foreach from=$newblob->GetData(true) item=blobline}
+      <tr class="diff-added">
+        <td class="diff-left">&nbsp;</td>
+	<td>{$blobline|escape}</td>
+      </tr>
+    {/foreach}
+  {else}
+    {foreach from=$diffsplit item=lineinfo}
+      {if $lineinfo[0]=='added'}
+      <tr class="diff-added">
+      {elseif $lineinfo[0]=='deleted'}
+      <tr class="diff-deleted">
+      {elseif $lineinfo[0]=='modified'}
+      <tr class="diff-modified">
+      {else}
+      <tr>
+      {/if}
+        <td class="diff-left">{if $lineinfo[1]}{$lineinfo[1]|escape}{else}&nbsp;{/if}</td>
+        <td>{if $lineinfo[2]}{$lineinfo[2]|escape}{else}&nbsp;{/if}</td>
+      </tr>
+    {/foreach}
+  {/if}
 </table>
 

comments