Commit fcf1de7e by Alexander Makarov

Merge pull request #2173 from yiisoft/gii-diff-do-not-copy-line-numbers

Fixes #1897
parents 1b4cec66 d4dd5548
...@@ -8,6 +8,7 @@ Yii Framework 2 gii extension Change Log ...@@ -8,6 +8,7 @@ Yii Framework 2 gii extension Change Log
- Bug: fixed controller in crud template to avoid returning query in findModel() (cebe) - Bug: fixed controller in crud template to avoid returning query in findModel() (cebe)
- Enh #1624: generate rules for unique indexes (lucianobaraglia) - Enh #1624: generate rules for unique indexes (lucianobaraglia)
- Enh #1818: Do not display checkbox column if all rows are empty (johonunu) - Enh #1818: Do not display checkbox column if all rows are empty (johonunu)
- Enh #1897: diff markup is now copy paste friendly (samdark)
2.0.0 alpha, December 1, 2013 2.0.0 alpha, December 1, 2013
----------------------------- -----------------------------
......
...@@ -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\\": "" }
......
...@@ -126,6 +126,7 @@ Yii Framework 2 Change Log ...@@ -126,6 +126,7 @@ Yii Framework 2 Change Log
- Chg #2063: Removed `yii\web\Request::acceptTypes` and renamed `yii\web\Request::acceptedContentTypes` to `acceptableContentTypes` (qiangxue) - Chg #2063: Removed `yii\web\Request::acceptTypes` and renamed `yii\web\Request::acceptedContentTypes` to `acceptableContentTypes` (qiangxue)
- Chg #2157: The '*' category pattern will match all categories that do not match any other patterns listed in `I18N::translations` (qiangxue, Ragazzo) - Chg #2157: The '*' category pattern will match all categories that do not match any other patterns listed in `I18N::translations` (qiangxue, Ragazzo)
- Chg #2161: Added ability to use `return` in `Widget::run` (samdark) - Chg #2161: Added ability to use `return` in `Widget::run` (samdark)
- Chg #2173: Removed `StringHelper::diff()`, Moved `phpspec/php-diff` dependency from `yiisoft/yii2` to `yiisoft/yii2-gii` (samdark)
- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue) - Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
- Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue) - Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue)
- Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue) - Chg: Renamed `attributeName` and `className` to `targetAttribute` and `targetClass` for `UniqueValidator` and `ExistValidator` (qiangxue)
......
...@@ -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