Support inheriting of CSS
Change-Id: Ib04c452561d1204dc3b392238f52193d43a09f52
Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java
index 4d859b5..e84e1e4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/XDocGlobalConfig.java
@@ -23,12 +23,12 @@
public class XDocGlobalConfig {
public static final String SECTION_FORMATTER = "formatter";
public static final String KEY_ALLOW_HTML = "allowHtml";
- public static final String KEY_APPEND_CSS = "appendCss";
public static final String KEY_CSS_THEME = "cssTheme";
public static final String KEY_ENABLED = "enabled";
public static final String KEY_EXT = "ext";
public static final String KEY_FORMATTER = "formatter";
public static final String KEY_INCLUDE_TOC = "includeToc";
+ public static final String KEY_INHERIT_CSS = "inheritCss";
public static final String KEY_MIME_TYPE = "mimeType";
public static final String KEY_PREFIX = "prefix";
public static final String KEY_PRIO = "prio";
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/AsciidoctorFormatter.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/AsciidoctorFormatter.java
index fe57a90..8f86ccf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/AsciidoctorFormatter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/AsciidoctorFormatter.java
@@ -15,9 +15,9 @@
package com.googlesource.gerrit.plugins.xdocs.formatter;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_ALLOW_HTML;
-import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_APPEND_CSS;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_CSS_THEME;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_INCLUDE_TOC;
+import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_INHERIT_CSS;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.MoreObjects;
@@ -80,7 +80,7 @@
}
ConfigSection projectCfg =
- formatters.getFormatterConfig(globalCfg.getSubsection(), projectName);
+ formatters.getFormatterConfig(NAME, projectName);
// asciidoctor ignores all attributes if no output file is specified,
// this is why we must specify an output file and then read its content
File tmpFile =
@@ -93,15 +93,16 @@
ByteStreams.copy(input, out);
String html = out.toString(UTF_8.name());
String cssTheme = projectCfg.getString(KEY_CSS_THEME);
- String globalCss = util.getGlobalCss("asciidoctor", cssTheme);
+ String inheritedCss =
+ util.getInheritedCss(projectName, NAME, "asciidoctor", cssTheme);
String projectCss = util.getCss(projectName, "asciidoctor", cssTheme);
- if (projectCfg.getBoolean(KEY_APPEND_CSS, true)) {
+ if (projectCfg.getBoolean(KEY_INHERIT_CSS, true)) {
return util.insertCss(html,
- MoreObjects.firstNonNull(globalCss, defaultCss), projectCss);
+ MoreObjects.firstNonNull(inheritedCss, defaultCss), projectCss);
} else {
return util.insertCss(html,
MoreObjects.firstNonNull(projectCss,
- MoreObjects.firstNonNull(globalCss, defaultCss)));
+ MoreObjects.firstNonNull(inheritedCss, defaultCss)));
}
}
} finally {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/FormatterUtil.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/FormatterUtil.java
index 47aedf4..2c49704 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/FormatterUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/FormatterUtil.java
@@ -14,18 +14,24 @@
package com.googlesource.gerrit.plugins.xdocs.formatter;
+import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_INHERIT_CSS;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
+import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.xdocs.ConfigSection;
+
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
@@ -46,14 +52,20 @@
private final String pluginName;
private final File baseDir;
private final GitRepositoryManager repoManager;
+ private final ProjectCache projectCache;
+ private final Formatters formatters;
@Inject
FormatterUtil(@PluginName String pluginName,
@PluginData File baseDir,
- GitRepositoryManager repoManager) {
+ GitRepositoryManager repoManager,
+ ProjectCache projectCache,
+ Formatters formatters) {
this.pluginName = pluginName;
this.baseDir = baseDir;
this.repoManager = repoManager;
+ this.projectCache = projectCache;
+ this.formatters = formatters;
}
/**
@@ -90,6 +102,55 @@
}
/**
+ * Returns the inherited CSS.
+ *
+ * If the project has a parent project the CSS of the parent project is
+ * returned; if there is no parent project the global CSS is returned.
+ *
+ * @param projectName the name of the project
+ * @param formatterName the name of the formatter for which the CSS should be
+ * returned
+ * @param name the name of the CSS file without theme and without the ".css"
+ * file extension
+ * @param theme the name of the CSS theme, may be <code>null</code>, if given
+ * it is included into the CSS file name: '<name>-<theme>.css'
+ * @return the inherited CSS; HTML characters are escaped; <code>null</code>
+ * if there is no inherited CSS
+ * @throws IOException thrown in case of an I/O Error while reading the global
+ * CSS file
+ */
+ public String getInheritedCss(String projectName, String formatterName,
+ String name, String theme) throws IOException {
+ return getInheritedCss(projectCache.get(new Project.NameKey(projectName)),
+ formatterName, name, theme);
+ }
+
+ private String getInheritedCss(ProjectState project, String formatterName,
+ String name, String theme) throws IOException {
+ for (ProjectState parent : project.parents()) {
+ String css = getCss(parent.getProject().getName(), name, theme);
+ ConfigSection cfg =
+ formatters.getFormatterConfig(formatterName, parent);
+ if (cfg.getBoolean(KEY_INHERIT_CSS, true)) {
+ return joinCss(getInheritedCss(parent, formatterName, name, theme), css);
+ } else {
+ return css;
+ }
+ }
+ return getGlobalCss(name, theme);
+ }
+
+ private String joinCss(String css1, String css2) {
+ if (css1 == null) {
+ return css2;
+ }
+ if (css2 == null) {
+ return css1;
+ }
+ return Joiner.on('\n').join(css1, css2);
+ }
+
+ /**
* Returns the CSS from the file
* "<review-site>/data/<plugin-name>/css/<name>-<theme>.css".
*
diff --git a/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/MarkdownFormatter.java b/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/MarkdownFormatter.java
index f4aa3a8..5ce5a73 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/MarkdownFormatter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/xdocs/formatter/MarkdownFormatter.java
@@ -15,8 +15,8 @@
package com.googlesource.gerrit.plugins.xdocs.formatter;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_ALLOW_HTML;
-import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_APPEND_CSS;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_CSS_THEME;
+import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_INHERIT_CSS;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.inject.Inject;
@@ -43,30 +43,31 @@
public String format(String projectName, String revision,
ConfigSection globalCfg, String raw) throws IOException {
ConfigSection projectCfg =
- formatters.getFormatterConfig(globalCfg.getSubsection(), projectName);
+ formatters.getFormatterConfig(NAME, projectName);
com.google.gerrit.server.documentation.MarkdownFormatter f =
new com.google.gerrit.server.documentation.MarkdownFormatter();
if (!globalCfg.getBoolean(KEY_ALLOW_HTML, false)) {
f.suppressHtml();
}
String cssTheme = projectCfg.getString(KEY_CSS_THEME);
- String globalCss = util.getGlobalCss("markdown", cssTheme);
+ String inheritedCss =
+ util.getInheritedCss(projectName, NAME, "markdown", cssTheme);
String projectCss = util.getCss(projectName, "markdown", cssTheme);
- if (projectCfg.getBoolean(KEY_APPEND_CSS, true)) {
- // if there is no global CSS and f.setCss(null) is invoked
+ if (projectCfg.getBoolean(KEY_INHERIT_CSS, true)) {
+ // if there is no inherited CSS and f.setCss(null) is invoked
// com.google.gerrit.server.documentation.MarkdownFormatter applies the
// default CSS
- f.setCss(globalCss);
+ f.setCss(inheritedCss);
byte[] b = f.markdownToDocHtml(raw, UTF_8.name());
return util.insertCss(new String(b, UTF_8), projectCss);
} else {
if (projectCss != null) {
f.setCss(projectCss);
} else {
- // if there is no global CSS and f.setCss(null) is invoked
+ // if there is no inherited CSS and f.setCss(null) is invoked
// com.google.gerrit.server.documentation.MarkdownFormatter applies the
// default CSS
- f.setCss(globalCss);
+ f.setCss(inheritedCss);
}
byte[] b = f.markdownToDocHtml(raw, UTF_8.name());
return new String(b, UTF_8);
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 9cf7e1b..26d773e 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -86,19 +86,19 @@
Default: `true`
-<a id="appendCss">
-formatter.<formatter>.appendCss
-: Whether the project-specific CSS should be appended to the default CSS.
+<a id="inheritCss">
+formatter.<formatter>.inheritCss
+: Whether the CSS should be inherited or overridden.
If `false` the default CSS is completely replaced by the
project-specific CSS.
- Overrides the [global configuration of `appendCss`](#formatterAppendCss)
+ Overrides the [global configuration of `inheritCss`](#formatterInheritCss)
for this formatter.
Supported for the following formatters: `ASCIIDOCTOR`, `MARKDOWN`
- Default: `true` (project-specific CSS is appended to the default CSS)
+ Default: `true` (CSS is inherited)
<a id="cssTheme">
formatter.<formatter>.cssTheme
@@ -138,7 +138,8 @@
* `ASCIIDOCTOR`: `@PLUGIN@/asciidoctor.css`
* `MARKDOWN`: `@PLUGIN@/markdown.css`
-Custom CSS files are *NOT* inherited from parent projects.
+If link:inheritCss[inheritCss] is set to true custom CSS files are
+inherited from parent projects.
<a id="globalConfig">
Global Configuration
@@ -233,18 +234,18 @@
Default: `true`
-<a id="formatterAppendCss">
-formatter.<formatter>.appendCss
-: Whether project-specific CSS should be appended to the default CSS.
+<a id="formatterInheritCss">
+formatter.<formatter>.inheritCss
+: Whether CSS should be inherited or overridden.
If `false` the default CSS is completely replaced by the
project-specific CSS.
- Can be overridden on [project-level](#appendCss).
+ Can be overridden on [project-level](#inheritCss).
Supported for the following formatters: `ASCIIDOCTOR`, `MARKDOWN`
- Default: `true` (project-specific CSS is appended to the default CSS)
+ Default: `true` (CSS is inherited)
<a id="formatterCssTheme">
formatter.<formatter>.cssTheme