Commit a37b35a4 by Alexander Makarov

Fixes #1897

- Gii diff markup is now copy paste friendly - Removed StringHelper::diff() - Moved phpspec/php-diff dependency from yiisoft/yii2 to yiisoft/yii2-gii
parent 1b4cec66
...@@ -9,9 +9,9 @@ namespace yii\gii; ...@@ -9,9 +9,9 @@ namespace yii\gii;
use Yii; use Yii;
use yii\base\Object; use yii\base\Object;
use yii\gii\components\DiffRendererHtmlInline;
use yii\gii\components\TextDiff; use yii\gii\components\TextDiff;
use yii\helpers\Html; use yii\helpers\Html;
use yii\helpers\StringHelper;
/** /**
* CodeFile represents a code file to be generated. * CodeFile represents a code file to be generated.
...@@ -147,9 +147,29 @@ class CodeFile extends Object ...@@ -147,9 +147,29 @@ class CodeFile extends Object
if (in_array($type, ['jpg', 'gif', 'png', 'exe'])) { if (in_array($type, ['jpg', 'gif', 'png', 'exe'])) {
return false; return false;
} elseif ($this->operation === self::OP_OVERWRITE) { } elseif ($this->operation === self::OP_OVERWRITE) {
return StringHelper::diff(file($this->path), $this->content); return $this->renderDiff(file($this->path), $this->content);
} else { } else {
return ''; return '';
} }
} }
private function renderDiff($lines1, $lines2)
{
if (!is_array($lines1)) {
$lines1 = explode("\n", $lines1);
}
if (!is_array($lines2)) {
$lines2 = explode("\n", $lines2);
}
foreach ($lines1 as $i => $line) {
$lines1[$i] = rtrim($line, "\r\n");
}
foreach ($lines2 as $i => $line) {
$lines2[$i] = rtrim($line, "\r\n");
}
$renderer = new DiffRendererHtmlInline();
$diff = new \Diff($lines1, $lines2);
return $diff->render($renderer);
}
} }
...@@ -148,10 +148,6 @@ body { ...@@ -148,10 +148,6 @@ body {
font-weight: normal; font-weight: normal;
color: #999; color: #999;
width: 5px; width: 5px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
} }
.Differences td { .Differences td {
...@@ -214,6 +210,10 @@ body { ...@@ -214,6 +210,10 @@ body {
background: #e99; background: #e99;
} }
.DifferencesInline th[data-line-number]:before {
content: attr(data-line-number);
}
/* additional styles for typeahead.js-bootstrap.css */ /* additional styles for typeahead.js-bootstrap.css */
.twitter-typeahead { .twitter-typeahead {
display: block !important; display: block !important;
......
<?php
namespace yii\gii\components;
class DiffRendererHtmlInline extends \Diff_Renderer_Html_Array
{
/**
* Render a and return diff with changes between the two sequences
* displayed inline (under each other)
*
* @return string The generated inline diff.
*/
public function render()
{
$changes = parent::render();
$html = '';
if(empty($changes)) {
return $html;
}
$html .= '<table class="Differences DifferencesInline">';
$html .= '<thead>';
$html .= '<tr>';
$html .= '<th>Old</th>';
$html .= '<th>New</th>';
$html .= '<th>Differences</th>';
$html .= '</tr>';
$html .= '</thead>';
foreach($changes as $i => $blocks) {
// If this is a separate block, we're condensing code so output ...,
// indicating a significant portion of the code has been collapsed as
// it is the same
if($i > 0) {
$html .= '<tbody class="Skipped">';
$html .= '<th data-line-number="&hellip;"></th>';
$html .= '<th data-line-number="&hellip;"></th>';
$html .= '<td>&nbsp;</td>';
$html .= '</tbody>';
}
foreach($blocks as $change) {
$html .= '<tbody class="Change'.ucfirst($change['tag']).'">';
// Equal changes should be shown on both sides of the diff
if($change['tag'] == 'equal') {
foreach($change['base']['lines'] as $no => $line) {
$fromLine = $change['base']['offset'] + $no + 1;
$toLine = $change['changed']['offset'] + $no + 1;
$html .= '<tr>';
$html .= '<th data-line-number="'.$fromLine.'"></th>';
$html .= '<th data-line-number="'.$toLine.'"></th>';
$html .= '<td class="Left">'.$line.'</td>';
$html .= '</tr>';
}
}
// Added lines only on the right side
else if($change['tag'] == 'insert') {
foreach($change['changed']['lines'] as $no => $line) {
$toLine = $change['changed']['offset'] + $no + 1;
$html .= '<tr>';
$html .= '<th data-line-number="&nbsp;"></th>';
$html .= '<th data-line-number="'.$toLine.'"></th>';
$html .= '<td class="Right"><ins>'.$line.'</ins>&nbsp;</td>';
$html .= '</tr>';
}
}
// Show deleted lines only on the left side
else if($change['tag'] == 'delete') {
foreach($change['base']['lines'] as $no => $line) {
$fromLine = $change['base']['offset'] + $no + 1;
$html .= '<tr>';
$html .= '<th data-line-number="'.$fromLine.'"></th>';
$html .= '<th data-line-number="&nbsp;"></th>';
$html .= '<td class="Left"><del>'.$line.'</del>&nbsp;</td>';
$html .= '</tr>';
}
}
// Show modified lines on both sides
else if($change['tag'] == 'replace') {
foreach($change['base']['lines'] as $no => $line) {
$fromLine = $change['base']['offset'] + $no + 1;
$html .= '<tr>';
$html .= '<th data-line-number="'.$fromLine.'"></th>';
$html .= '<th data-line-number="&nbsp;"></th>';
$html .= '<td class="Left"><span>'.$line.'</span></td>';
$html .= '</tr>';
}
foreach($change['changed']['lines'] as $no => $line) {
$toLine = $change['changed']['offset'] + $no + 1;
$html .= '<tr>';
$html .= '<th data-line-number="'.$toLine.'"></th>';
$html .= '<th data-line-number="&nbsp;"></th>';
$html .= '<td class="Right"><span>'.$line.'</span></td>';
$html .= '</tr>';
}
}
$html .= '</tbody>';
}
}
$html .= '</table>';
return $html;
}
}
\ No newline at end of file
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
], ],
"require": { "require": {
"yiisoft/yii2": "*", "yiisoft/yii2": "*",
"yiisoft/yii2-bootstrap": "*" "yiisoft/yii2-bootstrap": "*",
"phpspec/php-diff": ">=1.0.2"
}, },
"autoload": { "autoload": {
"psr-4": { "yii\\gii\\": "" } "psr-4": { "yii\\gii\\": "" }
......
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
"lib-pcre": "*", "lib-pcre": "*",
"yiisoft/yii2-composer": "*", "yiisoft/yii2-composer": "*",
"yiisoft/jquery": "~2.0 | ~1.10", "yiisoft/jquery": "~2.0 | ~1.10",
"phpspec/php-diff": ">=1.0.2",
"ezyang/htmlpurifier": "4.6.*", "ezyang/htmlpurifier": "4.6.*",
"michelf/php-markdown": "1.3.*" "michelf/php-markdown": "1.3.*"
}, },
......
...@@ -88,53 +88,4 @@ class BaseStringHelper ...@@ -88,53 +88,4 @@ class BaseStringHelper
return ''; return '';
} }
} }
/**
* Compares two strings or string arrays, and return their differences.
* This is a wrapper of the [phpspec/php-diff](https://packagist.org/packages/phpspec/php-diff) package.
* @param string|array $lines1 the first string or string array to be compared. If it is a string,
* it will be converted into a string array by breaking at newlines.
* @param string|array $lines2 the second string or string array to be compared. If it is a string,
* it will be converted into a string array by breaking at newlines.
* @param string $format the output format. It must be 'inline', 'unified', 'context', 'side-by-side', or 'array'.
* @return string|array the comparison result. An array is returned if `$format` is 'array'. For all other
* formats, a string is returned.
* @throws InvalidParamException if the format is invalid.
*/
public static function diff($lines1, $lines2, $format = 'inline')
{
if (!is_array($lines1)) {
$lines1 = explode("\n", $lines1);
}
if (!is_array($lines2)) {
$lines2 = explode("\n", $lines2);
}
foreach ($lines1 as $i => $line) {
$lines1[$i] = rtrim($line, "\r\n");
}
foreach ($lines2 as $i => $line) {
$lines2[$i] = rtrim($line, "\r\n");
}
switch ($format) {
case 'inline':
$renderer = new \Diff_Renderer_Html_Inline();
break;
case 'array':
$renderer = new \Diff_Renderer_Html_Array();
break;
case 'side-by-side':
$renderer = new \Diff_Renderer_Html_SideBySide();
break;
case 'context':
$renderer = new \Diff_Renderer_Text_Context();
break;
case 'unified':
$renderer = new \Diff_Renderer_Text_Unified();
break;
default:
throw new InvalidParamException("Output format must be 'inline', 'side-by-side', 'array', 'context' or 'unified'.");
}
$diff = new \Diff($lines1, $lines2);
return $diff->render($renderer);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment