Merge "Standalone PolyGerrit plugins"
This commit is contained in:
24
Documentation/dev-plugins-pg.txt
Normal file
24
Documentation/dev-plugins-pg.txt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
= Gerrit Code Review - PolyGerrit Plugin Development
|
||||||
|
|
||||||
|
CAUTION: Work in progress. Hard hat area. +
|
||||||
|
This document will be populated with details along with implementation. +
|
||||||
|
link:https://groups.google.com/d/topic/repo-discuss/vb8WJ4m0hK0/discussion[Join the discussion.]
|
||||||
|
|
||||||
|
== Plugin loading and initialization
|
||||||
|
|
||||||
|
link:https://gerrit-review.googlesource.com/Documentation/js-api.html#_entry_point[Entry point] for the plugin and the loading method is based on link:http://w3c.github.io/webcomponents/spec/imports/[HTML Imports] spec.
|
||||||
|
|
||||||
|
* Plugin provides index.html, similar to link:https://gerrit-review.googlesource.com/Documentation/dev-plugins.html#deployment[.js Web UI plugins]
|
||||||
|
* index.html contains a `dom-module` tag with a script that uses `Gerrit.install()`.
|
||||||
|
* PolyGerrit imports index.html along with all required resources defined in it (fonts, styles, etc)
|
||||||
|
* For standalone plugins, the entry point file is a `pluginname.html` file located in `gerrit-site/plugins` folder, where pluginname is an alphanumeric plugin name.
|
||||||
|
|
||||||
|
Here's a sample `myplugin.html`:
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<dom-module id="my-plugin">
|
||||||
|
<script>
|
||||||
|
Gerrit.install(function() { console.log('Ready.'); });
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
|
```
|
||||||
@@ -19,4 +19,5 @@ import java.util.List;
|
|||||||
public class PluginConfigInfo {
|
public class PluginConfigInfo {
|
||||||
public Boolean hasAvatars;
|
public Boolean hasAvatars;
|
||||||
public List<String> jsResourcePaths;
|
public List<String> jsResourcePaths;
|
||||||
|
public List<String> htmlResourcePaths;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
|||||||
import com.google.gwt.user.client.ui.DialogBox;
|
import com.google.gwt.user.client.ui.DialogBox;
|
||||||
import com.google.gwtexpui.progress.client.ProgressBar;
|
import com.google.gwtexpui.progress.client.ProgressBar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/** Loads JavaScript plugins with a progress meter visible. */
|
/** Loads JavaScript plugins with a progress meter visible. */
|
||||||
public class PluginLoader extends DialogBox {
|
public class PluginLoader extends DialogBox {
|
||||||
@@ -37,6 +38,13 @@ public class PluginLoader extends DialogBox {
|
|||||||
List<String> plugins, int loadTimeout, AsyncCallback<VoidResult> callback) {
|
List<String> plugins, int loadTimeout, AsyncCallback<VoidResult> callback) {
|
||||||
if (plugins == null || plugins.isEmpty()) {
|
if (plugins == null || plugins.isEmpty()) {
|
||||||
callback.onSuccess(VoidResult.create());
|
callback.onSuccess(VoidResult.create());
|
||||||
|
}
|
||||||
|
plugins = plugins
|
||||||
|
.stream()
|
||||||
|
.filter(p -> p.endsWith(".js"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (plugins.isEmpty()) {
|
||||||
|
callback.onSuccess(VoidResult.create());
|
||||||
} else {
|
} else {
|
||||||
self = new PluginLoader(loadTimeout, callback);
|
self = new PluginLoader(loadTimeout, callback);
|
||||||
self.load(plugins);
|
self.load(plugins);
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@@ -637,7 +638,11 @@ class HttpPluginServlet extends HttpServlet implements StartPluginListener, Relo
|
|||||||
Path path = plugin.getSrcFile();
|
Path path = plugin.getSrcFile();
|
||||||
if (req.getRequestURI().endsWith(getJsPluginPath(plugin)) && Files.exists(path)) {
|
if (req.getRequestURI().endsWith(getJsPluginPath(plugin)) && Files.exists(path)) {
|
||||||
res.setHeader("Content-Length", Long.toString(Files.size(path)));
|
res.setHeader("Content-Length", Long.toString(Files.size(path)));
|
||||||
res.setContentType("application/javascript");
|
if (path.toString().toLowerCase(Locale.US).endsWith(".html")) {
|
||||||
|
res.setContentType("text/html");
|
||||||
|
} else {
|
||||||
|
res.setContentType("application/javascript");
|
||||||
|
}
|
||||||
writeToResponse(res, Files.newInputStream(path));
|
writeToResponse(res, Files.newInputStream(path));
|
||||||
} else {
|
} else {
|
||||||
resourceCache.put(key, Resource.NOT_FOUND);
|
resourceCache.put(key, Resource.NOT_FOUND);
|
||||||
|
|||||||
@@ -309,9 +309,15 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
PluginConfigInfo info = new PluginConfigInfo();
|
PluginConfigInfo info = new PluginConfigInfo();
|
||||||
info.hasAvatars = toBoolean(avatar.get() != null);
|
info.hasAvatars = toBoolean(avatar.get() != null);
|
||||||
info.jsResourcePaths = new ArrayList<>();
|
info.jsResourcePaths = new ArrayList<>();
|
||||||
|
info.htmlResourcePaths = new ArrayList<>();
|
||||||
for (WebUiPlugin u : plugins) {
|
for (WebUiPlugin u : plugins) {
|
||||||
info.jsResourcePaths.add(
|
String path = String.format(
|
||||||
String.format("plugins/%s/%s", u.getPluginName(), u.getJavaScriptResourcePath()));
|
"plugins/%s/%s", u.getPluginName(), u.getJavaScriptResourcePath());
|
||||||
|
if (path.endsWith(".html")) {
|
||||||
|
info.htmlResourcePaths.add(path);
|
||||||
|
} else {
|
||||||
|
info.jsResourcePaths.add(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
Path path = entry.getValue();
|
Path path = entry.getValue();
|
||||||
String fileName = path.getFileName().toString();
|
String fileName = path.getFileName().toString();
|
||||||
if (!isJsPlugin(fileName) && !serverPluginFactory.handles(path)) {
|
if (!isUiPlugin(fileName) && !serverPluginFactory.handles(path)) {
|
||||||
log.warn("No Plugin provider was found that handles this file format: {}", fileName);
|
log.warn("No Plugin provider was found that handles this file format: {}", fileName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
private Plugin loadPlugin(String name, Path srcPlugin, FileSnapshot snapshot)
|
private Plugin loadPlugin(String name, Path srcPlugin, FileSnapshot snapshot)
|
||||||
throws InvalidPluginException {
|
throws InvalidPluginException {
|
||||||
String pluginName = srcPlugin.getFileName().toString();
|
String pluginName = srcPlugin.getFileName().toString();
|
||||||
if (isJsPlugin(pluginName)) {
|
if (isUiPlugin(pluginName)) {
|
||||||
return loadJsPlugin(name, srcPlugin, snapshot);
|
return loadJsPlugin(name, srcPlugin, snapshot);
|
||||||
} else if (serverPluginFactory.handles(srcPlugin)) {
|
} else if (serverPluginFactory.handles(srcPlugin)) {
|
||||||
return loadServerPlugin(srcPlugin, snapshot);
|
return loadServerPlugin(srcPlugin, snapshot);
|
||||||
@@ -718,8 +718,8 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
|
|
||||||
public String getGerritPluginName(Path srcPath) {
|
public String getGerritPluginName(Path srcPath) {
|
||||||
String fileName = srcPath.getFileName().toString();
|
String fileName = srcPath.getFileName().toString();
|
||||||
if (isJsPlugin(fileName)) {
|
if (isUiPlugin(fileName)) {
|
||||||
return fileName.substring(0, fileName.length() - 3);
|
return fileName.substring(0, fileName.lastIndexOf('.'));
|
||||||
}
|
}
|
||||||
if (serverPluginFactory.handles(srcPath)) {
|
if (serverPluginFactory.handles(srcPath)) {
|
||||||
return serverPluginFactory.getPluginName(srcPath);
|
return serverPluginFactory.getPluginName(srcPath);
|
||||||
@@ -735,8 +735,8 @@ public class PluginLoader implements LifecycleListener {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isJsPlugin(String name) {
|
private static boolean isUiPlugin(String name) {
|
||||||
return isPlugin(name, "js");
|
return isPlugin(name, "js") || isPlugin(name, "html");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPlugin(String fileName, String ext) {
|
private static boolean isPlugin(String fileName, String ext) {
|
||||||
|
|||||||
@@ -74,6 +74,18 @@ limitations under the License.
|
|||||||
.webLink {
|
.webLink {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
section.assignee {
|
||||||
|
@apply(--change-metadata-assignee);
|
||||||
|
}
|
||||||
|
section.labelStatus {
|
||||||
|
@apply(--change-metadata-label-status);
|
||||||
|
}
|
||||||
|
section.strategy {
|
||||||
|
@apply(--change-metadata-strategy);
|
||||||
|
}
|
||||||
|
section.topic {
|
||||||
|
@apply(--change-metadata-topic);
|
||||||
|
}
|
||||||
@media screen and (max-width: 50em), screen and (min-width: 75em) {
|
@media screen and (max-width: 50em), screen and (min-width: 75em) {
|
||||||
:host {
|
:host {
|
||||||
display: table;
|
display: table;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
|
||||||
<link rel="import" href="../styles/app-theme.html">
|
<link rel="import" href="../styles/app-theme.html">
|
||||||
|
<link rel="import" href="./plugins/gr-plugin-host/gr-plugin-host.html">
|
||||||
|
|
||||||
<link rel="import" href="./admin/gr-admin-view/gr-admin-view.html">
|
<link rel="import" href="./admin/gr-admin-view/gr-admin-view.html">
|
||||||
|
|
||||||
@@ -170,6 +171,9 @@ limitations under the License.
|
|||||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||||
<gr-reporting id="reporting"></gr-reporting>
|
<gr-reporting id="reporting"></gr-reporting>
|
||||||
<gr-router id="router"></gr-router>
|
<gr-router id="router"></gr-router>
|
||||||
|
<gr-plugin-host id="plugins"
|
||||||
|
config="[[_serverConfig.plugin]]">
|
||||||
|
</gr-plugin-host>
|
||||||
</template>
|
</template>
|
||||||
<script src="gr-app.js" crossorigin="anonymous"></script>
|
<script src="gr-app.js" crossorigin="anonymous"></script>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|||||||
@@ -62,7 +62,6 @@
|
|||||||
|
|
||||||
observers: [
|
observers: [
|
||||||
'_viewChanged(params.view)',
|
'_viewChanged(params.view)',
|
||||||
'_loadPlugins(_serverConfig.plugin.js_resource_paths)',
|
|
||||||
],
|
],
|
||||||
|
|
||||||
behaviors: [
|
behaviors: [
|
||||||
@@ -128,17 +127,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_loadPlugins: function(plugins) {
|
|
||||||
Gerrit._setPluginsCount(plugins.length);
|
|
||||||
for (var i = 0; i < plugins.length; i++) {
|
|
||||||
var scriptEl = document.createElement('script');
|
|
||||||
scriptEl.defer = true;
|
|
||||||
scriptEl.src = '/' + plugins[i];
|
|
||||||
scriptEl.onerror = Gerrit._pluginInstalled;
|
|
||||||
document.body.appendChild(scriptEl);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_loginTapHandler: function(e) {
|
_loginTapHandler: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
page.show('/login/' + encodeURIComponent(
|
page.show('/login/' + encodeURIComponent(
|
||||||
|
|||||||
@@ -89,10 +89,16 @@ limitations under the License.
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sets plugins count', function() {
|
test('passes config to gr-plugin-host', function(done) {
|
||||||
sandbox.stub(Gerrit, '_setPluginsCount');
|
var config = {plugin: {}};
|
||||||
element._loadPlugins([]);
|
element.$.restAPI.getConfig.restore();
|
||||||
assert.isTrue(Gerrit._setPluginsCount.calledWithExactly(0));
|
sandbox.stub(
|
||||||
|
element.$.restAPI, 'getConfig').returns(Promise.resolve(config));
|
||||||
|
element.attached();
|
||||||
|
flush(function() {
|
||||||
|
assert.strictEqual(element.$.plugins.config, config.plugin);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2017 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="../../shared/gr-js-api-interface/gr-js-api-interface.html">
|
||||||
|
|
||||||
|
<dom-module id="gr-plugin-host">
|
||||||
|
<script src="gr-plugin-host.js"></script>
|
||||||
|
</dom-module>
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (C) 2017 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-plugin-host',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
config: {
|
||||||
|
type: Object,
|
||||||
|
observer: "_configChanged",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
_configChanged: function(config) {
|
||||||
|
var jsPlugins = config.js_resource_paths || [];
|
||||||
|
var htmlPlugins = config.html_resource_paths || [];
|
||||||
|
Gerrit._setPluginsCount(jsPlugins.length + htmlPlugins.length);
|
||||||
|
this._loadJsPlugins(jsPlugins);
|
||||||
|
this._importHtmlPlugins(htmlPlugins);
|
||||||
|
},
|
||||||
|
|
||||||
|
_importHtmlPlugins: function(plugins) {
|
||||||
|
plugins.forEach(function(url) {
|
||||||
|
this.importHref('/' + url, null, Gerrit._pluginInstalled, true);
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_loadJsPlugins: function(plugins) {
|
||||||
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
|
var url = plugins[i];
|
||||||
|
var scriptEl = document.createElement('script');
|
||||||
|
scriptEl.defer = true;
|
||||||
|
scriptEl.src = '/' + plugins[i];
|
||||||
|
scriptEl.onerror = Gerrit._pluginInstalled;
|
||||||
|
document.body.appendChild(scriptEl);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})();
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2017 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-plugin-host</title>
|
||||||
|
|
||||||
|
<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
|
||||||
|
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||||
|
|
||||||
|
<link rel="import" href="gr-plugin-host.html">
|
||||||
|
|
||||||
|
<test-fixture id="basic">
|
||||||
|
<template>
|
||||||
|
<gr-plugin-host></gr-plugin-host>
|
||||||
|
</template>
|
||||||
|
</test-fixture>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
suite('gr-diff tests', function() {
|
||||||
|
var element;
|
||||||
|
var sandbox;
|
||||||
|
|
||||||
|
setup(function() {
|
||||||
|
element = fixture('basic');
|
||||||
|
sandbox = sinon.sandbox.create();
|
||||||
|
sandbox.stub(document.body, 'appendChild');
|
||||||
|
sandbox.stub(element, 'importHref');
|
||||||
|
});
|
||||||
|
|
||||||
|
teardown(function() {
|
||||||
|
sandbox.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('counts plugins', function() {
|
||||||
|
sandbox.stub(Gerrit, '_setPluginsCount');
|
||||||
|
element.config = {
|
||||||
|
html_resource_paths: ['foo/bar', 'baz'],
|
||||||
|
js_resource_paths: ['42'],
|
||||||
|
};
|
||||||
|
assert.isTrue(Gerrit._setPluginsCount.calledWith(3));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('imports html plugins from config', function() {
|
||||||
|
element.config = {
|
||||||
|
html_resource_paths: ['foo/bar', 'baz'],
|
||||||
|
};
|
||||||
|
assert.isTrue(element.importHref.calledWith(
|
||||||
|
'/foo/bar', null, Gerrit._pluginInstalled, true));
|
||||||
|
assert.isTrue(element.importHref.calledWith(
|
||||||
|
'/baz', null, Gerrit._pluginInstalled, true));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -107,7 +107,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(andybons): Polyfill currentScript for IE10/11 (edge supports it).
|
// TODO(andybons): Polyfill currentScript for IE10/11 (edge supports it).
|
||||||
var src = opt_src || (document.currentScript && document.currentScript.src);
|
var src = opt_src || (document.currentScript &&
|
||||||
|
document.currentScript.src || document.currentScript.baseURI);
|
||||||
var plugin = new Plugin(src);
|
var plugin = new Plugin(src);
|
||||||
try {
|
try {
|
||||||
callback(plugin);
|
callback(plugin);
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ limitations under the License.
|
|||||||
'change/gr-change-view/gr-change-view_test.html',
|
'change/gr-change-view/gr-change-view_test.html',
|
||||||
'change/gr-comment-list/gr-comment-list_test.html',
|
'change/gr-comment-list/gr-comment-list_test.html',
|
||||||
'change/gr-commit-info/gr-commit-info_test.html',
|
'change/gr-commit-info/gr-commit-info_test.html',
|
||||||
|
'change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html',
|
||||||
'change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html',
|
'change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html',
|
||||||
'change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html',
|
'change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html',
|
||||||
'change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html',
|
|
||||||
'change/gr-download-dialog/gr-download-dialog_test.html',
|
'change/gr-download-dialog/gr-download-dialog_test.html',
|
||||||
'change/gr-file-list/gr-file-list_test.html',
|
'change/gr-file-list/gr-file-list_test.html',
|
||||||
'change/gr-message/gr-message_test.html',
|
'change/gr-message/gr-message_test.html',
|
||||||
@@ -53,8 +53,8 @@ limitations under the License.
|
|||||||
'core/gr-reporting/gr-reporting_test.html',
|
'core/gr-reporting/gr-reporting_test.html',
|
||||||
'core/gr-search-bar/gr-search-bar_test.html',
|
'core/gr-search-bar/gr-search-bar_test.html',
|
||||||
'diff/gr-diff-builder/gr-diff-builder_test.html',
|
'diff/gr-diff-builder/gr-diff-builder_test.html',
|
||||||
'diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html',
|
|
||||||
'diff/gr-diff-comment-thread-group/gr-diff-comment-thread-group_test.html',
|
'diff/gr-diff-comment-thread-group/gr-diff-comment-thread-group_test.html',
|
||||||
|
'diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html',
|
||||||
'diff/gr-diff-comment/gr-diff-comment_test.html',
|
'diff/gr-diff-comment/gr-diff-comment_test.html',
|
||||||
'diff/gr-diff-cursor/gr-diff-cursor_test.html',
|
'diff/gr-diff-cursor/gr-diff-cursor_test.html',
|
||||||
'diff/gr-diff-highlight/gr-annotation_test.html',
|
'diff/gr-diff-highlight/gr-annotation_test.html',
|
||||||
@@ -71,6 +71,7 @@ limitations under the License.
|
|||||||
'diff/gr-syntax-layer/gr-syntax-layer_test.html',
|
'diff/gr-syntax-layer/gr-syntax-layer_test.html',
|
||||||
'diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html',
|
'diff/gr-syntax-lib-loader/gr-syntax-lib-loader_test.html',
|
||||||
'gr-app_test.html',
|
'gr-app_test.html',
|
||||||
|
'plugins/gr-plugin-host/gr-plugin-host_test.html',
|
||||||
'settings/gr-account-info/gr-account-info_test.html',
|
'settings/gr-account-info/gr-account-info_test.html',
|
||||||
'settings/gr-change-table-editor/gr-change-table-editor_test.html',
|
'settings/gr-change-table-editor/gr-change-table-editor_test.html',
|
||||||
'settings/gr-email-editor/gr-email-editor_test.html',
|
'settings/gr-email-editor/gr-email-editor_test.html',
|
||||||
|
|||||||
Reference in New Issue
Block a user