diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -13,7 +13,7 @@ 'core.pkg.js' => 'ab3502fe', 'dark-console.pkg.js' => '187792c2', 'differential.pkg.css' => 'ffb69e3d', - 'differential.pkg.js' => '5080baf4', + 'differential.pkg.js' => '5986f349', 'diffusion.pkg.css' => '42c75c37', 'diffusion.pkg.js' => '78c9885d', 'maniphest.pkg.css' => '35995d6d', @@ -437,7 +437,7 @@ 'rsrc/js/application/releeph/releeph-preview-branch.js' => '75184d68', 'rsrc/js/application/releeph/releeph-request-state-change.js' => '9f081f05', 'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'aa3a100c', - 'rsrc/js/application/repository/repository-crossreference.js' => '6337cf26', + 'rsrc/js/application/repository/repository-crossreference.js' => '44d48cd1', 'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e5bdb730', 'rsrc/js/application/search/behavior-reorder-queries.js' => 'b86f297f', 'rsrc/js/application/transactions/behavior-comment-actions.js' => '4dffaeb2', @@ -693,7 +693,7 @@ 'javelin-behavior-reorder-applications' => 'aa371860', 'javelin-behavior-reorder-columns' => '8ac32fd9', 'javelin-behavior-reorder-profile-menu-items' => 'e5bdb730', - 'javelin-behavior-repository-crossreference' => '6337cf26', + 'javelin-behavior-repository-crossreference' => '44d48cd1', 'javelin-behavior-scrollbar' => '92388bae', 'javelin-behavior-search-reorder-queries' => 'b86f297f', 'javelin-behavior-select-content' => 'e8240b50', @@ -1309,6 +1309,12 @@ '43bc9360' => array( 'javelin-install', ), + '44d48cd1' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-uri', + ), '457f4d16' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1536,12 +1542,6 @@ 'javelin-request', 'javelin-uri', ), - '6337cf26' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-uri', - ), '65bb0011' => array( 'javelin-behavior', 'javelin-dom', diff --git a/src/applications/differential/view/DifferentialChangesetDetailView.php b/src/applications/differential/view/DifferentialChangesetDetailView.php --- a/src/applications/differential/view/DifferentialChangesetDetailView.php +++ b/src/applications/differential/view/DifferentialChangesetDetailView.php @@ -246,6 +246,7 @@ 'displayPath' => hsprintf('%s', $display_parts), 'icon' => $display_icon, 'pathParts' => $path_parts, + 'symbolPath' => $display_filename, 'pathIconIcon' => $changeset->getPathIconIcon(), 'pathIconColor' => $changeset->getPathIconColor(), diff --git a/src/applications/diffusion/controller/DiffusionSymbolController.php b/src/applications/diffusion/controller/DiffusionSymbolController.php --- a/src/applications/diffusion/controller/DiffusionSymbolController.php +++ b/src/applications/diffusion/controller/DiffusionSymbolController.php @@ -4,7 +4,10 @@ public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); + + // See T13638 for discussion of escaping. $name = $request->getURIData('name'); + $name = phutil_unescape_uri_path_component($name); $query = id(new DiffusionSymbolQuery()) ->setViewer($viewer) diff --git a/src/applications/diffusion/engineextension/DiffusionDatasourceEngineExtension.php b/src/applications/diffusion/engineextension/DiffusionDatasourceEngineExtension.php --- a/src/applications/diffusion/engineextension/DiffusionDatasourceEngineExtension.php +++ b/src/applications/diffusion/engineextension/DiffusionDatasourceEngineExtension.php @@ -66,12 +66,12 @@ $parts = null; if (preg_match('/(.*)(?:\\.|::|->)(.*)/', $symbol, $parts)) { return urisprintf( - '/diffusion/symbol/%s/?jump=true&context=%s', + '/diffusion/symbol/%p/?jump=true&context=%s', $parts[2], $parts[1]); } else { return urisprintf( - '/diffusion/symbol/%s/?jump=true', + '/diffusion/symbol/%p/?jump=true', $symbol); } } diff --git a/webroot/rsrc/js/application/repository/repository-crossreference.js b/webroot/rsrc/js/application/repository/repository-crossreference.js --- a/webroot/rsrc/js/application/repository/repository-crossreference.js +++ b/webroot/rsrc/js/application/repository/repository-crossreference.js @@ -66,13 +66,8 @@ var target = e.getTarget(); - try { - // If we're in an inline comment, don't link symbols. - if (JX.DOM.findAbove(target, 'div', 'differential-inline-comment')) { - return; - } - } catch (ex) { - // Continue if we're not inside an inline comment. + if (!canLinkNode(target)) { + return; } // If only part of the symbol was edited, the symbol name itself will @@ -97,6 +92,29 @@ } }); } + + function canLinkNode(node) { + try { + // If we're in an inline comment, don't link symbols. + if (JX.DOM.findAbove(node, 'div', 'differential-inline-comment')) { + return false; + } + } catch (ex) { + // Continue if we're not inside an inline comment. + } + + // See T13644. Don't open symbols if we're inside a changeset header. + try { + if (JX.DOM.findAbove(node, 'h1')) { + return false; + } + } catch (ex) { + // Continue if not inside a header. + } + + return true; + } + function unhighlight() { highlighted && JX.DOM.alterClass(highlighted, classHighlight, false); highlighted = null; @@ -159,6 +177,9 @@ uri_symbol = uri_symbol.trim(); // See T13437. Symbols like "#define" need to be encoded. + // See T13644. Symbols like "a/b" must be double-encoded to survive + // one layer of decoding by the webserver. + uri_symbol = encodeURIComponent(uri_symbol); uri_symbol = encodeURIComponent(uri_symbol); var uri = JX.$U('/diffusion/symbol/' + uri_symbol + '/'); @@ -223,7 +244,7 @@ var changeset; try { changeset = JX.DOM.findAbove(target, 'div', 'differential-changeset'); - return JX.Stratcom.getData(changeset).path; + return JX.Stratcom.getData(changeset).symbolPath || null; } catch (ex) { // Ignore. } @@ -315,13 +336,8 @@ var target = e.getTarget(); - try { - // If we're in an inline comment, don't link symbols. - if (JX.DOM.findAbove(target, 'div', 'differential-inline-comment')) { - return; - } - } catch (ex) { - // Continue if we're not inside an inline comment. + if (!canLinkNode(target)) { + return; } // If only part of the symbol was edited, the symbol name itself will