--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java Tue Mar 05 18:53:54 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java Tue Mar 05 10:35:29 2019 -0800
@@ -96,6 +96,7 @@
protected void generateFrameFile() throws DocFileIOException {
Content frame = getFrameDetails();
HtmlTree body = new HtmlTree(HtmlTag.BODY);
+ body.addAttr(HtmlAttr.CLASS, "frames");
body.addAttr(HtmlAttr.ONLOAD, "loadFrames()");
String topFilePath = configuration.topFile.getPath();
Script script = new Script(
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Mar 05 18:53:54 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Mar 05 10:35:29 2019 -0800
@@ -26,6 +26,7 @@
package jdk.javadoc.internal.doclets.formats.html;
import jdk.javadoc.internal.doclets.formats.html.markup.Head;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader;
import java.util.*;
@@ -2197,6 +2198,8 @@
*/
public HtmlTree getBody(boolean includeScript, String title) {
HtmlTree body = new HtmlTree(HtmlTag.BODY);
+ body.addAttr(HtmlAttr.CLASS, getBodyClass());
+
// Set window title string which is later printed
this.winTitle = title;
// Don't print windowtitle script for overview-frame, allclasses-frame
@@ -2210,6 +2213,15 @@
return body;
}
+ public String getBodyClass() {
+ return getClass().getSimpleName()
+ .replaceAll("(Writer)?(Impl)?$", "")
+ .replaceAll("AnnotationType", "Class")
+ .replaceAll("(.)([A-Z])", "$1-$2")
+ .replaceAll("(?i)^(module|package|class)$", "$1-declaration")
+ .toLowerCase(Locale.US);
+ }
+
Script getMainBodyScript() {
return mainBodyScript;
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java Tue Mar 05 18:53:54 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java Tue Mar 05 10:35:29 2019 -0800
@@ -107,7 +107,8 @@
bodyContent.addContent(HtmlTree.P(HtmlTree.A(targetPath, new StringContent(targetPath))));
- Content body = new HtmlTree(HtmlTag.BODY);
+ Content body = new HtmlTree(HtmlTag.BODY)
+ .addAttr(HtmlAttr.CLASS, "index-redirect");
HtmlTree main = HtmlTree.MAIN(bodyContent);
body.addContent(main);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Tue Mar 05 18:53:54 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Tue Mar 05 10:35:29 2019 -0800
@@ -37,6 +37,7 @@
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.internal.doclets.formats.html.markup.DocType;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@@ -264,7 +265,7 @@
* @return the header content for the HTML file
*/
private static Content getHeader() {
- return new HtmlTree(HtmlTag.BODY);
+ return new HtmlTree(HtmlTag.BODY).addAttr(HtmlAttr.CLASS, "source");
}
/**
--- a/test/langtools/jdk/javadoc/doclet/JavascriptWinTitle/JavascriptWinTitle.java Tue Mar 05 18:53:54 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/JavascriptWinTitle/JavascriptWinTitle.java Tue Mar 05 10:35:29 2019 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,13 +56,13 @@
checkExit(Exit.OK);
checkOutput("overview-summary.html", true,
"<script type=\"text/javascript\">",
- "<body>");
+ "<body class=\"package-index\">");
// Test that "onload" is not present in BODY tag:
- checkOutput("p1/package-summary.html", true, "<body>");
- checkOutput("overview-frame.html", true, "<body>");
- checkOutput("allclasses-frame.html", true, "<body>");
- checkOutput("p1/package-frame.html", true, "<body>");
+ checkOutput("p1/package-summary.html", true, "<body class=\"package-declaration\">");
+ checkOutput("overview-frame.html", true, "<body class=\"package-index-frame\">");
+ checkOutput("allclasses-frame.html", true, "<body class=\"all-classes-frame\">");
+ checkOutput("p1/package-frame.html", true, "<body class=\"package-frame\">");
// Test that win title javascript is followed by NOSCRIPT code.
checkOutput("p1/C.html", true,
--- a/test/langtools/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java Tue Mar 05 18:53:54 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java Tue Mar 05 10:35:29 2019 -0800
@@ -330,7 +330,7 @@
checkOutput("index.html", frames,
"<iframe ",
"</iframe>",
- "<body onload=\"loadFrames()\">\n"
+ "<body class=\"frames\" onload=\"loadFrames()\">\n"
+ "<script type=\"text/javascript\">\n"
+ "if (targetPage == \"\" || targetPage == \"undefined\")");
--- a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java Tue Mar 05 18:53:54 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java Tue Mar 05 10:35:29 2019 -0800
@@ -591,7 +591,7 @@
checkOutput("index.html", true,
"<!DOCTYPE HTML>",
"<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">",
- "<body onload=\"loadFrames()\">\n"
+ "<body class=\"frames\" onload=\"loadFrames()\">\n"
+ "<script type=\"text/javascript\">\n"
+ "if (targetPage == \"\" || targetPage == \"undefined\")\n"
+ " window.location.replace('overview-summary.html');\n"
--- a/test/langtools/jdk/javadoc/doclet/testJavascript/TestJavascript.java Tue Mar 05 18:53:54 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testJavascript/TestJavascript.java Tue Mar 05 10:35:29 2019 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -115,7 +115,7 @@
+ "</script>");
checkOutput("index.html", true,
- "<body onload=\"loadFrames()\"");
+ "<body class=\"frames\" onload=\"loadFrames()\"");
//Make sure title javascript only runs if is-external is not true
checkOutput("pkg/C.html", true,
--- a/test/langtools/jdk/javadoc/doclet/testMetadata/TestMetadata.java Tue Mar 05 18:53:54 2019 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testMetadata/TestMetadata.java Tue Mar 05 10:35:29 2019 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8218998
+ * @bug 8218998 8219946
* @summary Add metadata to generated API documentation files
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -62,6 +62,7 @@
enum Source { PACKAGES, MODULES };
final ToolBox tb = new ToolBox();
+ final Set<String> allBodyClassesFound = new HashSet<>();
final Set<String> allGeneratorsFound = new HashSet<>();
public void runTests() throws Exception {
@@ -93,6 +94,7 @@
}
javadoc(args.toArray(new String[args.size()]));
checkExit(Exit.OK);
+ checkBodyClasses();
checkMetadata();
// spot check the descriptions for declarations
@@ -126,10 +128,91 @@
failed("not found: " + notFound);
}
+ checking ("all body classes");
+ if (allBodyClassesFound.equals(allBodyClasses)) {
+ passed("all gbody classes found");
+ } else {
+ Set<String> notFound = new TreeSet<>(allBodyClasses);
+ notFound.removeAll(allBodyClassesFound);
+ failed("not found: " + notFound);
+ }
+
printSummary();
}
final Pattern nl = Pattern.compile("[\\r\\n]+");
+ final Pattern bodyPattern = Pattern.compile("<body [^>]*class=\"([^\"]+)\"");
+ final Set<String> allBodyClasses = Set.of(
+ "all-classes-frame",
+ "all-classes-index",
+ "all-packages-index",
+ "class-declaration",
+ "class-use",
+ "constants-summary",
+ "deprecated-list",
+ "doc-file",
+ "frames",
+ "help",
+ "index-redirect",
+ "module-declaration",
+ "module-frame",
+ "module-index",
+ "module-index-frame",
+ "module-package-index-frame",
+ "package-declaration",
+ "package-frame",
+ "package-index",
+ "package-index-frame",
+ "package-tree",
+ "package-use",
+ "serialized-form",
+ "single-index",
+ "source",
+ "split-index",
+ "tree"
+ );
+
+ void checkBodyClasses() throws IOException {
+ Path outputDirPath = outputDir.toPath();
+ for (Path p : tb.findFiles(".html", outputDirPath)) {
+ checkBodyClass(outputDirPath.relativize(p));
+ }
+ }
+
+ void checkBodyClass(Path p) {
+ checking("Check body: " + p);
+
+ List<String> bodyLines = nl.splitAsStream(readOutputFile(p.toString()))
+ .filter(s -> s.contains("<body class="))
+ .collect(Collectors.toList());
+
+ String bodyLine;
+ switch (bodyLines.size()) {
+ case 0:
+ failed("Not found: <body class=");
+ return;
+ case 1:
+ bodyLine = bodyLines.get(0);
+ break;
+ default:
+ failed("Multiple found: <body class=");
+ return;
+ }
+
+ Matcher m = bodyPattern.matcher(bodyLine);
+ if (m.find()) {
+ String bodyClass = m.group(1);
+ if (allBodyClasses.contains(bodyClass)) {
+ passed("found: " + bodyClass);
+ allBodyClassesFound.add(bodyClass);
+ } else {
+ failed("Unrecognized body class: " + bodyClass);
+ }
+ } else {
+ failed("Unrecognized line:\n" + bodyLine);
+ }
+ }
+
final Pattern contentPattern = Pattern.compile("content=\"([^\"]+)\">");
final Pattern generatorPattern = Pattern.compile("content=\"javadoc/([^\"]+)\">");
final Set<String> allGenerators = Set.of(