mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-23 07:12:41 +01:00
When deleting inline comments, offer "undo" instead of prompting
Summary: Ref T2009. Ref T1460. Fixes T2618. When users hit "Delete" on inline comments, delete immediately and offer them "Undo". If they delete indirectly (e.g., by clicking "Delete" from the preview at the bottom of the page), we still prompt them, because the "Undo" action either won't be available or may not be easy to find. This is a "refdelete". Fixes T6464. This was just a mess. Make it not as much of a mess. It should work now. Pretty sure. Fixes T4999. We did not refresh these links often enough to find targets for them, so they could race with content. Reevaluate them after loading new changes. Test Plan: - Deleted and undid deletion of inlines from main view and preview. - Clicked "View" on inlines. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6464, T4999, T2618, T1460, T2009 Differential Revision: https://secure.phabricator.com/D12032
This commit is contained in:
parent
daa893e508
commit
dd501117e8
10 changed files with 220 additions and 131 deletions
|
@ -11,7 +11,7 @@ return array(
|
||||||
'core.pkg.js' => '5a1c336d',
|
'core.pkg.js' => '5a1c336d',
|
||||||
'darkconsole.pkg.js' => '8ab24e01',
|
'darkconsole.pkg.js' => '8ab24e01',
|
||||||
'differential.pkg.css' => '1940be3f',
|
'differential.pkg.css' => '1940be3f',
|
||||||
'differential.pkg.js' => '2b14c4a1',
|
'differential.pkg.js' => 'e62fe1cf',
|
||||||
'diffusion.pkg.css' => '591664fa',
|
'diffusion.pkg.css' => '591664fa',
|
||||||
'diffusion.pkg.js' => 'bfc0737b',
|
'diffusion.pkg.js' => 'bfc0737b',
|
||||||
'maniphest.pkg.css' => '68d4dd3d',
|
'maniphest.pkg.css' => '68d4dd3d',
|
||||||
|
@ -360,14 +360,14 @@ return array(
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '82439934',
|
'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '82439934',
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
|
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
|
||||||
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
|
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
|
||||||
'rsrc/js/application/differential/ChangesetViewManager.js' => 'a9af1212',
|
'rsrc/js/application/differential/ChangesetViewManager.js' => '88be0133',
|
||||||
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'd3aa4b40',
|
'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => '1b772f31',
|
||||||
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => 'e10f8e18',
|
'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => 'e10f8e18',
|
||||||
'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d',
|
'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d',
|
||||||
'rsrc/js/application/differential/behavior-comment-preview.js' => '6932def3',
|
'rsrc/js/application/differential/behavior-comment-preview.js' => '8e1389b5',
|
||||||
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
|
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
|
||||||
'rsrc/js/application/differential/behavior-dropdown-menus.js' => '2035b9cb',
|
'rsrc/js/application/differential/behavior-dropdown-menus.js' => '2035b9cb',
|
||||||
'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '7378d48a',
|
'rsrc/js/application/differential/behavior-edit-inline-comments.js' => 'a48aa699',
|
||||||
'rsrc/js/application/differential/behavior-keyboard-nav.js' => '2c426492',
|
'rsrc/js/application/differential/behavior-keyboard-nav.js' => '2c426492',
|
||||||
'rsrc/js/application/differential/behavior-populate.js' => '8694b1df',
|
'rsrc/js/application/differential/behavior-populate.js' => '8694b1df',
|
||||||
'rsrc/js/application/differential/behavior-show-field-details.js' => 'bba9eedf',
|
'rsrc/js/application/differential/behavior-show-field-details.js' => 'bba9eedf',
|
||||||
|
@ -509,7 +509,7 @@ return array(
|
||||||
'aphront-two-column-view-css' => '16ab3ad2',
|
'aphront-two-column-view-css' => '16ab3ad2',
|
||||||
'aphront-typeahead-control-css' => '0e403212',
|
'aphront-typeahead-control-css' => '0e403212',
|
||||||
'auth-css' => '1e655982',
|
'auth-css' => '1e655982',
|
||||||
'changeset-view-manager' => 'a9af1212',
|
'changeset-view-manager' => '88be0133',
|
||||||
'config-options-css' => '7fedf08b',
|
'config-options-css' => '7fedf08b',
|
||||||
'config-welcome-css' => '6abd79be',
|
'config-welcome-css' => '6abd79be',
|
||||||
'conpherence-durable-column-view' => '9207426d',
|
'conpherence-durable-column-view' => '9207426d',
|
||||||
|
@ -520,7 +520,7 @@ return array(
|
||||||
'conpherence-widget-pane-css' => '3d575438',
|
'conpherence-widget-pane-css' => '3d575438',
|
||||||
'differential-changeset-view-css' => '6a8b172a',
|
'differential-changeset-view-css' => '6a8b172a',
|
||||||
'differential-core-view-css' => '7ac3cabc',
|
'differential-core-view-css' => '7ac3cabc',
|
||||||
'differential-inline-comment-editor' => 'd3aa4b40',
|
'differential-inline-comment-editor' => '1b772f31',
|
||||||
'differential-results-table-css' => '181aa9d9',
|
'differential-results-table-css' => '181aa9d9',
|
||||||
'differential-revision-add-comment-css' => 'c478bcaa',
|
'differential-revision-add-comment-css' => 'c478bcaa',
|
||||||
'differential-revision-comment-css' => '48186045',
|
'differential-revision-comment-css' => '48186045',
|
||||||
|
@ -569,8 +569,8 @@ return array(
|
||||||
'javelin-behavior-differential-comment-jump' => '4fdb476d',
|
'javelin-behavior-differential-comment-jump' => '4fdb476d',
|
||||||
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
|
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
|
||||||
'javelin-behavior-differential-dropdown-menus' => '2035b9cb',
|
'javelin-behavior-differential-dropdown-menus' => '2035b9cb',
|
||||||
'javelin-behavior-differential-edit-inline-comments' => '7378d48a',
|
'javelin-behavior-differential-edit-inline-comments' => 'a48aa699',
|
||||||
'javelin-behavior-differential-feedback-preview' => '6932def3',
|
'javelin-behavior-differential-feedback-preview' => '8e1389b5',
|
||||||
'javelin-behavior-differential-keyboard-navigation' => '2c426492',
|
'javelin-behavior-differential-keyboard-navigation' => '2c426492',
|
||||||
'javelin-behavior-differential-populate' => '8694b1df',
|
'javelin-behavior-differential-populate' => '8694b1df',
|
||||||
'javelin-behavior-differential-show-field-details' => 'bba9eedf',
|
'javelin-behavior-differential-show-field-details' => 'bba9eedf',
|
||||||
|
@ -931,6 +931,14 @@ return array(
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
'phabricator-keyboard-shortcut-manager',
|
'phabricator-keyboard-shortcut-manager',
|
||||||
),
|
),
|
||||||
|
'1b772f31' => array(
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-request',
|
||||||
|
'javelin-workflow',
|
||||||
|
),
|
||||||
'1d298e3a' => array(
|
'1d298e3a' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
|
@ -1227,14 +1235,6 @@ return array(
|
||||||
'6882e80a' => array(
|
'6882e80a' => array(
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
'6932def3' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-request',
|
|
||||||
'javelin-util',
|
|
||||||
'phabricator-shaped-request',
|
|
||||||
),
|
|
||||||
'69adf288' => array(
|
'69adf288' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
),
|
),
|
||||||
|
@ -1316,14 +1316,6 @@ return array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
'7378d48a' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-vector',
|
|
||||||
'differential-inline-comment-editor',
|
|
||||||
),
|
|
||||||
'73d09eef' => array(
|
'73d09eef' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-vector',
|
'javelin-vector',
|
||||||
|
@ -1500,6 +1492,16 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
|
'88be0133' => array(
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-workflow',
|
||||||
|
'javelin-router',
|
||||||
|
'javelin-behavior-device',
|
||||||
|
'javelin-vector',
|
||||||
|
),
|
||||||
'88f0c5b3' => array(
|
'88f0c5b3' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1528,6 +1530,14 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
),
|
),
|
||||||
|
'8e1389b5' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-request',
|
||||||
|
'javelin-util',
|
||||||
|
'phabricator-shaped-request',
|
||||||
|
),
|
||||||
'8ef9ab58' => array(
|
'8ef9ab58' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1609,6 +1619,14 @@ return array(
|
||||||
'javelin-vector',
|
'javelin-vector',
|
||||||
'javelin-magical-init',
|
'javelin-magical-init',
|
||||||
),
|
),
|
||||||
|
'a48aa699' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-vector',
|
||||||
|
'differential-inline-comment-editor',
|
||||||
|
),
|
||||||
'a4ae61bf' => array(
|
'a4ae61bf' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1629,16 +1647,6 @@ return array(
|
||||||
'javelin-uri',
|
'javelin-uri',
|
||||||
'phabricator-keyboard-shortcut',
|
'phabricator-keyboard-shortcut',
|
||||||
),
|
),
|
||||||
'a9af1212' => array(
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-workflow',
|
|
||||||
'javelin-router',
|
|
||||||
'javelin-behavior-device',
|
|
||||||
'javelin-vector',
|
|
||||||
),
|
|
||||||
'a9f88de2' => array(
|
'a9f88de2' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1756,14 +1764,6 @@ return array(
|
||||||
'd254d646' => array(
|
'd254d646' => array(
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
),
|
),
|
||||||
'd3aa4b40' => array(
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-request',
|
|
||||||
'javelin-workflow',
|
|
||||||
),
|
|
||||||
'd4a14807' => array(
|
'd4a14807' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
|
|
@ -290,6 +290,15 @@ final class PhabricatorAuditInlineComment
|
||||||
return $this->proxy->getHasReplies();
|
return $this->proxy->getHasReplies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsDeleted($is_deleted) {
|
||||||
|
$this->proxy->setIsDeleted($is_deleted);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsDeleted() {
|
||||||
|
return $this->proxy->getIsDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
|
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,7 @@ final class DifferentialInlineCommentQuery
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'changesetID IN (%Ld) AND
|
'changesetID IN (%Ld) AND
|
||||||
(authorPHID = %s OR transactionPHID IS NOT NULL)',
|
((authorPHID = %s AND isDeleted = 0) OR transactionPHID IS NOT NULL)',
|
||||||
$ids,
|
$ids,
|
||||||
$phid);
|
$phid);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,8 @@ final class DifferentialInlineCommentQuery
|
||||||
|
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'authorPHID = %s AND revisionPHID = %s AND transactionPHID IS NULL',
|
'authorPHID = %s AND revisionPHID = %s AND transactionPHID IS NULL
|
||||||
|
AND isDeleted = 0',
|
||||||
$phid,
|
$phid,
|
||||||
$rev_phid);
|
$rev_phid);
|
||||||
}
|
}
|
||||||
|
@ -159,7 +160,7 @@ final class DifferentialInlineCommentQuery
|
||||||
if ($this->draftsByAuthors) {
|
if ($this->draftsByAuthors) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'authorPHID IN (%Ls) AND transactionPHID IS NULL',
|
'authorPHID IN (%Ls) AND isDeleted = 0 AND transactionPHID IS NULL',
|
||||||
$this->draftsByAuthors);
|
$this->draftsByAuthors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,15 @@ final class DifferentialInlineComment
|
||||||
return $this->proxy->getHasReplies();
|
return $this->proxy->getHasReplies();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsDeleted($is_deleted) {
|
||||||
|
$this->proxy->setIsDeleted($is_deleted);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsDeleted() {
|
||||||
|
return $this->proxy->getIsDeleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
|
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -79,32 +79,40 @@ abstract class PhabricatorInlineCommentController
|
||||||
|
|
||||||
$this->readRequestParameters();
|
$this->readRequestParameters();
|
||||||
|
|
||||||
switch ($this->getOperation()) {
|
$op = $this->getOperation();
|
||||||
|
switch ($op) {
|
||||||
case 'delete':
|
case 'delete':
|
||||||
$inline = $this->loadCommentForEdit($this->getCommentID());
|
case 'undelete':
|
||||||
|
case 'refdelete':
|
||||||
if ($request->isFormPost()) {
|
if (!$request->validateCSRF()) {
|
||||||
$this->deleteComment($inline);
|
return new Aphront404Response();
|
||||||
return $this->buildEmptyResponse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$dialog = new AphrontDialogView();
|
// NOTE: For normal deletes, we just process the delete immediately
|
||||||
$dialog->setUser($user);
|
// and show an "Undo" action. For deletes by reference from the
|
||||||
$dialog->setSubmitURI($request->getRequestURI());
|
// preview ("refdelete"), we prompt first (because the "Undo" may
|
||||||
|
// not draw, or may not be easy to locate).
|
||||||
|
|
||||||
$dialog->setTitle(pht('Really delete this comment?'));
|
if ($op == 'refdelete') {
|
||||||
$dialog->addHiddenInput('id', $this->getCommentID());
|
if (!$request->isFormPost()) {
|
||||||
$dialog->addHiddenInput('op', 'delete');
|
return $this->newDialog()
|
||||||
$dialog->appendChild(
|
->setTitle(pht('Really delete comment?'))
|
||||||
phutil_tag('p', array(), pht('Delete this inline comment?')));
|
->addHiddenInput('id', $this->getCommentID())
|
||||||
|
->addHiddenInput('op', $op)
|
||||||
|
->appendParagraph(pht('Delete this inline comment?'))
|
||||||
|
->addCancelButton('#')
|
||||||
|
->addSubmitButton(pht('Delete'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$dialog->addCancelButton('#');
|
$is_delete = ($op == 'delete' || $op == 'refdelete');
|
||||||
$dialog->addSubmitButton(pht('Delete'));
|
|
||||||
|
|
||||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
$inline = $this->loadCommentForEdit($this->getCommentID());
|
||||||
|
$inline->setIsDeleted((int)$is_delete)->save();
|
||||||
|
|
||||||
|
return $this->buildEmptyResponse();
|
||||||
case 'edit':
|
case 'edit':
|
||||||
$inline = $this->loadCommentForEdit($this->getCommentID());
|
$inline = $this->loadCommentForEdit($this->getCommentID());
|
||||||
|
|
||||||
$text = $this->getCommentText();
|
$text = $this->getCommentText();
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
|
|
|
@ -25,6 +25,9 @@ interface PhabricatorInlineCommentInterface extends PhabricatorMarkupInterface {
|
||||||
public function setHasReplies($has_replies);
|
public function setHasReplies($has_replies);
|
||||||
public function getHasReplies();
|
public function getHasReplies();
|
||||||
|
|
||||||
|
public function setIsDeleted($deleted);
|
||||||
|
public function getIsDeleted();
|
||||||
|
|
||||||
public function setContent($content);
|
public function setContent($content);
|
||||||
public function getContent();
|
public function getContent();
|
||||||
|
|
||||||
|
|
|
@ -359,6 +359,8 @@ JX.install('ChangesetViewManager', {
|
||||||
if (response.undoTemplates) {
|
if (response.undoTemplates) {
|
||||||
this._undoTemplates = response.undoTemplates;
|
this._undoTemplates = response.undoTemplates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JX.Stratcom.invoke('differential-inline-comment-refresh');
|
||||||
},
|
},
|
||||||
|
|
||||||
_getContentFrame: function() {
|
_getContentFrame: function() {
|
||||||
|
|
|
@ -19,6 +19,7 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
members : {
|
members : {
|
||||||
_uri : null,
|
_uri : null,
|
||||||
_undoText : null,
|
_undoText : null,
|
||||||
|
_completed: false,
|
||||||
_skipOverInlineCommentRows : function(node) {
|
_skipOverInlineCommentRows : function(node) {
|
||||||
// TODO: Move this semantic information out of class names.
|
// TODO: Move this semantic information out of class names.
|
||||||
while (node && node.className.indexOf('inline') !== -1) {
|
while (node && node.className.indexOf('inline') !== -1) {
|
||||||
|
@ -73,11 +74,17 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
JX.DOM.remove(rows[ii]);
|
JX.DOM.remove(rows[ii]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
JX.DifferentialInlineCommentEditor._undoRows = [];
|
||||||
},
|
},
|
||||||
_undo : function() {
|
_undo : function() {
|
||||||
this._removeUndoLink();
|
this._removeUndoLink();
|
||||||
|
|
||||||
|
if (this._undoText) {
|
||||||
this.setText(this._undoText);
|
this.setText(this._undoText);
|
||||||
|
} else {
|
||||||
|
this.setOperation('undelete');
|
||||||
|
}
|
||||||
|
|
||||||
this.start();
|
this.start();
|
||||||
},
|
},
|
||||||
_registerUndoListener : function() {
|
_registerUndoListener : function() {
|
||||||
|
@ -146,9 +153,18 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
'inline-edit-form',
|
'inline-edit-form',
|
||||||
onsubmit);
|
onsubmit);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_didCompleteWorkflow : function(response) {
|
_didCompleteWorkflow : function(response) {
|
||||||
var op = this.getOperation();
|
var op = this.getOperation();
|
||||||
|
|
||||||
|
if (op == 'delete' || op == 'refdelete') {
|
||||||
|
this._undoText = null;
|
||||||
|
this._drawUndo();
|
||||||
|
} else {
|
||||||
|
this._removeUndoLink();
|
||||||
|
}
|
||||||
|
|
||||||
// We don't get any markup back if the user deletes a comment, or saves
|
// We don't get any markup back if the user deletes a comment, or saves
|
||||||
// an empty comment (which effects a delete).
|
// an empty comment (which effects a delete).
|
||||||
if (response.markup) {
|
if (response.markup) {
|
||||||
|
@ -156,30 +172,33 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
}
|
}
|
||||||
|
|
||||||
// These operations remove the old row (edit adds a new row first).
|
// These operations remove the old row (edit adds a new row first).
|
||||||
var remove_old = (op == 'edit' || op == 'delete');
|
var remove_old = (op == 'edit' || op == 'delete' || op == 'refdelete');
|
||||||
if (remove_old) {
|
if (remove_old) {
|
||||||
JX.DOM.remove(this.getRow());
|
this._setRowState('hidden');
|
||||||
var other_rows = this.getOtherRows();
|
|
||||||
for(var i = 0; i < other_rows.length; ++i) {
|
|
||||||
JX.DOM.remove(other_rows[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once the user saves something, get rid of the 'undo' option. A
|
if (op == 'undelete') {
|
||||||
// particular case where we need this is saving a delete, when we might
|
this._setRowState('visible');
|
||||||
// otherwise leave around an 'undo' for an earlier edit to the same
|
}
|
||||||
// comment.
|
|
||||||
this._removeUndoLink();
|
this._completed = true;
|
||||||
|
|
||||||
JX.Stratcom.invoke('differential-inline-comment-update');
|
JX.Stratcom.invoke('differential-inline-comment-update');
|
||||||
this.invoke('done');
|
this.invoke('done');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_didCancelWorkflow : function() {
|
_didCancelWorkflow : function() {
|
||||||
this.invoke('done');
|
this.invoke('done');
|
||||||
|
|
||||||
var op = this.getOperation();
|
switch (this.getOperation()) {
|
||||||
if (op == 'delete') {
|
case 'delete':
|
||||||
// No undo for delete, we prompt the user explicitly.
|
case 'refdelete':
|
||||||
|
if (!this._completed) {
|
||||||
|
this._setRowState('visible');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case 'undelete':
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +228,10 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
// Save the text so we can 'undo' back to it.
|
// Save the text so we can 'undo' back to it.
|
||||||
this._undoText = text;
|
this._undoText = text;
|
||||||
|
|
||||||
|
this._drawUndo();
|
||||||
|
},
|
||||||
|
|
||||||
|
_drawUndo: function() {
|
||||||
var templates = this.getTemplates();
|
var templates = this.getTemplates();
|
||||||
var template = this.getOnRight() ? templates.r : templates.l;
|
var template = this.getOnRight() ? templates.r : templates.l;
|
||||||
template = JX.$H(template).getNode();
|
template = JX.$H(template).getNode();
|
||||||
|
@ -231,21 +254,18 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
this._registerUndoListener();
|
this._registerUndoListener();
|
||||||
|
|
||||||
var data = this._buildRequestData();
|
var data = this._buildRequestData();
|
||||||
|
|
||||||
var op = this.getOperation();
|
var op = this.getOperation();
|
||||||
|
|
||||||
|
|
||||||
if (op == 'delete') {
|
if (op == 'delete' || op == 'refdelete' || op == 'undelete') {
|
||||||
this._setRowState('loading');
|
this._setRowState('loading');
|
||||||
|
|
||||||
var oncomplete = JX.bind(this, this._didCompleteWorkflow);
|
var oncomplete = JX.bind(this, this._didCompleteWorkflow);
|
||||||
var onclose = JX.bind(this, function() {
|
var oncancel = JX.bind(this, this._didCancelWorkflow);
|
||||||
this._setRowState('visible');
|
|
||||||
this._didCancelWorkflow();
|
|
||||||
});
|
|
||||||
|
|
||||||
new JX.Workflow(this._uri, data)
|
new JX.Workflow(this._uri, data)
|
||||||
.setHandler(oncomplete)
|
.setHandler(oncomplete)
|
||||||
.setCloseHandler(onclose)
|
.setCloseHandler(oncancel)
|
||||||
.start();
|
.start();
|
||||||
} else {
|
} else {
|
||||||
var handler = JX.bind(this, this._didContinueWorkflow);
|
var handler = JX.bind(this, this._didContinueWorkflow);
|
||||||
|
@ -260,7 +280,21 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteByID: function(id) {
|
||||||
|
var data = {
|
||||||
|
op: 'refdelete',
|
||||||
|
changesetID: id
|
||||||
|
};
|
||||||
|
|
||||||
|
new JX.Workflow(this._uri, data)
|
||||||
|
.setHandler(function() {
|
||||||
|
JX.Stratcom.invoke('differential-inline-comment-update');
|
||||||
|
})
|
||||||
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
statics : {
|
statics : {
|
||||||
|
@ -280,7 +314,6 @@ JX.install('DifferentialInlineCommentEditor', {
|
||||||
properties : {
|
properties : {
|
||||||
operation : null,
|
operation : null,
|
||||||
row : null,
|
row : null,
|
||||||
otherRows: [],
|
|
||||||
table : null,
|
table : null,
|
||||||
onRight : null,
|
onRight : null,
|
||||||
ID : null,
|
ID : null,
|
||||||
|
|
|
@ -49,7 +49,6 @@ JX.behavior('differential-feedback-preview', function(config) {
|
||||||
|
|
||||||
request.start();
|
request.start();
|
||||||
|
|
||||||
|
|
||||||
function refreshInlinePreview() {
|
function refreshInlinePreview() {
|
||||||
new JX.Request(config.inlineuri, function(r) {
|
new JX.Request(config.inlineuri, function(r) {
|
||||||
var inline = JX.$(config.inline);
|
var inline = JX.$(config.inline);
|
||||||
|
@ -59,13 +58,20 @@ JX.behavior('differential-feedback-preview', function(config) {
|
||||||
container: inline
|
container: inline
|
||||||
});
|
});
|
||||||
|
|
||||||
// Go through the previews and activate any "View" links where the
|
updateLinks();
|
||||||
// actual comment appears in the document.
|
})
|
||||||
|
.setTimeout(5000)
|
||||||
|
.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLinks() {
|
||||||
|
var inline = JX.$(config.inline);
|
||||||
|
|
||||||
var links = JX.DOM.scry(
|
var links = JX.DOM.scry(
|
||||||
inline,
|
inline,
|
||||||
'a',
|
'a',
|
||||||
'differential-inline-preview-jump');
|
'differential-inline-preview-jump');
|
||||||
|
|
||||||
for (var ii = 0; ii < links.length; ii++) {
|
for (var ii = 0; ii < links.length; ii++) {
|
||||||
var data = JX.Stratcom.getData(links[ii]);
|
var data = JX.Stratcom.getData(links[ii]);
|
||||||
try {
|
try {
|
||||||
|
@ -76,15 +82,18 @@ JX.behavior('differential-feedback-preview', function(config) {
|
||||||
// This inline comment isn't visible, e.g. on some other diff.
|
// This inline comment isn't visible, e.g. on some other diff.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.setTimeout(5000)
|
|
||||||
.send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JX.Stratcom.listen(
|
JX.Stratcom.listen(
|
||||||
'differential-inline-comment-update',
|
'differential-inline-comment-update',
|
||||||
null,
|
null,
|
||||||
refreshInlinePreview);
|
refreshInlinePreview);
|
||||||
|
|
||||||
|
JX.Stratcom.listen(
|
||||||
|
'differential-inline-comment-refresh',
|
||||||
|
null,
|
||||||
|
updateLinks);
|
||||||
|
|
||||||
refreshInlinePreview();
|
refreshInlinePreview();
|
||||||
});
|
});
|
||||||
|
|
|
@ -298,25 +298,40 @@ JX.behavior('differential-edit-inline-comments', function(config) {
|
||||||
|
|
||||||
var handle_inline_action = function(node, op) {
|
var handle_inline_action = function(node, op) {
|
||||||
var data = JX.Stratcom.getData(node);
|
var data = JX.Stratcom.getData(node);
|
||||||
var row = node.parentNode.parentNode;
|
|
||||||
var other_rows = [];
|
// If you click an action in the preview at the bottom of the page, we
|
||||||
|
// find the corresponding node and simulate clicking that, if it's
|
||||||
|
// present on the page. This gives the editor a more consistent view
|
||||||
|
// of the document.
|
||||||
if (JX.Stratcom.hasSigil(node, 'differential-inline-comment-preview')) {
|
if (JX.Stratcom.hasSigil(node, 'differential-inline-comment-preview')) {
|
||||||
// The DOM structure around the comment is different if it's part of the
|
|
||||||
// preview, so make sure not to pass the wrong container.
|
|
||||||
row = node;
|
|
||||||
if (op === 'delete') {
|
|
||||||
// Furthermore, deleting a comment in the preview does not automatically
|
|
||||||
// delete other occurrences of the same comment, so do that manually.
|
|
||||||
var nodes = JX.DOM.scry(
|
var nodes = JX.DOM.scry(
|
||||||
JX.DOM.getContentFrame(),
|
JX.DOM.getContentFrame(),
|
||||||
'div',
|
'div',
|
||||||
'differential-inline-comment');
|
'differential-inline-comment');
|
||||||
for (var i = 0; i < nodes.length; ++i) {
|
|
||||||
if (JX.Stratcom.getData(nodes[i]).id === data.id) {
|
var found = false;
|
||||||
other_rows.push(nodes[i]);
|
var node_data;
|
||||||
|
for (var ii = 0; ii < nodes.length; ++ii) {
|
||||||
|
if (nodes[ii] == node) {
|
||||||
|
// Don't match the preview itself.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
node_data = JX.Stratcom.getData(nodes[ii]);
|
||||||
|
if (node_data.id == data.id) {
|
||||||
|
node = nodes[ii];
|
||||||
|
data = node_data;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
new JX.DifferentialInlineCommentEditor(config.uri)
|
||||||
|
.deleteByID(data.id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
op = 'refdelete';
|
||||||
}
|
}
|
||||||
|
|
||||||
var original = data.original;
|
var original = data.original;
|
||||||
|
@ -328,6 +343,7 @@ JX.behavior('differential-edit-inline-comments', function(config) {
|
||||||
reply_phid = data.phid;
|
reply_phid = data.phid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var row = JX.DOM.findAbove(node, 'tr');
|
||||||
var changeset_root = JX.DOM.findAbove(
|
var changeset_root = JX.DOM.findAbove(
|
||||||
node,
|
node,
|
||||||
'div',
|
'div',
|
||||||
|
@ -344,7 +360,6 @@ JX.behavior('differential-edit-inline-comments', function(config) {
|
||||||
.setOnRight(data.on_right)
|
.setOnRight(data.on_right)
|
||||||
.setOriginalText(original)
|
.setOriginalText(original)
|
||||||
.setRow(row)
|
.setRow(row)
|
||||||
.setOtherRows(other_rows)
|
|
||||||
.setTable(row.parentNode)
|
.setTable(row.parentNode)
|
||||||
.setReplyToCommentPHID(reply_phid)
|
.setReplyToCommentPHID(reply_phid)
|
||||||
.setRenderer(view.getRenderer())
|
.setRenderer(view.getRenderer())
|
||||||
|
|
Loading…
Reference in a new issue