diff --git a/src/applications/differential/controller/DifferentialChangesetViewController.php b/src/applications/differential/controller/DifferentialChangesetViewController.php
index 437cd66d22..3a3e7883ca 100644
--- a/src/applications/differential/controller/DifferentialChangesetViewController.php
+++ b/src/applications/differential/controller/DifferentialChangesetViewController.php
@@ -157,6 +157,11 @@ final class DifferentialChangesetViewController extends DifferentialController {
$parser->setLeftSideCommentMapping($left_source, $left_new);
$parser->setWhitespaceMode($request->getStr('whitespace'));
+ if ($request->getStr('renderer') == '1up') {
+ $parser->setRenderer(new DifferentialChangesetOneUpRenderer());
+ }
+
+
if ($left && $right) {
$parser->setOriginals($left, $right);
}
diff --git a/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php b/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php
index 919f753231..5ab1fa07b2 100644
--- a/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php
+++ b/src/applications/differential/render/DifferentialChangesetOneUpRenderer.php
@@ -7,15 +7,61 @@ final class DifferentialChangesetOneUpRenderer
return true;
}
- public function renderChangesetTable($contents) {
- throw new Exception("Not implemented!");
- }
-
public function renderTextChange(
$range_start,
$range_len,
$rows) {
- throw new Exception("Not implemented!");
+
+ $primitives = $this->buildPrimitives($range_start, $range_len);
+
+ $out = array();
+ foreach ($primitives as $p) {
+ $type = $p['type'];
+ switch ($type) {
+ case 'old':
+ case 'new':
+ $out[] = '
';
+ if ($type == 'old') {
+ if ($p['htype']) {
+ $class = 'left old';
+ } else {
+ $class = 'left';
+ }
+ $out[] = ''.$p['line'].' | ';
+ $out[] = ' | ';
+ $out[] = ''.$p['render'].' | ';
+ } else if ($type == 'new') {
+ if ($p['htype']) {
+ $class = 'right new';
+ $out[] = ' | ';
+ } else {
+ $class = 'right';
+ $out[] = ''.$p['oline'].' | ';
+ }
+ $out[] = ''.$p['line'].' | ';
+ $out[] = ''.$p['render'].' | ';
+ }
+ $out[] = '
';
+ break;
+ case 'inline':
+ $out[] = ' | | ';
+ $out[] = '';
+
+ $out[] = 'INLINE COMMENT ';
+ $out[] = phutil_escape_html($p['comment']->getContent());
+
+ $out[] = ' |
';
+ break;
+ default:
+ $out[] = ' | | '.$type.' |
';
+ break;
+ }
+ }
+
+ if ($out) {
+ return $this->wrapChangeInTable(implode('', $out));
+ }
+ return null;
}
public function renderFileChange($old_file = null,
diff --git a/src/applications/differential/render/DifferentialChangesetRenderer.php b/src/applications/differential/render/DifferentialChangesetRenderer.php
index 6424d96da9..b592e988eb 100644
--- a/src/applications/differential/render/DifferentialChangesetRenderer.php
+++ b/src/applications/differential/render/DifferentialChangesetRenderer.php
@@ -356,6 +356,7 @@ abstract class DifferentialChangesetRenderer {
'htype' => null,
'cursor' => $ii,
'line' => null,
+ 'oline' => null,
'render' => null,
);
@@ -364,13 +365,15 @@ abstract class DifferentialChangesetRenderer {
'htype' => null,
'cursor' => $ii,
'line' => null,
+ 'oline' => null,
'render' => null,
'copy' => null,
'coverage' => null,
);
if (isset($old[$ii])) {
- $ospec['line'] = $old[$ii]['line'];
+ $ospec['line'] = (int)$old[$ii]['line'];
+ $nspec['oline'] = (int)$old[$ii]['line'];
$ospec['htype'] = $old[$ii]['type'];
if (isset($old_render[$ii])) {
$ospec['render'] = $old_render[$ii];
@@ -378,7 +381,8 @@ abstract class DifferentialChangesetRenderer {
}
if (isset($new[$ii])) {
- $nspec['line'] = $new[$ii]['line'];
+ $nspec['line'] = (int)$new[$ii]['line'];
+ $ospec['oline'] = (int)$new[$ii]['line'];
$nspec['htype'] = $new[$ii]['type'];
if (isset($new_render[$ii])) {
$nspec['render'] = $new_render[$ii];
@@ -408,7 +412,7 @@ abstract class DifferentialChangesetRenderer {
foreach ($new_comments[$nspec['line']] as $comment) {
$primitives[] = array(
'type' => 'inline',
- 'comment' => 'comment',
+ 'comment' => $comment,
'right' => true,
);
}
@@ -445,6 +449,7 @@ abstract class DifferentialChangesetRenderer {
$new_buf = array();
foreach ($primitives as $primitive) {
$type = $primitive['type'];
+
if ($type == 'old') {
if (!$primitive['htype']) {
// This is a line which appears in both the old file and the new
@@ -475,11 +480,12 @@ abstract class DifferentialChangesetRenderer {
$new_buf = array();
$out[] = array($primitive);
} else if ($type == 'inline') {
- if ($primitive['right']) {
- $new_buf[] = $primitive;
- } else {
- $old_buf[] = $primitive;
- }
+ $out[] = $old_buf;
+ $out[] = $new_buf;
+ $old_buf = array();
+ $new_buf = array();
+
+ $out[] = array($primitive);
} else {
throw new Exception("Unknown primitive type '{$primitive}'!");
}
diff --git a/webroot/rsrc/js/application/core/behavior-device.js b/webroot/rsrc/js/application/core/behavior-device.js
index 40eca13e9c..df6d9c6cd5 100644
--- a/webroot/rsrc/js/application/core/behavior-device.js
+++ b/webroot/rsrc/js/application/core/behavior-device.js
@@ -10,40 +10,44 @@
JX.install('Device', {
statics : {
_device : null,
+ recalculate: function() {
+ var v = JX.Vector.getViewport();
+ var self = JX.Device;
+
+ var device = 'desktop';
+ if (v.x <= 768) {
+ device = 'tablet';
+ }
+ if (v.x <= 480) {
+ device = 'phone';
+ }
+
+ if (device == self._device) {
+ return;
+ }
+
+ self._device = device;
+
+ var e = document.body;
+ JX.DOM.alterClass(e, 'device-phone', (device == 'phone'));
+ JX.DOM.alterClass(e, 'device-tablet', (device == 'tablet'));
+ JX.DOM.alterClass(e, 'device-desktop', (device == 'desktop'));
+ JX.DOM.alterClass(e, 'device', (device != 'desktop'));
+
+ JX.Stratcom.invoke('phabricator-device-change', null, device);
+ },
+
getDevice : function() {
- return JX.Device._device;
+ var self = JX.Device;
+ if (self._device === null) {
+ self.recalculate();
+ }
+ return self._device;
}
}
});
JX.behavior('device', function() {
-
- function onresize() {
- var v = JX.Vector.getViewport();
-
- var device = 'desktop';
- if (v.x <= 768) {
- device = 'tablet';
- }
- if (v.x <= 480) {
- device = 'phone';
- }
-
- if (device == JX.Device.getDevice()) {
- return;
- }
-
- JX.Device._device = device;
-
- var e = document.body;
- JX.DOM.alterClass(e, 'device-phone', (device == 'phone'));
- JX.DOM.alterClass(e, 'device-tablet', (device == 'tablet'));
- JX.DOM.alterClass(e, 'device-desktop', (device == 'desktop'));
- JX.DOM.alterClass(e, 'device', (device != 'desktop'));
-
- JX.Stratcom.invoke('phabricator-device-change', null, device);
- }
-
- JX.Stratcom.listen('resize', null, onresize);
- onresize();
+ JX.Stratcom.listen('resize', null, JX.Device.recalculate);
+ JX.Device.recalculate();
});
diff --git a/webroot/rsrc/js/application/differential/behavior-populate.js b/webroot/rsrc/js/application/differential/behavior-populate.js
index 44b5786058..79c9732fa8 100644
--- a/webroot/rsrc/js/application/differential/behavior-populate.js
+++ b/webroot/rsrc/js/application/differential/behavior-populate.js
@@ -5,6 +5,7 @@
* javelin-util
* javelin-dom
* javelin-stratcom
+ * javelin-behavior-device
* phabricator-tooltip
*/
@@ -23,10 +24,16 @@ JX.behavior('differential-populate', function(config) {
}
}
+ // NOTE: If you load the page at one device resolution and then resize to
+ // a different one we don't re-render the diffs, because it's a complicated
+ // mess and you could lose inline comments, cursor positions, etc.
+ var renderer = (JX.Device.getDevice() == 'desktop') ? '2up' : '1up';
+
for (var k in config.registry) {
var data = {
ref : config.registry[k],
- whitespace: config.whitespace
+ whitespace: config.whitespace,
+ renderer: renderer
};
new JX.Workflow(config.uri, data)