Add support for Documentation search
Bug: Issue 6200
Change-Id: Ibcad93bd77835106977e72dea7d62159d5518b67
diff --git a/Documentation/replace_macros.py b/Documentation/replace_macros.py
index 6f90697..309a135 100755
--- a/Documentation/replace_macros.py
+++ b/Documentation/replace_macros.py
@@ -89,7 +89,7 @@
</button>
<script type="text/javascript">
var f = function() {
- window.location = '../#/Documentation/' +
+ window.location = '../#/Documentation/q/' +
encodeURIComponent(document.getElementById("docSearch").value);
}
document.getElementById("searchBox").onclick = f;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
index c9346f4..4b84864 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
@@ -236,7 +236,7 @@
if (matchPrefix(QUERY, token)) {
query(token);
- } else if (matchPrefix("/Documentation/", token)) {
+ } else if (matchPrefix("/Documentation/q/", token)) {
docSearch(token);
} else if (matchPrefix("/c/", token)) {
diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java
index 124ad1c..062d776 100644
--- a/java/com/google/gerrit/httpd/raw/StaticModule.java
+++ b/java/com/google/gerrit/httpd/raw/StaticModule.java
@@ -71,7 +71,15 @@
*/
public static final ImmutableList<String> POLYGERRIT_INDEX_PATHS =
ImmutableList.of(
- "/", "/c/*", "/p/*", "/q/*", "/x/*", "/admin/*", "/dashboard/*", "/settings/*");
+ "/",
+ "/c/*",
+ "/p/*",
+ "/q/*",
+ "/x/*",
+ "/admin/*",
+ "/dashboard/*",
+ "/settings/*",
+ "/Documentation/q/*");
// TODO(dborowitz): These fragments conflict with the REST API
// namespace, so they will need to use a different path.
// "/groups/*",
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index 5be259c..7278c5a 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -166,6 +166,7 @@
CHANGE: 'change',
DASHBOARD: 'dashboard',
DIFF: 'diff',
+ DOCUMENTATION_SEARCH: 'documentation-search',
EDIT: 'edit',
GROUP: 'group',
PLUGIN_SCREEN: 'plugin-screen',
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index 2ea7e37..0f2bbff 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -148,6 +148,10 @@
IMPROPERLY_ENCODED_PLUS: /^\/c\/(.+)\/\ \/(.+)$/,
PLUGIN_SCREEN: /^\/x\/([\w-]+)\/([\w-]+)\/?/,
+
+ DOCUMENTATION_SEARCH_FILTER: '/Documentation/q/filter::filter',
+ DOCUMENTATION_SEARCH: /^\/Documentation\/q\/(.*)$/,
+ DOCUMENTATION: /^\/Documentation(\/)?(.+)?/,
};
/**
@@ -848,6 +852,17 @@
this._mapRoute(RoutePattern.PLUGIN_SCREEN, '_handlePluginScreen');
+ this._mapRoute(RoutePattern.DOCUMENTATION_SEARCH_FILTER,
+ '_handleDocumentationSearchRoute');
+
+ // redirects /Documentation/q/* to /Documentation/q/filter:*
+ this._mapRoute(RoutePattern.DOCUMENTATION_SEARCH,
+ '_handleDocumentationSearchRedirectRoute');
+
+ // Makes sure /Documentation/* links work (doin't return 404)
+ this._mapRoute(RoutePattern.DOCUMENTATION,
+ '_handleDocumentationRedirectRoute');
+
// Note: this route should appear last so it only catches URLs unmatched
// by other patterns.
this._mapRoute(RoutePattern.DEFAULT, '_handleDefaultRoute');
@@ -1425,6 +1440,27 @@
this._setParams({view, plugin, screen});
},
+ _handleDocumentationSearchRoute(data) {
+ this._setParams({
+ view: Gerrit.Nav.View.DOCUMENTATION_SEARCH,
+ filter: data.params.filter || null,
+ });
+ },
+
+ _handleDocumentationSearchRedirectRoute(data) {
+ this._redirect('/Documentation/q/filter:' +
+ encodeURIComponent(data.params[0]));
+ },
+
+ _handleDocumentationRedirectRoute(data) {
+ if (data.params[1]) {
+ location.reload();
+ } else {
+ // Redirect /Documentation to /Documentation/index.html
+ this._redirect('/Documentation/index.html');
+ }
+ },
+
/**
* Catchall route for when no other route is matched.
*/
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index 7d4f9ba..b9eaa18 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -157,6 +157,9 @@
'_handleDefaultRoute',
'_handleChangeLegacyRoute',
'_handleDiffLegacyRoute',
+ '_handleDocumentationRedirectRoute',
+ '_handleDocumentationSearchRoute',
+ '_handleDocumentationSearchRedirectRoute',
'_handleLegacyLinenum',
'_handleImproperlyEncodedPlusRoute',
'_handlePassThroughRoute',
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html
new file mode 100644
index 0000000..720f353
--- /dev/null
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html
@@ -0,0 +1,62 @@
+<!--
+@license
+Copyright (C) 2018 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<link rel="import" href="../../../bower_components/polymer/polymer.html">
+
+<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
+<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
+<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="../../../styles/gr-table-styles.html">
+<link rel="import" href="../../../styles/shared-styles.html">
+<link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
+<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
+
+<dom-module id="gr-documentation-search">
+ <template>
+ <style include="shared-styles"></style>
+ <style include="gr-table-styles"></style>
+ <gr-list-view
+ filter="[[_filter]]"
+ items=false
+ offset=0
+ loading="[[_loading]]"
+ path="[[_path]]">
+ <table id="list" class="genericList">
+ <tr class="headerRow">
+ <th class="name topHeader">Name</th>
+ <th class="name topHeader"></th>
+ <th class="name topHeader"></th>
+ </tr>
+ <tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
+ <td>Loading...</td>
+ </tr>
+ <tbody class$="[[computeLoadingClass(_loading)]]">
+ <template is="dom-repeat" items="[[_documentationSearches]]">
+ <tr class="table">
+ <td class="name">
+ <a href$="[[_computeSearchUrl(item.url)]]">[[item.title]]</a>
+ </td>
+ <td></td>
+ <td></td>
+ </tr>
+ </template>
+ </tbody>
+ </table>
+ </gr-list-view>
+ <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+ </template>
+ <script src="gr-documentation-search.js"></script>
+</dom-module>
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js
new file mode 100644
index 0000000..f850b9d
--- /dev/null
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.js
@@ -0,0 +1,81 @@
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function() {
+ 'use strict';
+
+ Polymer({
+ is: 'gr-documentation-search',
+
+ properties: {
+ /**
+ * URL params passed from the router.
+ */
+ params: {
+ type: Object,
+ observer: '_paramsChanged',
+ },
+
+ _path: {
+ type: String,
+ readOnly: true,
+ value: '/Documentation',
+ },
+ _documentationSearches: Array,
+
+ _loading: {
+ type: Boolean,
+ value: true,
+ },
+ _filter: {
+ type: String,
+ value: '',
+ },
+ },
+
+ behaviors: [
+ Gerrit.ListViewBehavior,
+ ],
+
+ attached() {
+ this.dispatchEvent(
+ new CustomEvent('title-change', {title: 'Documentation Search'}));
+ },
+
+ _paramsChanged(params) {
+ this._loading = true;
+ this._filter = this.getFilterValue(params);
+
+ return this._getDocumentationSearches(this._filter);
+ },
+
+ _getDocumentationSearches(filter) {
+ this._documentationSearches = [];
+ return this.$.restAPI.getDocumentationSearches(filter)
+ .then(searches => {
+ // Late response.
+ if (filter !== this._filter || !searches) { return; }
+ this._documentationSearches = searches;
+ this._loading = false;
+ });
+ },
+
+ _computeSearchUrl(url) {
+ if (!url) { return ''; }
+ return this.getBaseUrl() + '/' + url;
+ },
+ });
+})();
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html
new file mode 100644
index 0000000..84addb0
--- /dev/null
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<!--
+@license
+Copyright (C) 2018 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+<title>gr-documentation-search</title>
+
+<script src="../../../bower_components/page/page.js"></script>
+<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
+<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<link rel="import" href="../../../test/common-test-setup.html"/>
+<link rel="import" href="gr-documentation-search.html">
+
+<script>void(0);</script>
+
+<test-fixture id="basic">
+ <template>
+ <gr-documentation-search></gr-documentation-search>
+ </template>
+</test-fixture>
+
+<script>
+ let counter;
+ const documentationGenerator = () => {
+ return {
+ title: `Gerrit Code Review - REST API Developers Notes${++counter}`,
+ url: 'Documentation/dev-rest-api.html',
+ };
+ };
+
+ suite('gr-documentation-search tests', () => {
+ let element;
+ let documentationSearches;
+ let sandbox;
+ let value;
+
+ setup(() => {
+ sandbox = sinon.sandbox.create();
+ sandbox.stub(page, 'show');
+ element = fixture('basic');
+ counter = 0;
+ });
+
+ teardown(() => {
+ sandbox.restore();
+ });
+
+ suite('list with searches for documentation', () => {
+ setup(done => {
+ documentationSearches = _.times(26, documentationGenerator);
+ stub('gr-rest-api-interface', {
+ getDocumentationSearches() {
+ return Promise.resolve(documentationSearches);
+ },
+ });
+ element._paramsChanged(value).then(() => { flush(done); });
+ });
+
+ test('test for test repo in the list', done => {
+ flush(() => {
+ assert.equal(element._documentationSearches[0].title,
+ 'Gerrit Code Review - REST API Developers Notes1');
+ assert.equal(element._documentationSearches[0].url,
+ 'Documentation/dev-rest-api.html');
+ done();
+ });
+ });
+ });
+
+ suite('filter', () => {
+ setup(() => {
+ documentationSearches = _.times(25, documentationGenerator);
+ documentationSearchesFiltered = _.times(1, documentationSearches);
+ });
+
+ test('_paramsChanged', done => {
+ sandbox.stub(element.$.restAPI, 'getDocumentationSearches', () => {
+ return Promise.resolve(documentationSearches);
+ });
+ const value = {
+ filter: 'test',
+ };
+ element._paramsChanged(value).then(() => {
+ assert.isTrue(element.$.restAPI.getDocumentationSearches.lastCall
+ .calledWithExactly('test'));
+ done();
+ });
+ });
+ });
+
+ suite('loading', () => {
+ test('correct contents are displayed', () => {
+ assert.isTrue(element._loading);
+ assert.equal(element.computeLoadingClass(element._loading), 'loading');
+ assert.equal(getComputedStyle(element.$.loading).display, 'block');
+
+ element._loading = false;
+ element._repos = _.times(25, documentationGenerator);
+
+ flushAsynchronousOperations();
+ assert.equal(element.computeLoadingClass(element._loading), '');
+ assert.equal(getComputedStyle(element.$.loading).display, 'none');
+ });
+ });
+ });
+</script>
diff --git a/polygerrit-ui/app/elements/gr-app.html b/polygerrit-ui/app/elements/gr-app.html
index 787a1c6..b34cd0a 100644
--- a/polygerrit-ui/app/elements/gr-app.html
+++ b/polygerrit-ui/app/elements/gr-app.html
@@ -48,6 +48,7 @@
<link rel="import" href="../styles/shared-styles.html">
<link rel="import" href="../styles/themes/app-theme.html">
<link rel="import" href="./admin/gr-admin-view/gr-admin-view.html">
+<link rel="import" href="./documentation/gr-documentation-search/gr-documentation-search.html">
<link rel="import" href="./change-list/gr-change-list-view/gr-change-list-view.html">
<link rel="import" href="./change-list/gr-dashboard-view/gr-dashboard-view.html">
<link rel="import" href="./change/gr-change-view/gr-change-view.html">
@@ -198,6 +199,11 @@
<template is="dom-if" if="[[_showCLAView]]" restamp="true">
<gr-cla-view></gr-cla-view>
</template>
+ <template is="dom-if" if="[[_showDocumentationSearch]]" restamp="true">
+ <gr-documentation-search
+ params="[[params]]">
+ </gr-documentation-search>
+ </template>
<div id="errorView" class="errorView">
<div class="errorEmoji">[[_lastError.emoji]]</div>
<div class="errorText">[[_lastError.text]]</div>
diff --git a/polygerrit-ui/app/elements/gr-app.js b/polygerrit-ui/app/elements/gr-app.js
index b0cc514..9c465f0 100644
--- a/polygerrit-ui/app/elements/gr-app.js
+++ b/polygerrit-ui/app/elements/gr-app.js
@@ -72,6 +72,7 @@
_showCLAView: Boolean,
_showEditorView: Boolean,
_showPluginScreen: Boolean,
+ _showDocumentationSearch: Boolean,
/** @type {?} */
_viewState: Object,
/** @type {?} */
@@ -315,6 +316,8 @@
if (isPluginScreen) {
this.async(() => this.set('_showPluginScreen', true), 1);
}
+ this.set('_showDocumentationSearch',
+ view === Gerrit.Nav.View.DOCUMENTATION_SEARCH);
if (this.params.justRegistered) {
this.$.registrationOverlay.open();
this.$.registrationDialog.loadData().then(() => {
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index c0078e9..2a1ad9e 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -2981,6 +2981,22 @@
});
},
+ /**
+ * @param {string} filter
+ * @return {!Promise<?Object>}
+ */
+ getDocumentationSearches(filter) {
+ filter = filter.trim();
+ const encodedFilter = encodeURIComponent(filter);
+
+ // TODO(kaspern): Rename rest api from /projects/ to /repos/ once backend
+ // supports it.
+ return this._fetchSharedCacheURL({
+ url: `/Documentation/?q=${encodedFilter}`,
+ anonymizedUrl: '/Documentation/?*',
+ });
+ },
+
getMergeable(changeNum) {
return this._getChangeURLAndFetch({
changeNum,
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index 5b9ae15..10d3e0d 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -120,6 +120,7 @@
'diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.html',
'diff/gr-selection-action-box/gr-selection-action-box_test.html',
'diff/gr-syntax-layer/gr-syntax-layer_test.html',
+ 'documentation/gr-documentation-search/gr-documentation-search_test.html',
'edit/gr-default-editor/gr-default-editor_test.html',
'edit/gr-edit-controls/gr-edit-controls_test.html',
'edit/gr-edit-file-controls/gr-edit-file-controls_test.html',