Skip to content

Commit 0754266

Browse files
8267709: Investigate differences between HtmlStyle and stylesheet.css
Reviewed-by: hannesw
1 parent 23189a1 commit 0754266

File tree

2 files changed

+222
-1
lines changed

2 files changed

+222
-1
lines changed

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ public enum HtmlStyle {
770770
packageUsePage,
771771

772772
/**
773-
* The class of the {@code body} element for the page listing any deprecated items.
773+
* The class of the {@code body} element for the page listing any preview items.
774774
*/
775775
previewListPage,
776776

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
25+
/*
26+
* @test
27+
* @bug 8267574
28+
* @summary check stylesheet names against HtmlStyle
29+
* @modules jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.markup
30+
* jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.resources:open
31+
*/
32+
33+
import java.io.BufferedWriter;
34+
import java.io.IOException;
35+
import java.io.InputStream;
36+
import java.io.PrintWriter;
37+
import java.net.URL;
38+
import java.nio.file.Files;
39+
import java.nio.file.Path;
40+
import java.util.Arrays;
41+
import java.util.Set;
42+
import java.util.TreeSet;
43+
import java.util.regex.Matcher;
44+
import java.util.regex.Pattern;
45+
import java.util.stream.Collectors;
46+
47+
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
48+
49+
/**
50+
* This test compares the set of CSS class names defined in HtmlStyle
51+
* and other files (such as search.js) against the set of CSS class names
52+
* defined in the main stylesheet.css provided by the doclet.
53+
*
54+
* The goal is to detect "unexpected" discrepancies between the two sets.
55+
* "Expected" discrepancies are taken into account, but may indicate a
56+
* need to resolve the discrepancy.
57+
*
58+
* The test does not take into direct account the recent introduction of
59+
* CSS constructs like section {@code [class$="-details"]}
60+
*/
61+
public class CheckStylesheetClasses {
62+
public static void main(String... args) throws Exception {
63+
CheckStylesheetClasses c = new CheckStylesheetClasses();
64+
c.run();
65+
}
66+
67+
int errors = 0;
68+
69+
void run() throws Exception {
70+
Set<String> htmlStyleNames = getHtmlStyleNames();
71+
Set<String> styleSheetNames = getStylesheetNames();
72+
73+
System.err.println("found " + htmlStyleNames.size() + " names in HtmlStyle");
74+
System.err.println("found " + styleSheetNames.size() + " names in stylesheet");
75+
76+
// Write the lists to external files for the benefit of external diff tools:
77+
// for example, to compare against the CSS class names used in generated documentation.
78+
// To find the classes used in a directory containing HTML files, use something like
79+
// find $DIRECTORY -name \*.html | \
80+
// xargs grep -o 'class="[^"]*"' | \
81+
// sed -e 's/^[^"]*"//' -e 's/".*$//' | \
82+
// while read line ; do for w in $line ; do echo $w ; done ; done | \
83+
// sort -u
84+
85+
try (BufferedWriter out = Files.newBufferedWriter(Path.of("htmlStyleNames.txt"));
86+
PrintWriter pw = new PrintWriter(out)) {
87+
htmlStyleNames.forEach(pw::println);
88+
}
89+
90+
try (BufferedWriter out = Files.newBufferedWriter(Path.of("styleSheetNames.txt"));
91+
PrintWriter pw = new PrintWriter(out)) {
92+
styleSheetNames.forEach(pw::println);
93+
}
94+
95+
// Remove names from htmlStyleNames if they are valid names generated by the doclet,
96+
// even if they do not by default require a style to be defined in the stylesheet.
97+
// In general, names in these lists are worthy of attention to see if they *should*
98+
// be defined in the stylesheet, especially when the names exist in a family of
99+
// related items: related by name or by function.
100+
101+
// the page names are provided to override a style on a specific page;
102+
// only some are used in the stylesheet
103+
htmlStyleNames.removeIf(s -> s.endsWith("-page") && !styleSheetNames.contains(s));
104+
105+
// descriptions; class-description is used;
106+
// surprisingly? module-description and package-description are not
107+
htmlStyleNames.removeIf(s -> s.endsWith("-description") && !styleSheetNames.contains(s));
108+
109+
// help page
110+
htmlStyleNames.removeIf(s -> s.startsWith("help-") && !styleSheetNames.contains(s));
111+
112+
// summary and details tables; styles for these may be present in the stylesheet
113+
// using constructs like these:
114+
// .summary section[class$="-summary"], .details section[class$="-details"],
115+
htmlStyleNames.removeIf(s -> s.endsWith("-details"));
116+
htmlStyleNames.removeIf(s -> s.endsWith("-summary") && !styleSheetNames.contains(s));
117+
118+
// signature classes
119+
removeAll(htmlStyleNames, "annotations", "element-name", "extends-implements",
120+
"modifiers", "permits", "return-type");
121+
122+
// misc: these are defined in HtmlStyle, and used by the doclet
123+
removeAll(htmlStyleNames, "col-plain", "details-table", "external-link",
124+
"hierarchy", "index", "package-uses", "packages", "permits-note",
125+
"serialized-package-container", "source-container");
126+
127+
// Remove names from styleSheetNames if they are false positives,
128+
// or used by other code (i.e. not HtmlStyle),
129+
// or if they are unused and therefore candidates to be deleted.
130+
131+
// false positives: file extensions and URL components
132+
removeAll(styleSheetNames, "css", "png", "w3");
133+
134+
// for doc-comment authors; maybe worthy of inclusion in HtmlStyle, just to be documented
135+
removeAll(styleSheetNames, "borderless", "plain", "striped");
136+
137+
// used in search.js; may be worth documenting in HtmlStyle
138+
removeAll(styleSheetNames, "result-highlight", "result-item",
139+
"search-tag-desc-result", "search-tag-holder-result",
140+
"ui-autocomplete", "ui-autocomplete-category",
141+
"watermark");
142+
143+
// very JDK specific
144+
styleSheetNames.remove("module-graph");
145+
146+
// apparently unused
147+
// "tab" is commented implying it is in the header/footer, but
148+
// (a) it is a poorly chosen name
149+
// (b) it does not seem to be used in make/Docs.gmk or anywhere else
150+
removeAll(styleSheetNames, "all-classes-container", "all-packages-container",
151+
"bottom-nav", "clear", "constant-values-container", "deprecated-content",
152+
"footer", "hidden", "override-specify-label", "serialized-class-details",
153+
"tab", "table-sub-heading-color");
154+
155+
boolean ok = check(htmlStyleNames, "HtmlStyle", styleSheetNames, "stylesheet")
156+
& check(styleSheetNames, "stylesheet", htmlStyleNames, "HtmlStyle");
157+
158+
if (!ok) {
159+
throw new Exception("differences found");
160+
}
161+
162+
if (errors > 0) {
163+
throw new Exception(errors + " errors found");
164+
}
165+
}
166+
167+
boolean check(Set<String> s1, String l1, Set<String> s2, String l2) {
168+
boolean equal = true;
169+
for (String s : s1) {
170+
if (!s2.contains(s)) {
171+
System.err.println("In " + l1 + " but not " + l2 + ": " + s);
172+
equal = false;
173+
}
174+
}
175+
return equal;
176+
}
177+
178+
/**
179+
* Remove all the names from the set, giving a message for any that were not found.
180+
*/
181+
void removeAll(Set<String> set, String... names) {
182+
for (String name : names) {
183+
if (!set.remove(name)) {
184+
error("name not found in set: " + name);
185+
}
186+
}
187+
}
188+
189+
void error(String message) {
190+
System.err.println("error: " + message);
191+
errors++;
192+
}
193+
194+
Set<String> getHtmlStyleNames() {
195+
return Arrays.stream(HtmlStyle.values())
196+
.map(HtmlStyle::cssName)
197+
.collect(Collectors.toCollection(TreeSet::new));
198+
}
199+
200+
Set<String> getStylesheetNames() throws IOException {
201+
Set<String> names = new TreeSet<>();
202+
String stylesheet = "/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css";
203+
URL url = HtmlStyle.class.getResource(stylesheet);
204+
readStylesheet(url, names);
205+
return names;
206+
}
207+
208+
private void readStylesheet(URL resource, Set<String> names) throws IOException {
209+
try (InputStream in = resource.openStream()) {
210+
if (in == null) {
211+
throw new AssertionError("Cannot find or access resource " + resource);
212+
}
213+
String s = new String(in.readAllBytes());
214+
Pattern p = Pattern.compile("(?i)(\\s|([a-z][a-z0-9-]*))\\.(?<name>[a-z0-9-]+)\\b");
215+
Matcher m = p.matcher(s);
216+
while (m.find()) {
217+
names.add(m.group("name"));
218+
}
219+
}
220+
}
221+
}

0 commit comments

Comments
 (0)