From 4d335b7befbf671d83d5668048f20fb631ec64cb Mon Sep 17 00:00:00 2001 From: Chad Little Date: Mon, 14 Aug 2017 20:50:06 -0700 Subject: [PATCH] Build a basic DiffusionPatternSearchView Summary: Roughs this in a little, kinda basic. Allows for grouping results by page. A bit better on mobile. Would like more content return from conduit though. Test Plan: Test `CMS`, `cms`, and `OMGLOLWTFBBQ`, desktop and mobile {F5099081} Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D18429 --- resources/celerity/map.php | 8 +- src/__phutil_library_map__.php | 2 + .../controller/DiffusionBrowseController.php | 139 ++++-------------- .../view/DiffusionPatternSearchView.php | 124 ++++++++++++++++ .../css/application/diffusion/diffusion.css | 5 + .../css/application/search/search-results.css | 5 +- 6 files changed, 166 insertions(+), 117 deletions(-) create mode 100644 src/applications/diffusion/view/DiffusionPatternSearchView.php diff --git a/resources/celerity/map.php b/resources/celerity/map.php index e379a6acf6..e21ba4bf8b 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -75,7 +75,7 @@ return array( 'rsrc/css/application/diffusion/diffusion-readme.css' => '419dd5b6', 'rsrc/css/application/diffusion/diffusion-repository.css' => 'ee6f20ec', 'rsrc/css/application/diffusion/diffusion-source.css' => '750add59', - 'rsrc/css/application/diffusion/diffusion.css' => '8a6eb632', + 'rsrc/css/application/diffusion/diffusion.css' => 'd0fbb996', 'rsrc/css/application/feed/feed.css' => 'ecd4ec57', 'rsrc/css/application/files/global-drag-and-drop.css' => 'b556a948', 'rsrc/css/application/flag/flag.css' => 'bba8f811', @@ -111,7 +111,7 @@ return array( 'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd', 'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae', 'rsrc/css/application/search/application-search-view.css' => '66ee5d46', - 'rsrc/css/application/search/search-results.css' => '8f8e08ed', + 'rsrc/css/application/search/search-results.css' => '505dd8cf', 'rsrc/css/application/slowvote/slowvote.css' => 'a94b7230', 'rsrc/css/application/tokens/tokens.css' => '3d0f239e', 'rsrc/css/application/uiexample/example.css' => '528b19de', @@ -570,7 +570,7 @@ return array( 'differential-revision-history-css' => '0e8eb855', 'differential-revision-list-css' => 'f3c47d33', 'differential-table-of-contents-css' => 'ae4b7a55', - 'diffusion-css' => '8a6eb632', + 'diffusion-css' => 'd0fbb996', 'diffusion-icons-css' => '0c15255e', 'diffusion-readme-css' => '419dd5b6', 'diffusion-repository-css' => 'ee6f20ec', @@ -798,7 +798,7 @@ return array( 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => 'c5af80a2', 'phabricator-remarkup-css' => 'cad18339', - 'phabricator-search-results-css' => '8f8e08ed', + 'phabricator-search-results-css' => '505dd8cf', 'phabricator-shaped-request' => '7cbe244b', 'phabricator-slowvote-css' => 'a94b7230', 'phabricator-source-code-view-css' => 'aea41829', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1b328c1ec3..5d8d7c3543 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -776,6 +776,7 @@ phutil_register_library_map(array( 'DiffusionPathQueryTestCase' => 'applications/diffusion/query/pathid/__tests__/DiffusionPathQueryTestCase.php', 'DiffusionPathTreeController' => 'applications/diffusion/controller/DiffusionPathTreeController.php', 'DiffusionPathValidateController' => 'applications/diffusion/controller/DiffusionPathValidateController.php', + 'DiffusionPatternSearchView' => 'applications/diffusion/view/DiffusionPatternSearchView.php', 'DiffusionPhpExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPhpExternalSymbolsSource.php', 'DiffusionPreCommitContentAffectedFilesHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAffectedFilesHeraldField.php', 'DiffusionPreCommitContentAuthorHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitContentAuthorHeraldField.php', @@ -5776,6 +5777,7 @@ phutil_register_library_map(array( 'DiffusionPathQueryTestCase' => 'PhabricatorTestCase', 'DiffusionPathTreeController' => 'DiffusionController', 'DiffusionPathValidateController' => 'DiffusionController', + 'DiffusionPatternSearchView' => 'DiffusionView', 'DiffusionPhpExternalSymbolsSource' => 'DiffusionExternalSymbolsSource', 'DiffusionPreCommitContentAffectedFilesHeraldField' => 'DiffusionPreCommitContentHeraldField', 'DiffusionPreCommitContentAuthorHeraldField' => 'DiffusionPreCommitContentHeraldField', diff --git a/src/applications/diffusion/controller/DiffusionBrowseController.php b/src/applications/diffusion/controller/DiffusionBrowseController.php index 429c20e4c0..44c518e5c9 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseController.php @@ -447,136 +447,53 @@ final class DiffusionBrowseController extends DiffusionController { } $results = $pager->sliceResults($results); + $table = null; + $header = null; if ($search_mode == 'grep') { $table = $this->renderGrepResults($results, $query_string); - $header = pht( + $title = pht( 'File content matching "%s" under "%s"', $query_string, nonempty($drequest->getPath(), '/')); + $header = id(new PHUIHeaderView()) + ->setHeader($title) + ->addClass('diffusion-search-result-header'); } - return id(new PHUIObjectBoxView()) - ->setHeaderText($header) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setTable($table) - ->setPager($pager); + return array($header, $table, $pager); } private function renderGrepResults(array $results, $pattern) { $drequest = $this->getDiffusionRequest(); - require_celerity_resource('phabricator-search-results-css'); - $rows = array(); - foreach ($results as $result) { - list($path, $line, $string) = $result; - - $href = $drequest->generateURI(array( - 'action' => 'browse', - 'path' => $path, - 'line' => $line, - )); - - $matches = null; - $count = @preg_match_all( - '('.$pattern.')u', - $string, - $matches, - PREG_OFFSET_CAPTURE); - - if (!$count) { - $output = ltrim($string); - } else { - $output = array(); - $cursor = 0; - $length = strlen($string); - foreach ($matches[0] as $match) { - $offset = $match[1]; - if ($cursor != $offset) { - $output[] = array( - 'text' => substr($string, $cursor, $offset), - 'highlight' => false, - ); - } - $output[] = array( - 'text' => $match[0], - 'highlight' => true, - ); - $cursor = $offset + strlen($match[0]); - } - if ($cursor != $length) { - $output[] = array( - 'text' => substr($string, $cursor), - 'highlight' => false, - ); - } - - if ($output) { - $output[0]['text'] = ltrim($output[0]['text']); - } - - foreach ($output as $key => $segment) { - if ($segment['highlight']) { - $output[$key] = phutil_tag('strong', array(), $segment['text']); - } else { - $output[$key] = $segment['text']; - } - } - } - - $string = phutil_tag( - 'pre', - array('class' => 'PhabricatorMonospaced phui-source-fragment'), - $output); - - $path = Filesystem::readablePath($path, $drequest->getPath()); - - $rows[] = array( - phutil_tag('a', array('href' => $href), $path), - $line, - $string, - ); + if (!$results) { + return id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_NODATA) + ->appendChild( + pht( + 'The pattern you searched for was not found in the content of any '. + 'files.')); } - $table = id(new AphrontTableView($rows)) - ->setClassName('remarkup-code') - ->setHeaders(array(pht('Path'), pht('Line'), pht('String'))) - ->setColumnClasses(array('', 'n', 'wide')) - ->setNoDataString( - pht( - 'The pattern you searched for was not found in the content of any '. - 'files.')); - - return $table; - } - - private function renderFindResults(array $results) { - $drequest = $this->getDiffusionRequest(); - - $rows = array(); - foreach ($results as $result) { - $href = $drequest->generateURI(array( - 'action' => 'browse', - 'path' => $result, - )); - - $readable = Filesystem::readablePath($result, $drequest->getPath()); - - $rows[] = array( - phutil_tag('a', array('href' => $href), $readable), - ); + $grouped = array(); + foreach ($results as $file) { + list($path, $line, $string) = $file; + $grouped[$path][] = array($line, $string); } - $table = id(new AphrontTableView($rows)) - ->setHeaders(array(pht('Path'))) - ->setColumnClasses(array('wide')) - ->setNoDataString( - pht( - 'The pattern you searched for did not match the names of any '. - 'files.')); + $view = array(); + foreach ($grouped as $path => $matches) { + $view[] = id(new DiffusionPatternSearchView()) + ->setPath($path) + ->setMatches($matches) + ->setPattern($pattern) + ->setDiffusionRequest($drequest) + ->render(); + } - return $table; + return $view; } private function loadLintMessages() { diff --git a/src/applications/diffusion/view/DiffusionPatternSearchView.php b/src/applications/diffusion/view/DiffusionPatternSearchView.php new file mode 100644 index 0000000000..a679b51400 --- /dev/null +++ b/src/applications/diffusion/view/DiffusionPatternSearchView.php @@ -0,0 +1,124 @@ +path = $path; + return $this; + } + + public function setMatches(array $matches) { + $this->matches = $matches; + return $this; + } + + public function setPattern($pattern) { + $this->pattern = $pattern; + return $this; + } + + public function render() { + $drequest = $this->getDiffusionRequest(); + $path = $this->path; + $pattern = $this->pattern; + $rows = array(); + + foreach ($this->matches as $result) { + list($line, $string) = $result; + + $matches = null; + $count = @preg_match_all( + '('.$pattern.')u', + $string, + $matches, + PREG_OFFSET_CAPTURE); + + if (!$count) { + $output = ltrim($string); + } else { + $output = array(); + $cursor = 0; + $length = strlen($string); + foreach ($matches[0] as $match) { + $offset = $match[1]; + if ($cursor != $offset) { + $output[] = array( + 'text' => substr($string, $cursor, $offset), + 'highlight' => false, + ); + } + $output[] = array( + 'text' => $match[0], + 'highlight' => true, + ); + $cursor = $offset + strlen($match[0]); + } + if ($cursor != $length) { + $output[] = array( + 'text' => substr($string, $cursor), + 'highlight' => false, + ); + } + + if ($output) { + $output[0]['text'] = ltrim($output[0]['text']); + } + + foreach ($output as $key => $segment) { + if ($segment['highlight']) { + $output[$key] = phutil_tag('strong', array(), $segment['text']); + } else { + $output[$key] = $segment['text']; + } + } + } + + $string = phutil_tag( + 'pre', + array('class' => 'PhabricatorMonospaced phui-source-fragment'), + $output); + + $href = $drequest->generateURI(array( + 'action' => 'browse', + 'path' => $path, + 'line' => $line, + )); + + $rows[] = array( + phutil_tag('a', array('href' => $href), $line), + $string, + ); + } + + $path_title = Filesystem::readablePath($this->path, $drequest->getPath()); + + $href = $drequest->generateURI(array( + 'action' => 'browse', + 'path' => $path_title, + )); + + $title = phutil_tag('a', array('href' => $href), $path_title); + + + $table = id(new AphrontTableView($rows)) + ->setClassName('remarkup-code') + ->setHeaders(array(pht('Line'), pht('String'))) + ->setColumnClasses(array('n', 'wide')); + + $header = id(new PHUIHeaderView()) + ->setHeader($title); + + $box = id(new PHUIObjectBoxView()) + ->setHeader($header) + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) + ->setTable($table); + + return $box->render(); + } + + +} diff --git a/webroot/rsrc/css/application/diffusion/diffusion.css b/webroot/rsrc/css/application/diffusion/diffusion.css index 7c1c9eebf5..024407da00 100644 --- a/webroot/rsrc/css/application/diffusion/diffusion.css +++ b/webroot/rsrc/css/application/diffusion/diffusion.css @@ -122,6 +122,11 @@ color: {$darkbluetext}; } +.diffusion-search-result-header.phui-header-shell { + border: none; + padding-bottom: 24px; +} + /* - Search Input ------------------------------------------------------------*/ .diffusion-search-form-view { diff --git a/webroot/rsrc/css/application/search/search-results.css b/webroot/rsrc/css/application/search/search-results.css index 02d40fa179..86a0cc075a 100644 --- a/webroot/rsrc/css/application/search/search-results.css +++ b/webroot/rsrc/css/application/search/search-results.css @@ -12,9 +12,10 @@ } .phui-source-fragment strong { - background-color: {$lightyellow}; - font-weight: normal; + background-color: {$gentle.highlight}; + font-weight: 600; color: {$blacktext}; + letter-spacing: 0.02em; } .phui-fulltext-tokens {