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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /**
  3. * Side by Side HTML diff generator for PHP DiffLib.
  4. *
  5. * PHP version 5
  6. *
  7. * Copyright (c) 2009 Chris Boulton <chris.boulton@interspire.com>
  8. *
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * - Neither the name of the Chris Boulton nor the names of its contributors
  20. * may be used to endorse or promote products derived from this software
  21. * without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. * @package DiffLib
  36. * @author Chris Boulton <chris.boulton@interspire.com>
  37. * @copyright (c) 2009 Chris Boulton
  38. * @license New BSD License http://www.opensource.org/licenses/bsd-license.php
  39. * @version 1.1
  40. * @link http://github.com/chrisboulton/php-diff
  41. */
  42. require_once dirname(__FILE__).'/Array.php';
  43. class Diff_Renderer_Html_SideBySide extends Diff_Renderer_Html_Array
  44. {
  45. /**
  46. * Render a and return diff with changes between the two sequences
  47. * displayed side by side.
  48. *
  49. * @return string The generated side by side diff.
  50. */
  51. public function render()
  52. {
  53. $changes = parent::render();
  54. $html = '';
  55. if(empty($changes)) {
  56. return $html;
  57. }
  58. $html .= '<table class="Differences DifferencesSideBySide">';
  59. $html .= '<thead>';
  60. $html .= '<tr>';
  61. $html .= '<th colspan="2">Old Version</th>';
  62. $html .= '<th colspan="2">New Version</th>';
  63. $html .= '</tr>';
  64. $html .= '</thead>';
  65. foreach($changes as $i => $blocks) {
  66. if($i > 0) {
  67. $html .= '<tbody class="Skipped">';
  68. $html .= '<th>&hellip;</th><td>&nbsp;</td>';
  69. $html .= '<th>&hellip;</th><td>&nbsp;</td>';
  70. $html .= '</tbody>';
  71. }
  72. foreach($blocks as $change) {
  73. $html .= '<tbody class="Change'.ucfirst($change['tag']).'">';
  74. // Equal changes should be shown on both sides of the diff
  75. if($change['tag'] == 'equal') {
  76. foreach($change['base']['lines'] as $no => $line) {
  77. $fromLine = $change['base']['offset'] + $no + 1;
  78. $toLine = $change['changed']['offset'] + $no + 1;
  79. $html .= '<tr>';
  80. $html .= '<th>'.$fromLine.'</th>';
  81. $html .= '<td class="Left"><span>'.$line.'</span>&nbsp;</td>';
  82. $html .= '<th>'.$toLine.'</th>';
  83. $html .= '<td class="Right"><span>'.$line.'</span>&nbsp;</td>';
  84. $html .= '</tr>';
  85. }
  86. }
  87. // Added lines only on the right side
  88. else if($change['tag'] == 'insert') {
  89. foreach($change['changed']['lines'] as $no => $line) {
  90. $toLine = $change['changed']['offset'] + $no + 1;
  91. $html .= '<tr>';
  92. $html .= '<th>&nbsp;</th>';
  93. $html .= '<td class="Left">&nbsp;</td>';
  94. $html .= '<th>'.$toLine.'</th>';
  95. $html .= '<td class="Right"><ins>'.$line.'</ins>&nbsp;</td>';
  96. $html .= '</tr>';
  97. }
  98. }
  99. // Show deleted lines only on the left side
  100. else if($change['tag'] == 'delete') {
  101. foreach($change['base']['lines'] as $no => $line) {
  102. $fromLine = $change['base']['offset'] + $no + 1;
  103. $html .= '<tr>';
  104. $html .= '<th>'.$fromLine.'</th>';
  105. $html .= '<td class="Left"><del>'.$line.'</del>&nbsp;</td>';
  106. $html .= '<th>&nbsp;</th>';
  107. $html .= '<td class="Right">&nbsp;</td>';
  108. $html .= '</tr>';
  109. }
  110. }
  111. // Show modified lines on both sides
  112. else if($change['tag'] == 'replace') {
  113. if(count($change['base']['lines']) >= count($change['changed']['lines'])) {
  114. foreach($change['base']['lines'] as $no => $line) {
  115. $fromLine = $change['base']['offset'] + $no + 1;
  116. $html .= '<tr>';
  117. $html .= '<th>'.$fromLine.'</th>';
  118. $html .= '<td class="Left"><span>'.$line.'</span>&nbsp;</td>';
  119. if(!isset($change['changed']['lines'][$no])) {
  120. $toLine = '&nbsp;';
  121. $changedLine = '&nbsp;';
  122. }
  123. else {
  124. $toLine = $change['base']['offset'] + $no + 1;
  125. $changedLine = '<span>'.$change['changed']['lines'][$no].'</span>';
  126. }
  127. $html .= '<th>'.$toLine.'</th>';
  128. $html .= '<td class="Right">'.$changedLine.'</td>';
  129. $html .= '</tr>';
  130. }
  131. }
  132. else {
  133. foreach($change['changed']['lines'] as $no => $changedLine) {
  134. if(!isset($change['base']['lines'][$no])) {
  135. $fromLine = '&nbsp;';
  136. $line = '&nbsp;';
  137. }
  138. else {
  139. $fromLine = $change['base']['offset'] + $no + 1;
  140. $line = '<span>'.$change['base']['lines'][$no].'</span>';
  141. }
  142. $html .= '<tr>';
  143. $html .= '<th>'.$fromLine.'</th>';
  144. $html .= '<td class="Left"><span>'.$line.'</span>&nbsp;</td>';
  145. $toLine = $change['changed']['offset'] + $no + 1;
  146. $html .= '<th>'.$toLine.'</th>';
  147. $html .= '<td class="Right">'.$changedLine.'</td>';
  148. $html .= '</tr>';
  149. }
  150. }
  151. }
  152. $html .= '</tbody>';
  153. }
  154. }
  155. $html .= '</table>';
  156. return $html;
  157. }
  158. }