diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 80341e1c3f..6d8f0e18cc 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -483,7 +483,7 @@ return array( 'rsrc/js/core/behavior-keyboard-pager.js' => '1325b731', 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '42c44e8b', 'rsrc/js/core/behavior-lightbox-attachments.js' => 'c7e748bf', - 'rsrc/js/core/behavior-line-linker.js' => 'e15c8b1f', + 'rsrc/js/core/behavior-line-linker.js' => '590e6527', 'rsrc/js/core/behavior-linked-container.js' => '74446546', 'rsrc/js/core/behavior-more.js' => '506aa3f4', 'rsrc/js/core/behavior-object-selector.js' => '98ef467f', @@ -644,7 +644,7 @@ return array( 'javelin-behavior-phabricator-gesture-example' => '242dedd0', 'javelin-behavior-phabricator-keyboard-pager' => '1325b731', 'javelin-behavior-phabricator-keyboard-shortcuts' => '42c44e8b', - 'javelin-behavior-phabricator-line-linker' => 'e15c8b1f', + 'javelin-behavior-phabricator-line-linker' => '590e6527', 'javelin-behavior-phabricator-nav' => 'f166c949', 'javelin-behavior-phabricator-notification-example' => '29819b75', 'javelin-behavior-phabricator-object-selector' => '98ef467f', @@ -1452,6 +1452,12 @@ return array( 'javelin-util', 'javelin-magical-init', ), + '590e6527' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-history', + ), '5a4e4a3b' => array( 'javelin-dom', 'javelin-util', @@ -2096,12 +2102,6 @@ return array( 'javelin-dom', 'phuix-dropdown-menu', ), - 'e15c8b1f' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-history', - ), 'e5bdb730' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/applications/diffusion/controller/DiffusionBrowseController.php b/src/applications/diffusion/controller/DiffusionBrowseController.php index 3cc873b360..e4e7a0c030 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseController.php @@ -472,15 +472,21 @@ final class DiffusionBrowseController extends DiffusionController { $viewer = $this->getViewer(); $base_uri = $this->getRequest()->getRequestURI(); - $user = $this->getRequest()->getUser(); $repository = $drequest->getRepository(); $path = $drequest->getPath(); $line = nonempty((int)$drequest->getLine(), 1); $buttons = array(); - // TODO: Restore these behaviors. - $editor_link = null; - $template = null; + $editor_uri = null; + $editor_template = null; + + $link_engine = PhabricatorEditorURIEngine::newForViewer($viewer); + if ($link_engine) { + $link_engine->setRepository($repository); + + $editor_uri = $link_engine->getURIForPath($path, $line); + $editor_template = $link_engine->getURITokensForPath($path); + } $buttons[] = id(new PHUIButtonView()) @@ -494,16 +500,16 @@ final class DiffusionBrowseController extends DiffusionController { ))) ->setIcon('fa-backward'); - if ($editor_link) { + if ($editor_uri) { $buttons[] = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Open File')) - ->setHref($editor_link) + ->setHref($editor_uri) ->setIcon('fa-pencil') ->setID('editor_link') - ->setMetadata(array('link_template' => $template)) - ->setDisabled(!$editor_link) + ->setMetadata(array('template' => $editor_template)) + ->setDisabled(!$editor_uri) ->setColor(PHUIButtonView::GREY); } diff --git a/src/infrastructure/editor/PhabricatorEditorURIEngine.php b/src/infrastructure/editor/PhabricatorEditorURIEngine.php index bf0c1d1b4b..d4821c4ffd 100644 --- a/src/infrastructure/editor/PhabricatorEditorURIEngine.php +++ b/src/infrastructure/editor/PhabricatorEditorURIEngine.php @@ -68,7 +68,7 @@ final class PhabricatorEditorURIEngine } public function getURIForPath($path, $line) { - $tokens = $this->getURITokensForRepository(); + $tokens = $this->getURITokensForRepository($path); $variables = array( 'f' => $this->escapeToken($path), @@ -80,12 +80,14 @@ final class PhabricatorEditorURIEngine return $this->newStringFromTokens($tokens); } - public function getURITokensForRepository() { - if (!$this->repositoryTokens) { - $this->repositoryTokens = $this->newURITokensForRepository(); - } + public function getURITokensForPath($path) { + $tokens = $this->getURITokensForRepository($path); - return $this->repositoryTokens; + $variables = array( + 'f' => $this->escapeToken($path), + ); + + return $this->newTokensWithVariables($tokens, $variables); } public static function getVariableDefinitions() { @@ -121,6 +123,14 @@ final class PhabricatorEditorURIEngine ); } + private function getURITokensForRepository() { + if (!$this->repositoryTokens) { + $this->repositoryTokens = $this->newURITokensForRepository(); + } + + return $this->repositoryTokens; + } + private function newURITokensForRepository() { $tokens = $this->getRawURITokens(); @@ -259,6 +269,8 @@ final class PhabricatorEditorURIEngine $last_literal = $key; } + $tokens = array_values($tokens); + return $tokens; } diff --git a/webroot/rsrc/js/core/behavior-line-linker.js b/webroot/rsrc/js/core/behavior-line-linker.js index 8cb3d0c615..9042cb0912 100644 --- a/webroot/rsrc/js/core/behavior-line-linker.js +++ b/webroot/rsrc/js/core/behavior-line-linker.js @@ -169,10 +169,33 @@ JX.behavior('phabricator-line-linker', function() { JX.History.replace(uri); if (editor_link) { - if (editor_link.href) { - var editdata = JX.Stratcom.getData(editor_link); - editor_link.href = editdata.link_template.replace('%25l', o); + var data = JX.Stratcom.getData(editor_link); + var template = data.template; + + var variables = { + l: parseInt(Math.min(o, t), 10), + }; + + var parts = []; + for (var ii = 0; ii < template.length; ii++) { + var part = template[ii]; + var value = part.value; + + if (part.type === 'literal') { + parts.push(value); + continue; + } + + if (part.type === 'variable') { + if (variables.hasOwnProperty(value)) { + var replacement = variables[value]; + replacement = encodeURIComponent(replacement); + parts.push(replacement); + } + } } + + editor_link.href = parts.join(''); } }); @@ -188,4 +211,16 @@ JX.behavior('phabricator-line-linker', function() { } } + if (editor_link) { + // TODO: This should be pht()'d, but this behavior is weird enough to + // make that a bit tricky. + + new JX.KeyboardShortcut('\\', 'Open File in External Editor') + .setGroup('diff-nav') + .setHandler(function() { + JX.$U(editor_link.href).go(); + }) + .register(); + } + });