@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

Make "Show Context" persist rendering, whitespace, encoding, etc

Summary:
Ref T2009. Currently, we do not persist view parameters when making context rendering requests.

The big one is the renderer (1up vs 2up). This makes context on unified diffs come in with too many columns.

However, it impacts other parameters too. For example, at HEAD, if you change highlighting to "rainbow" and then load more context, the context uses the original highlighter instead of the rainbow highlighter.

This moves context loads into ChangesetViewManager, which maintains view parameters and can provide them correctly.

- This removes "ref"; it is no longer required, as the ChangesetViewManager tracks it.
- This removes URI management from `behavior-show-more`; it is no longer required, since the ChangesetViewManager knows how to render.
- This removes "whitespace" since this is handled properly by the view manager.

Test Plan:
- Used "Show Top" / "Show All" / "Show Bottom" in 1-up and 2-up views.
- Changed file highlighting to rainbow, loaded stuff, saw rainbow stick.
- Used "Show Entire File" in 1-up and 2-up views.
- Saw loading chrome.
- No loading chrome normally.
- Made inlines, verified `copyRows()` code runs.
- Poked around Diffusion -- it is missing some parameter handling, but works OK.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T2009

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

+251 -158
+47 -46
resources/celerity/map.php
··· 11 11 'core.pkg.js' => 'a77025a1', 12 12 'darkconsole.pkg.js' => '8ab24e01', 13 13 'differential.pkg.css' => 'd8866ed8', 14 - 'differential.pkg.js' => '7b5a4aa4', 14 + 'differential.pkg.js' => '9e55f9f5', 15 15 'diffusion.pkg.css' => '591664fa', 16 16 'diffusion.pkg.js' => 'bfc0737b', 17 17 'maniphest.pkg.css' => '68d4dd3d', ··· 360 360 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '82439934', 361 361 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375', 362 362 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63', 363 - 'rsrc/js/application/differential/ChangesetViewManager.js' => 'c024db3d', 364 - 'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => 'f2441746', 363 + 'rsrc/js/application/differential/ChangesetViewManager.js' => 'fce415a0', 364 + 'rsrc/js/application/differential/DifferentialInlineCommentEditor.js' => '6a049cf7', 365 365 'rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js' => 'e10f8e18', 366 366 'rsrc/js/application/differential/behavior-comment-jump.js' => '4fdb476d', 367 367 'rsrc/js/application/differential/behavior-comment-preview.js' => '6932def3', 368 368 'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1', 369 - 'rsrc/js/application/differential/behavior-dropdown-menus.js' => 'e33d4bc5', 369 + 'rsrc/js/application/differential/behavior-dropdown-menus.js' => '2035b9cb', 370 370 'rsrc/js/application/differential/behavior-edit-inline-comments.js' => '65936067', 371 371 'rsrc/js/application/differential/behavior-keyboard-nav.js' => '2c426492', 372 372 'rsrc/js/application/differential/behavior-populate.js' => 'bdb3e4d0', 373 373 'rsrc/js/application/differential/behavior-show-field-details.js' => 'bba9eedf', 374 - 'rsrc/js/application/differential/behavior-show-more.js' => '954d2de0', 374 + 'rsrc/js/application/differential/behavior-show-more.js' => 'c662904a', 375 375 'rsrc/js/application/differential/behavior-toggle-files.js' => 'ca3f91eb', 376 376 'rsrc/js/application/differential/behavior-user-select.js' => 'a8d8459d', 377 377 'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => 'b42eddc7', ··· 510 510 'aphront-two-column-view-css' => '16ab3ad2', 511 511 'aphront-typeahead-control-css' => '0e403212', 512 512 'auth-css' => '1e655982', 513 - 'changeset-view-manager' => 'c024db3d', 513 + 'changeset-view-manager' => 'fce415a0', 514 514 'config-options-css' => '7fedf08b', 515 515 'config-welcome-css' => '6abd79be', 516 516 'conpherence-durable-column-view' => '3b836442', ··· 521 521 'conpherence-widget-pane-css' => '3d575438', 522 522 'differential-changeset-view-css' => 'b600950c', 523 523 'differential-core-view-css' => '7ac3cabc', 524 - 'differential-inline-comment-editor' => 'f2441746', 524 + 'differential-inline-comment-editor' => '6a049cf7', 525 525 'differential-results-table-css' => '181aa9d9', 526 526 'differential-revision-add-comment-css' => 'c478bcaa', 527 527 'differential-revision-comment-css' => '48186045', ··· 569 569 'javelin-behavior-differential-add-reviewers-and-ccs' => 'e10f8e18', 570 570 'javelin-behavior-differential-comment-jump' => '4fdb476d', 571 571 'javelin-behavior-differential-diff-radios' => 'e1ff79b1', 572 - 'javelin-behavior-differential-dropdown-menus' => 'e33d4bc5', 572 + 'javelin-behavior-differential-dropdown-menus' => '2035b9cb', 573 573 'javelin-behavior-differential-edit-inline-comments' => '65936067', 574 574 'javelin-behavior-differential-feedback-preview' => '6932def3', 575 575 'javelin-behavior-differential-keyboard-navigation' => '2c426492', 576 576 'javelin-behavior-differential-populate' => 'bdb3e4d0', 577 577 'javelin-behavior-differential-show-field-details' => 'bba9eedf', 578 - 'javelin-behavior-differential-show-more' => '954d2de0', 578 + 'javelin-behavior-differential-show-more' => 'c662904a', 579 579 'javelin-behavior-differential-toggle-files' => 'ca3f91eb', 580 580 'javelin-behavior-differential-user-select' => 'a8d8459d', 581 581 'javelin-behavior-diffusion-commit-branches' => 'bdaf4d04', ··· 944 944 'javelin-dom', 945 945 'javelin-reactor-dom', 946 946 ), 947 + '2035b9cb' => array( 948 + 'javelin-behavior', 949 + 'javelin-dom', 950 + 'javelin-util', 951 + 'javelin-stratcom', 952 + 'javelin-workflow', 953 + 'phuix-dropdown-menu', 954 + 'phuix-action-list-view', 955 + 'phuix-action-view', 956 + 'phabricator-phtize', 957 + 'changeset-view-manager', 958 + ), 947 959 '2290aeef' => array( 948 960 'javelin-install', 949 961 'javelin-dom', ··· 1236 1248 '69adf288' => array( 1237 1249 'javelin-install', 1238 1250 ), 1251 + '6a049cf7' => array( 1252 + 'javelin-dom', 1253 + 'javelin-util', 1254 + 'javelin-stratcom', 1255 + 'javelin-install', 1256 + 'javelin-request', 1257 + 'javelin-workflow', 1258 + ), 1239 1259 '6c2b09a2' => array( 1240 1260 'javelin-install', 1241 1261 'javelin-util', ··· 1534 1554 'javelin-resource', 1535 1555 'javelin-routable', 1536 1556 ), 1537 - '954d2de0' => array( 1538 - 'javelin-behavior', 1539 - 'javelin-dom', 1540 - 'javelin-workflow', 1541 - 'javelin-util', 1542 - 'javelin-stratcom', 1543 - ), 1544 1557 '988040b4' => array( 1545 1558 'javelin-install', 1546 1559 'javelin-dom', ··· 1704 1717 'javelin-util', 1705 1718 'phabricator-shaped-request', 1706 1719 ), 1707 - 'c024db3d' => array( 1708 - 'javelin-dom', 1709 - 'javelin-util', 1710 - 'javelin-stratcom', 1711 - 'javelin-install', 1712 - 'javelin-workflow', 1713 - 'javelin-router', 1714 - 'javelin-behavior-device', 1715 - 'javelin-vector', 1716 - ), 1717 1720 'c1700f6f' => array( 1718 1721 'javelin-install', 1719 1722 'javelin-util', ··· 1727 1730 'javelin-dom', 1728 1731 'javelin-stratcom', 1729 1732 'javelin-vector', 1733 + ), 1734 + 'c662904a' => array( 1735 + 'javelin-behavior', 1736 + 'javelin-dom', 1737 + 'javelin-workflow', 1738 + 'javelin-util', 1739 + 'javelin-stratcom', 1740 + 'changeset-view-manager', 1730 1741 ), 1731 1742 'c90a04fc' => array( 1732 1743 'javelin-dom', ··· 1827 1838 'javelin-workflow', 1828 1839 'javelin-vector', 1829 1840 ), 1830 - 'e33d4bc5' => array( 1831 - 'javelin-behavior', 1832 - 'javelin-dom', 1833 - 'javelin-util', 1834 - 'javelin-stratcom', 1835 - 'javelin-workflow', 1836 - 'phuix-dropdown-menu', 1837 - 'phuix-action-list-view', 1838 - 'phuix-action-view', 1839 - 'phabricator-phtize', 1840 - 'changeset-view-manager', 1841 - ), 1842 1841 'e379b58e' => array( 1843 1842 'javelin-behavior', 1844 1843 'javelin-stratcom', ··· 1892 1891 'efe49472' => array( 1893 1892 'javelin-install', 1894 1893 'javelin-util', 1895 - ), 1896 - 'f2441746' => array( 1897 - 'javelin-dom', 1898 - 'javelin-util', 1899 - 'javelin-stratcom', 1900 - 'javelin-install', 1901 - 'javelin-request', 1902 - 'javelin-workflow', 1903 1894 ), 1904 1895 'f24f3253' => array( 1905 1896 'javelin-behavior', ··· 1990 1981 'javelin-behavior', 1991 1982 'javelin-dom', 1992 1983 'phortune-credit-card-form', 1984 + ), 1985 + 'fce415a0' => array( 1986 + 'javelin-dom', 1987 + 'javelin-util', 1988 + 'javelin-stratcom', 1989 + 'javelin-install', 1990 + 'javelin-workflow', 1991 + 'javelin-router', 1992 + 'javelin-behavior-device', 1993 + 'javelin-vector', 1993 1994 ), 1994 1995 'fe287620' => array( 1995 1996 'javelin-install',
+5 -11
src/applications/differential/controller/DifferentialChangesetViewController.php
··· 154 154 $parser->setRenderCacheKey($render_cache_key); 155 155 $parser->setRightSideCommentMapping($right_source, $right_new); 156 156 $parser->setLeftSideCommentMapping($left_source, $left_new); 157 - $parser->setWhitespaceMode($request->getStr('whitespace')); 158 - $parser->setCharacterEncoding($request->getStr('encoding')); 159 - $parser->setHighlightAs($request->getStr('highlight')); 160 157 161 - if ($request->getStr('renderer') == '1up') { 162 - $parser->setRenderer(new DifferentialChangesetOneUpRenderer()); 163 - } 158 + $parser->readParametersFromRequest($request); 164 159 165 160 if ($left && $right) { 166 161 $parser->setOriginals($left, $right); ··· 235 230 $detail = id(new DifferentialChangesetDetailView()) 236 231 ->setUser($this->getViewer()) 237 232 ->setChangeset($changeset) 233 + ->setRenderingRef($rendering_reference) 234 + ->setRenderURI('/differential/changeset/') 235 + ->setRenderer($parser->getRenderer()->getRendererKey()) 238 236 ->appendChild($output) 239 237 ->setVsChangesetID($left_source); 240 238 ··· 242 240 'changesetViewIDs' => array($detail->getID()), 243 241 )); 244 242 245 - Javelin::initBehavior('differential-show-more', array( 246 - 'uri' => '/differential/changeset/', 247 - 'whitespace' => $request->getStr('whitespace'), 248 - )); 249 - 243 + Javelin::initBehavior('differential-show-more'); 250 244 Javelin::initBehavior('differential-comment-jump', array()); 251 245 252 246 $panel = new DifferentialPrimaryPaneView();
+38
src/applications/differential/parser/DifferentialChangesetParser.php
··· 92 92 return $this->disableCache; 93 93 } 94 94 95 + public static function getDefaultRendererForViewer(PhabricatorUser $viewer) { 96 + $prefs = $viewer->loadPreferences(); 97 + $pref_unified = PhabricatorUserPreferences::PREFERENCE_DIFF_UNIFIED; 98 + if ($prefs->getPreference($pref_unified) == 'unified') { 99 + return '1up'; 100 + } 101 + return null; 102 + } 103 + 104 + public function readParametersFromRequest(AphrontRequest $request) { 105 + $this->setWhitespaceMode($request->getStr('whitespace')); 106 + $this->setCharacterEncoding($request->getStr('encoding')); 107 + $this->setHighlightAs($request->getStr('highlight')); 108 + 109 + $renderer = null; 110 + 111 + // If the viewer prefers unified diffs, always set the renderer to unified. 112 + // Otherwise, we leave it unspecified and the client will choose a 113 + // renderer based on the screen size. 114 + 115 + if ($request->getStr('renderer')) { 116 + $renderer = $request->getStr('renderer'); 117 + } else { 118 + $renderer = self::getDefaultRendererForViewer($request->getViewer()); 119 + } 120 + 121 + switch ($renderer) { 122 + case '1up': 123 + $this->setRenderer(new DifferentialChangesetOneUpRenderer()); 124 + break; 125 + default: 126 + $this->setRenderer(new DifferentialChangesetTwoUpRenderer()); 127 + break; 128 + } 129 + 130 + return $this; 131 + } 132 + 95 133 const CACHE_VERSION = 11; 96 134 const CACHE_MAX_SIZE = 8e6; 97 135
-1
src/applications/differential/render/DifferentialChangesetHTMLRenderer.php
··· 519 519 'sigil' => 'show-more', 520 520 'meta' => array( 521 521 'type' => ($is_all ? 'all' : null), 522 - 'ref' => $reference, 523 522 'range' => $range, 524 523 ), 525 524 ),
+4
src/applications/differential/render/DifferentialChangesetOneUpRenderer.php
··· 11 11 return 'diff-1up'; 12 12 } 13 13 14 + public function getRendererKey() { 15 + return '1up'; 16 + } 17 + 14 18 protected function renderColgroup() { 15 19 return phutil_tag('colgroup', array(), array( 16 20 phutil_tag('col', array('class' => 'num')),
+4
src/applications/differential/render/DifferentialChangesetOneUpTestRenderer.php
··· 7 7 return true; 8 8 } 9 9 10 + public function getRendererKey() { 11 + return '1up-test'; 12 + } 13 + 10 14 }
+2
src/applications/differential/render/DifferentialChangesetRenderer.php
··· 34 34 private $oldFile = false; 35 35 private $newFile = false; 36 36 37 + abstract public function getRendererKey(); 38 + 37 39 public function setShowEditAndReplyLinks($bool) { 38 40 $this->showEditAndReplyLinks = $bool; 39 41 return $this;
+4
src/applications/differential/render/DifferentialChangesetTwoUpRenderer.php
··· 11 11 return 'diff-2up'; 12 12 } 13 13 14 + public function getRendererKey() { 15 + return '2up'; 16 + } 17 + 14 18 protected function renderColgroup() { 15 19 return phutil_tag('colgroup', array(), array( 16 20 phutil_tag('col', array('class' => 'num')),
+4
src/applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php
··· 7 7 return false; 8 8 } 9 9 10 + public function getRendererKey() { 11 + return '2up-test'; 12 + } 13 + 10 14 }
+11 -14
src/applications/differential/view/DifferentialChangesetDetailView.php
··· 12 12 private $whitespace; 13 13 private $renderingRef; 14 14 private $autoload; 15 + private $renderer; 15 16 16 17 public function setAutoload($autoload) { 17 18 $this->autoload = $autoload; ··· 67 68 public function setSymbolIndex($symbol_index) { 68 69 $this->symbolIndex = $symbol_index; 69 70 return $this; 71 + } 72 + 73 + public function setRenderer($renderer) { 74 + $this->renderer = $renderer; 75 + return $this; 76 + } 77 + 78 + public function getRenderer() { 79 + return $this->renderer; 70 80 } 71 81 72 82 public function getID() { ··· 188 198 $icon = id(new PHUIIconView()) 189 199 ->setIconFont($display_icon); 190 200 191 - $renderer = null; 192 - 193 - // If the viewer prefers unified diffs, always set the renderer to unified. 194 - // Otherwise, we leave it unspecified and the client will choose a 195 - // renderer based on the screen size. 196 - 197 - $viewer = $this->getUser(); 198 - $prefs = $viewer->loadPreferences(); 199 - $pref_unified = PhabricatorUserPreferences::PREFERENCE_DIFF_UNIFIED; 200 - if ($prefs->getPreference($pref_unified) == 'unified') { 201 - $renderer = '1up'; 202 - } 203 - 204 201 return javelin_tag( 205 202 'div', 206 203 array( ··· 213 210 'renderURI' => $this->getRenderURI(), 214 211 'whitespace' => $this->getWhitespace(), 215 212 'highlight' => null, 216 - 'renderer' => $renderer, 213 + 'renderer' => $this->getRenderer(), 217 214 'ref' => $this->getRenderingRef(), 218 215 'autoload' => $this->getAutoload(), 219 216 ),
+5 -5
src/applications/differential/view/DifferentialChangesetListView.php
··· 136 136 ), 137 137 )); 138 138 139 + $renderer = DifferentialChangesetParser::getDefaultRendererForViewer( 140 + $this->getUser()); 141 + 139 142 $output = array(); 140 143 $ids = array(); 141 144 foreach ($changesets as $key => $changeset) { ··· 169 172 170 173 $detail->setRenderURI($this->renderURI); 171 174 $detail->setWhitespace($this->whitespace); 175 + $detail->setRenderer($renderer); 172 176 173 177 if (isset($this->visibleChangesets[$key])) { 174 178 $load = 'Loading...'; ··· 205 209 'changesetViewIDs' => $ids, 206 210 )); 207 211 208 - $this->initBehavior('differential-show-more', array( 209 - 'uri' => $this->renderURI, 210 - 'whitespace' => $this->whitespace, 211 - )); 212 - 212 + $this->initBehavior('differential-show-more'); 213 213 $this->initBehavior('differential-comment-jump', array()); 214 214 215 215 if ($this->inlineURI) {
+3 -5
src/applications/phriction/controller/PhrictionDiffController.php
··· 97 97 $output = id(new DifferentialChangesetDetailView()) 98 98 ->setUser($this->getViewer()) 99 99 ->setChangeset($changeset) 100 + ->setRenderingRef("{$l},{$r}") 101 + ->setRenderURI('/phriction/diff/'.$document->getID().'/') 100 102 ->appendChild($output); 101 103 102 104 require_celerity_resource('differential-changeset-view-css'); ··· 106 108 Javelin::initBehavior('differential-populate', array( 107 109 'changesetViewIDs' => array($output->getID()), 108 110 )); 109 - 110 - Javelin::initBehavior('differential-show-more', array( 111 - 'uri' => '/phriction/diff/'.$document->getID().'/', 112 - 'whitespace' => $whitespace_mode, 113 - )); 111 + Javelin::initBehavior('differential-show-more'); 114 112 115 113 $slug = $document->getSlug(); 116 114
+2 -2
src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
··· 948 948 ), 949 949 950 950 "\xE2\x96\xB2 Show %d Line(s)" => array( 951 - "\xE2\x96\xB2 Show %d Line(s)", 952 - "\xE2\x96\xB2 Show %d Line(s)", 951 + "\xE2\x96\xB2 Show Line", 952 + "\xE2\x96\xB2 Show %d Lines", 953 953 ), 954 954 955 955 'Show All %d Line(s)' => array(
+91 -17
webroot/rsrc/js/application/differential/ChangesetViewManager.js
··· 118 118 this._loaded = true; 119 119 this._sequence++; 120 120 121 - var params = { 122 - ref: this._ref, 123 - whitespace: this._whitespace || '', 124 - renderer: this.getRenderer() || '', 125 - highlight: this._highlight || '', 126 - encoding: this._encoding || '' 127 - }; 121 + var params = this._getViewParameters(); 128 122 129 123 var workflow = new JX.Workflow(this._renderURI, params) 130 124 .setHandler(JX.bind(this, this._onresponse, this._sequence)); 131 125 126 + this._startContentWorkflow(workflow); 127 + 128 + JX.DOM.setContent( 129 + this._getContentFrame(), 130 + JX.$N( 131 + 'div', 132 + {className: 'differential-loading'}, 133 + 'Loading...')); 134 + 135 + return this; 136 + }, 137 + 138 + /** 139 + * Load missing context in a changeset. 140 + * 141 + * We do this when the user clicks "Show X Lines". We also expand all of 142 + * the missing context when they "Show Entire File". 143 + * 144 + * @param string Line range specification, like "0-40/0-20". 145 + * @param node Row where the context should be rendered after loading. 146 + * @param bool True if this is a bulk load of multiple context blocks. 147 + * @return this 148 + */ 149 + loadContext: function(range, target, bulk) { 150 + var params = this._getViewParameters(); 151 + params.range = range; 152 + 153 + var container = JX.DOM.scry(target, 'td')[0]; 154 + // TODO: pht() 155 + JX.DOM.setContent(container, 'Loading...'); 156 + JX.DOM.alterClass(target, 'differential-show-more-loading', true); 157 + 158 + var workflow = new JX.Workflow(this._renderURI, params) 159 + .setHandler(JX.bind(this, this._oncontext, target)); 160 + 161 + if (bulk) { 162 + // If we're loading a bunch of these because the viewer clicked 163 + // "Show Entire File Content" or similar, use lower-priority requests 164 + // and draw a progress bar. 165 + this._startContentWorkflow(workflow); 166 + } else { 167 + // If this is a single click on a context link, use a higher priority 168 + // load without a chrome change. 169 + workflow.start(); 170 + } 171 + 172 + return this; 173 + }, 174 + 175 + _startContentWorkflow: function(workflow) { 132 176 var routable = workflow.getRoutable(); 133 177 134 178 routable ··· 137 181 .setKey(this._getRoutableKey()); 138 182 139 183 JX.Router.getInstance().queue(routable); 184 + }, 140 185 141 - JX.DOM.setContent( 142 - this._getContentFrame(), 143 - JX.$N( 144 - 'div', 145 - {className: 'differential-loading'}, 146 - 'Loading...')); 147 186 148 - return this; 187 + /** 188 + * Receive a response to a context request. 189 + */ 190 + _oncontext: function(target, response) { 191 + var table = JX.$H(response.changeset).getNode(); 192 + var root = target.parentNode; 193 + this._moveRows(table, root, target); 194 + root.removeChild(target); 149 195 }, 150 196 197 + _moveRows: function(src, dst, before) { 198 + var rows = JX.DOM.scry(src, 'tr'); 199 + for (var ii = 0; ii < rows.length; ii++) { 200 + 201 + // Find the table this <tr /> belongs to. If it's a sub-table, like a 202 + // table in an inline comment, don't copy it. 203 + if (JX.DOM.findAbove(rows[ii], 'table') !== src) { 204 + continue; 205 + } 206 + 207 + if (before) { 208 + dst.insertBefore(rows[ii], before); 209 + } else { 210 + dst.appendChild(rows[ii]); 211 + } 212 + } 213 + }, 214 + 215 + /** 216 + * Get parameters which define the current rendering options. 217 + */ 218 + _getViewParameters: function() { 219 + return { 220 + ref: this._ref, 221 + whitespace: this._whitespace || '', 222 + renderer: this.getRenderer() || '', 223 + highlight: this._highlight || '', 224 + encoding: this._encoding || '' 225 + }; 226 + }, 151 227 152 228 /** 153 229 * Get the active @{class:JX.Routable} for this changeset. ··· 176 252 // a different one we don't re-render the diffs, because it's a 177 253 // complicated mess and you could lose inline comments, cursor positions, 178 254 // etc. 179 - var renderer = (JX.Device.getDevice() == 'desktop') ? '2up' : '1up'; 180 - 181 - return renderer; 255 + return (JX.Device.getDevice() == 'desktop') ? '2up' : '1up'; 182 256 }, 183 257 184 258 setEncoding: function(encoding) {
+19
webroot/rsrc/js/application/differential/DifferentialInlineCommentEditor.js
··· 43 43 var table = this.getTable(); 44 44 var target = exact_row ? row : this._skipOverInlineCommentRows(row); 45 45 46 + function copyRows(dst, src, before) { 47 + var rows = JX.DOM.scry(src, 'tr'); 48 + for (var ii = 0; ii < rows.length; ii++) { 49 + 50 + // Find the table this <tr /> belongs to. If it's a sub-table, like a 51 + // table in an inline comment, don't copy it. 52 + if (JX.DOM.findAbove(rows[ii], 'table') !== src) { 53 + continue; 54 + } 55 + 56 + if (before) { 57 + dst.insertBefore(rows[ii], before); 58 + } else { 59 + dst.appendChild(rows[ii]); 60 + } 61 + } 62 + return rows; 63 + } 64 + 46 65 return copyRows(table, content, target); 47 66 }, 48 67 _removeUndoLink : function() {
+5 -6
webroot/rsrc/js/application/differential/behavior-dropdown-menus.js
··· 16 16 var pht = JX.phtize(config.pht); 17 17 18 18 function show_more(container) { 19 + var view = JX.ChangesetViewManager.getForNode(container); 20 + 19 21 var nodes = JX.DOM.scry(container, 'tr', 'context-target'); 20 22 for (var ii = 0; ii < nodes.length; ii++) { 21 23 var show = JX.DOM.scry(nodes[ii], 'a', 'show-more'); 22 24 for (var jj = 0; jj < show.length; jj++) { 23 - if (JX.Stratcom.getData(show[jj]).type != 'all') { 25 + var data = JX.Stratcom.getData(show[jj]); 26 + if (data.type != 'all') { 24 27 continue; 25 28 } 26 - var event_data = { 27 - context : nodes[ii], 28 - show : show[jj] 29 - }; 30 - JX.Stratcom.invoke('differential-reveal-context', null, event_data); 29 + view.loadContext(data.range, nodes[ii], true); 31 30 } 32 31 } 33 32 }
+7 -51
webroot/rsrc/js/application/differential/behavior-show-more.js
··· 5 5 * javelin-workflow 6 6 * javelin-util 7 7 * javelin-stratcom 8 + * changeset-view-manager 8 9 */ 9 10 10 - JX.behavior('differential-show-more', function(config) { 11 - 12 - function onresponse(context, response) { 13 - var table = JX.$H(response.changeset).getNode(); 14 - var root = context.parentNode; 15 - copyRows(root, table, context); 16 - root.removeChild(context); 17 - } 11 + JX.behavior('differential-show-more', function() { 18 12 19 13 JX.Stratcom.listen( 20 14 'click', 21 15 'show-more', 22 16 function(e) { 23 - var event_data = { 24 - context : e.getNodes()['context-target'], 25 - show : e.getNodes()['show-more'] 26 - }; 27 - 28 - JX.Stratcom.invoke('differential-reveal-context', null, event_data); 29 17 e.kill(); 30 - }); 31 18 32 - JX.Stratcom.listen( 33 - 'differential-reveal-context', 34 - null, 35 - function(e) { 36 - var context = e.getData().context; 37 - var data = JX.Stratcom.getData(e.getData().show); 38 - 39 - var container = JX.DOM.scry(context, 'td')[0]; 40 - JX.DOM.setContent(container, 'Loading...'); 41 - JX.DOM.alterClass(context, 'differential-show-more-loading', true); 42 - 43 - if (!data.whitespace) { 44 - data.whitespace = config.whitespace; 45 - } 19 + var changeset = e.getNode('differential-changeset'); 20 + var view = JX.ChangesetViewManager.getForNode(changeset); 21 + var data = e.getNodeData('show-more'); 22 + var target = e.getNode('context-target'); 46 23 47 - new JX.Workflow(config.uri, data) 48 - .setHandler(JX.bind(null, onresponse, context)) 49 - .start(); 24 + view.loadContext(data.range, target); 50 25 }); 51 26 52 27 }); 53 - 54 - function copyRows(dst, src, before) { 55 - var rows = JX.DOM.scry(src, 'tr'); 56 - for (var ii = 0; ii < rows.length; ii++) { 57 - 58 - // Find the table this <tr /> belongs to. If it's a sub-table, like a 59 - // table in an inline comment, don't copy it. 60 - if (JX.DOM.findAbove(rows[ii], 'table') !== src) { 61 - continue; 62 - } 63 - 64 - if (before) { 65 - dst.insertBefore(rows[ii], before); 66 - } else { 67 - dst.appendChild(rows[ii]); 68 - } 69 - } 70 - return rows; 71 - }