@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refine unusual inline comment client interactions

Summary: Ref T13513. Refine some inline behaviors, see test plan.

Test Plan:
- Edit a comment ("A"), type text ("AB"), cancel, edit.
- Old behavior: edit and undo states (wrong, and undo does not function).
- New behavior: edit state only.
- Edit a comment ("A"), type text ("AB"), cancel. Undo ("AB"), cancel. Edit.
- Old behavior: "AB" (wrong: you never submitted this text).
- New behavior: "A".
- Create a comment, type text, cancel.
- Old behavior: counter appears in filetree (wrong, comment is undo-able but should not be counted).
- New behavior: no counter.
- Cancel editing an empty comment with no text.
- Old behavior: Something buggy -- undo, I think?
- New behavior: it just vanishes (correct behavior).

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21212

+82 -24
+21 -21
resources/celerity/map.php
··· 13 13 'core.pkg.js' => '632fb8f5', 14 14 'dark-console.pkg.js' => '187792c2', 15 15 'differential.pkg.css' => '2d70b7b9', 16 - 'differential.pkg.js' => 'b35de23a', 16 + 'differential.pkg.js' => '4287e51f', 17 17 'diffusion.pkg.css' => '42c75c37', 18 18 'diffusion.pkg.js' => 'a98c0bf7', 19 19 'maniphest.pkg.css' => '35995d6d', ··· 379 379 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be', 380 380 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9', 381 381 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', 382 - 'rsrc/js/application/diff/DiffChangeset.js' => '9a713ba5', 382 + 'rsrc/js/application/diff/DiffChangeset.js' => 'a49dc31e', 383 383 'rsrc/js/application/diff/DiffChangesetList.js' => '10726e6a', 384 - 'rsrc/js/application/diff/DiffInline.js' => '02791ed9', 384 + 'rsrc/js/application/diff/DiffInline.js' => '7f804f2b', 385 385 'rsrc/js/application/diff/DiffPathView.js' => '8207abf9', 386 386 'rsrc/js/application/diff/DiffTreeView.js' => '5d83623b', 387 387 'rsrc/js/application/diff/behavior-preview-link.js' => 'f51e9c17', ··· 776 776 'phabricator-darklog' => '3b869402', 777 777 'phabricator-darkmessage' => '26cd4b73', 778 778 'phabricator-dashboard-css' => '5a205b9d', 779 - 'phabricator-diff-changeset' => '9a713ba5', 779 + 'phabricator-diff-changeset' => 'a49dc31e', 780 780 'phabricator-diff-changeset-list' => '10726e6a', 781 - 'phabricator-diff-inline' => '02791ed9', 781 + 'phabricator-diff-inline' => '7f804f2b', 782 782 'phabricator-diff-path-view' => '8207abf9', 783 783 'phabricator-diff-tree-view' => '5d83623b', 784 784 'phabricator-drag-and-drop-file-upload' => '4370900d', ··· 944 944 'javelin-leader', 945 945 'javelin-json', 946 946 ), 947 - '02791ed9' => array( 948 - 'javelin-dom', 949 - ), 950 947 '02cb4398' => array( 951 948 'javelin-behavior', 952 949 'javelin-dom', ··· 1629 1626 'javelin-install', 1630 1627 'javelin-dom', 1631 1628 ), 1629 + '7f804f2b' => array( 1630 + 'javelin-dom', 1631 + ), 1632 1632 '80bff3af' => array( 1633 1633 'javelin-install', 1634 1634 'javelin-typeahead-source', ··· 1797 1797 'javelin-request', 1798 1798 'javelin-util', 1799 1799 ), 1800 - '9a713ba5' => array( 1801 - 'javelin-dom', 1802 - 'javelin-util', 1803 - 'javelin-stratcom', 1804 - 'javelin-install', 1805 - 'javelin-workflow', 1806 - 'javelin-router', 1807 - 'javelin-behavior-device', 1808 - 'javelin-vector', 1809 - 'phabricator-diff-inline', 1810 - 'phabricator-diff-path-view', 1811 - 'phuix-button-view', 1812 - ), 1813 1800 '9aae2b66' => array( 1814 1801 'javelin-install', 1815 1802 'javelin-util', ··· 1862 1849 'javelin-dom', 1863 1850 'javelin-stratcom', 1864 1851 'javelin-vector', 1852 + ), 1853 + 'a49dc31e' => array( 1854 + 'javelin-dom', 1855 + 'javelin-util', 1856 + 'javelin-stratcom', 1857 + 'javelin-install', 1858 + 'javelin-workflow', 1859 + 'javelin-router', 1860 + 'javelin-behavior-device', 1861 + 'javelin-vector', 1862 + 'phabricator-diff-inline', 1863 + 'phabricator-diff-path-view', 1864 + 'phuix-button-view', 1865 1865 ), 1866 1866 'a4aa75c4' => array( 1867 1867 'phui-button-css',
+8
src/infrastructure/diff/PhabricatorInlineCommentController.php
··· 220 220 221 221 $inline->setIsEditing(false); 222 222 223 + // If the user uses "Undo" to get into an edited state ("AB"), then 224 + // clicks cancel to return to the previous state ("A"), we also want 225 + // to set the stored state back to "A". 226 + $text = $this->getCommentText(); 227 + if (strlen($text)) { 228 + $inline->setContent($text); 229 + } 230 + 223 231 $content = $inline->getContent(); 224 232 if (!strlen($content)) { 225 233 $this->deleteComment($inline);
+4
webroot/rsrc/js/application/diff/DiffChangeset.js
··· 829 829 continue; 830 830 } 831 831 832 + if (inline.isUndo()) { 833 + continue; 834 + } 835 + 832 836 if (inline.isSynthetic()) { 833 837 continue; 834 838 }
+49 -3
webroot/rsrc/js/application/diff/DiffInline.js
··· 65 65 66 66 this._number = parseInt(data.number, 10); 67 67 this._length = parseInt(data.length, 10); 68 - this._originalText = data.original; 68 + 69 + var original = '' + data.original; 70 + if (original.length) { 71 + this._originalText = original; 72 + } else { 73 + this._originalText = null; 74 + } 69 75 this._isNewFile = data.isNewFile; 70 76 71 77 this._replyToCommentPHID = data.replyToCommentPHID; ··· 101 107 102 108 isEditing: function() { 103 109 return this._isEditing; 110 + }, 111 + 112 + isUndo: function() { 113 + return !!this._undoRow; 104 114 }, 105 115 106 116 isDeleted: function() { ··· 370 380 }, 371 381 372 382 edit: function(text) { 383 + // If you edit an inline ("A"), modify the text ("AB"), cancel, and then 384 + // edit it again: discard the undo state ("AB"). Otherwise we end up 385 + // with an open editor and an active "Undo" link, which is weird. 386 + 387 + if (this._undoRow) { 388 + JX.DOM.remove(this._undoRow); 389 + this._undoRow = null; 390 + 391 + this._undoType = null; 392 + this._undoText = null; 393 + } 394 + 373 395 var uri = this._getInlineURI(); 374 396 var handler = JX.bind(this, this._oneditresponse); 397 + 375 398 var data = this._newRequestData('edit', text || null); 376 399 377 400 this.setLoading(true); ··· 647 670 } 648 671 649 672 this.setEditing(false); 650 - this.setInvisible(false); 673 + 674 + // If this was an empty box and we typed some text and then hit cancel, 675 + // don't show the empty concrete inline. 676 + if (!this._originalText) { 677 + this.setInvisible(true); 678 + } else { 679 + this.setInvisible(false); 680 + } 681 + 682 + // If you "undo" to restore text ("AB") and then "Cancel", we put you 683 + // back in the original text state ("A"). We also send the original 684 + // text ("A") to the server as the current persistent state. 651 685 652 686 var uri = this._getInlineURI(); 653 - var data = this._newRequestData('cancel'); 687 + var data = this._newRequestData('cancel', this._originalText); 654 688 var handler = JX.bind(this, this._onCancelResponse); 655 689 656 690 this.setLoading(true); ··· 664 698 665 699 _onCancelResponse: function(response) { 666 700 this.setLoading(false); 701 + 702 + // If the comment was empty when we started editing it (there's no 703 + // original text) and empty when we finished editing it (there's no 704 + // undo row), just delete the comment. 705 + if (!this._originalText && !this.isUndo()) { 706 + this.setDeleted(true); 707 + 708 + JX.DOM.remove(this._row); 709 + this._row = null; 710 + 711 + this._didUpdate(); 712 + } 667 713 }, 668 714 669 715 _readText: function(row) {