--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -592,7 +592,7 @@
}
Table table = getSummaryTable();
if (table.needsScript()) {
- writer.getScript().addContent(table.getScript());
+ writer.getMainBodyScript().append(table.getScript());
}
return table.toContent();
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -32,13 +32,11 @@
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
-import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
-import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
+import jdk.javadoc.internal.doclets.formats.html.markup.Script;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
-import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
/**
@@ -99,12 +97,12 @@
HtmlTree body = new HtmlTree(HtmlTag.BODY);
body.addAttr(HtmlAttr.ONLOAD, "loadFrames()");
String topFilePath = configuration.topFile.getPath();
- String javaScriptRefresh = "\nif (targetPage == \"\" || targetPage == \"undefined\")\n" +
- " window.location.replace('" + topFilePath + "');\n";
- RawHtml scriptContent = new RawHtml(javaScriptRefresh.replace("\n", DocletConstants.NL));
- HtmlTree scriptTree = HtmlTree.SCRIPT();
- scriptTree.addContent(scriptContent);
- body.addContent(scriptTree);
+ Script script = new Script(
+ "\nif (targetPage == \"\" || targetPage == \"undefined\")\n" +
+ " window.location.replace(")
+ .appendStringLiteral(topFilePath, '\'')
+ .append(");\n");
+ body.addContent(script.asContent());
Content noScript = HtmlTree.NOSCRIPT(contents.noScriptMessage);
body.addContent(noScript);
if (configuration.allowTag(HtmlTag.MAIN)) {
@@ -135,12 +133,12 @@
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
head.addContent(getGeneratedBy(!configuration.notimestamp));
- Content windowTitle = HtmlTree.TITLE(new StringContent(title));
+ Content windowTitle = HtmlTree.TITLE(title);
head.addContent(windowTitle);
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
head.addContent(meta);
addStyleSheetProperties(configuration, head);
- head.addContent(getFramesJavaScript());
+ head.addContent(getFramesScript().asContent());
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
head, body);
Content htmlDocument = new HtmlDocument(htmlDocType,
@@ -217,4 +215,64 @@
frame.setStyle(HtmlStyle.rightIframe);
contentTree.addContent(frame);
}
+
+ /**
+ * Returns a content tree for the SCRIPT tag for the main page(index.html).
+ *
+ * @return a content for the SCRIPT tag
+ */
+ protected Script getFramesScript() {
+ return new Script("\n" +
+ " tmpTargetPage = \"\" + window.location.search;\n" +
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" +
+ " tmpTargetPage = tmpTargetPage.substring(1);\n" +
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" +
+ " tmpTargetPage = \"undefined\";\n" +
+ " targetPage = tmpTargetPage;\n" +
+ " function validURL(url) {\n" +
+ " try {\n" +
+ " url = decodeURIComponent(url);\n" +
+ " }\n" +
+ " catch (error) {\n" +
+ " return false;\n" +
+ " }\n" +
+ " var pos = url.indexOf(\".html\");\n" +
+ " if (pos == -1 || pos != url.length - 5)\n" +
+ " return false;\n" +
+ " var allowNumber = false;\n" +
+ " var allowSep = false;\n" +
+ " var seenDot = false;\n" +
+ " for (var i = 0; i < url.length - 5; i++) {\n" +
+ " var ch = url.charAt(i);\n" +
+ " if ('a' <= ch && ch <= 'z' ||\n" +
+ " 'A' <= ch && ch <= 'Z' ||\n" +
+ " ch == '$' ||\n" +
+ " ch == '_' ||\n" +
+ " ch.charCodeAt(0) > 127) {\n" +
+ " allowNumber = true;\n" +
+ " allowSep = true;\n" +
+ " } else if ('0' <= ch && ch <= '9'\n" +
+ " || ch == '-') {\n" +
+ " if (!allowNumber)\n" +
+ " return false;\n" +
+ " } else if (ch == '/' || ch == '.') {\n" +
+ " if (!allowSep)\n" +
+ " return false;\n" +
+ " allowNumber = false;\n" +
+ " allowSep = false;\n" +
+ " if (ch == '.')\n" +
+ " seenDot = true;\n" +
+ " if (ch == '/' && seenDot)\n" +
+ " return false;\n" +
+ " } else {\n" +
+ " return false;\n" +
+ " }\n" +
+ " }\n" +
+ " return true;\n" +
+ " }\n" +
+ " function loadFrames() {\n" +
+ " if (targetPage != \"\" && targetPage != \"undefined\")\n" +
+ " top.classFrame.location = top.targetPage;\n" +
+ " }\n");
+ }
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -78,6 +78,7 @@
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
+import jdk.javadoc.internal.doclets.formats.html.markup.Script;
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
@@ -178,6 +179,13 @@
final static Pattern IMPROPER_HTML_CHARS = Pattern.compile(".*[&<>].*");
/**
+ * The window title of this file.
+ */
+ protected String winTitle;
+
+ protected Script mainBodyScript;
+
+ /**
* Constructor to construct the HtmlStandardWriter object.
*
* @param path File to be generated.
@@ -258,19 +266,18 @@
* @return a content tree for the script
*/
public Content getAllClassesLinkScript(String id) {
- HtmlTree script = HtmlTree.SCRIPT();
- String scriptCode = "<!--\n" +
- " allClassesLink = document.getElementById(\"" + id + "\");\n" +
+ Script script = new Script("<!--\n" +
+ " allClassesLink = document.getElementById(")
+ .appendStringLiteral(id)
+ .append(");\n" +
" if(window==top) {\n" +
" allClassesLink.style.display = \"block\";\n" +
" }\n" +
" else {\n" +
" allClassesLink.style.display = \"none\";\n" +
" }\n" +
- " //-->\n";
- Content scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
- script.addContent(scriptContent);
- Content div = HtmlTree.DIV(script);
+ " //-->\n");
+ Content div = HtmlTree.DIV(script.asContent());
Content div_noscript = HtmlTree.DIV(contents.noScriptMessage);
Content noScript = HtmlTree.NOSCRIPT(div_noscript);
div.addContent(noScript);
@@ -409,7 +416,7 @@
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
head.addContent(getGeneratedBy(!configuration.notimestamp));
- head.addContent(getTitle());
+ head.addContent(HtmlTree.TITLE(winTitle));
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
head.addContent(meta);
if (!configuration.notimestamp) {
@@ -607,13 +614,11 @@
tree.addContent(fixedNavDiv);
HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE);
tree.addContent(paddingDiv);
- HtmlTree scriptTree = HtmlTree.SCRIPT();
- String scriptCode = "<!--\n"
+ Script script = new Script(
+ "<!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
- + "//-->\n";
- RawHtml scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
- scriptTree.addContent(scriptContent);
- tree.addContent(scriptTree);
+ + "//-->\n");
+ tree.addContent(script.asContent());
} else {
subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
tree.addContent(subDiv);
@@ -2113,9 +2118,11 @@
HtmlTree javascript = HtmlTree.SCRIPT(pathToRoot.resolve(DocPaths.JAVASCRIPT).getPath());
head.addContent(javascript);
if (configuration.createindex) {
- if (pathToRoot != null && script != null) {
+ if (pathToRoot != null && mainBodyScript != null) {
String ptrPath = pathToRoot.isEmpty() ? "." : pathToRoot.getPath();
- script.addContent(new RawHtml("var pathtoroot = \"" + ptrPath + "/\";loadScripts(document, \'script\');"));
+ mainBodyScript.append("var pathtoroot = ")
+ .appendStringLiteral(ptrPath + "/")
+ .append(";loadScripts(document, \'script\');");
}
addJQueryFile(head, DocPaths.JSZIP_MIN);
addJQueryFile(head, DocPaths.JSZIPUTILS_MIN);
@@ -2548,7 +2555,52 @@
return new TableHeader(contents.packageLabel, contents.descriptionLabel);
}
- Content getScript() {
+ /**
+ * Returns an HtmlTree for the SCRIPT tag.
+ *
+ * @return an HtmlTree for the SCRIPT tag
+ */
+ protected Script getWinTitleScript() {
+ Script script = new Script();
+ if (winTitle != null && winTitle.length() > 0) {
+ script.append("<!--\n" +
+ " try {\n" +
+ " if (location.href.indexOf('is-external=true') == -1) {\n" +
+ " parent.document.title=")
+ .appendStringLiteral(winTitle)
+ .append(";\n" +
+ " }\n" +
+ " }\n" +
+ " catch(err) {\n" +
+ " }\n" +
+ "//-->\n");
+ }
return script;
}
+
+ /**
+ * Returns an HtmlTree for the BODY tag.
+ *
+ * @param includeScript set true if printing windowtitle script
+ * @param title title for the window
+ * @return an HtmlTree for the BODY tag
+ */
+ public HtmlTree getBody(boolean includeScript, String title) {
+ HtmlTree body = new HtmlTree(HtmlTag.BODY);
+ // Set window title string which is later printed
+ this.winTitle = title;
+ // Don't print windowtitle script for overview-frame, allclasses-frame
+ // and package-frame
+ if (includeScript) {
+ this.mainBodyScript = getWinTitleScript();
+ body.addContent(mainBodyScript.asContent());
+ Content noScript = HtmlTree.NOSCRIPT(HtmlTree.DIV(contents.noScriptMessage));
+ body.addContent(noScript);
+ }
+ return body;
+ }
+
+ Script getMainBodyScript() {
+ return mainBodyScript;
+ }
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -32,6 +32,7 @@
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.Script;
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -73,18 +74,18 @@
String title = (configuration.windowtitle.length() > 0)
? configuration.windowtitle
- : configuration.getText("doclet.Generated_Docs_Untitled");
+ : resources.getText("doclet.Generated_Docs_Untitled");
- Content windowTitle = HtmlTree.TITLE(new StringContent(title));
+ Content windowTitle = HtmlTree.TITLE(title);
head.addContent(windowTitle);
Content metaContentType = HtmlTree.META("Content", CONTENT_TYPE, configuration.charset);
head.addContent(metaContentType);
String topFilePath = configuration.topFile.getPath();
- String javaScriptRefresh = "window.location.replace('" + topFilePath + "')";
- HtmlTree scriptTree = HtmlTree.SCRIPT();
- scriptTree.addContent(javaScriptRefresh);
- head.addContent(scriptTree);
+ Script script = new Script("window.location.replace(")
+ .appendStringLiteral(topFilePath, '\'')
+ .append(")");
+ head.addContent(script.asContent());
HtmlTree metaRefresh = new HtmlTree(HtmlTag.META);
metaRefresh.addAttr(HtmlAttr.HTTP_EQUIV, "Refresh");
metaRefresh.addAttr(HtmlAttr.CONTENT, "0;" + topFilePath);
@@ -98,7 +99,7 @@
ContentBuilder bodyContent = new ContentBuilder();
bodyContent.addContent(HtmlTree.NOSCRIPT(
- HtmlTree.P(configuration.getContent("doclet.No_Script_Message"))));
+ HtmlTree.P(contents.getContent("doclet.No_Script_Message"))));
bodyContent.addContent(HtmlTree.P(HtmlTree.A(topFilePath, new StringContent(topFilePath))));
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -162,7 +162,7 @@
}
if (table.needsScript()) {
- getScript().addContent(table.getScript());
+ mainBodyScript.append(table.getScript());
}
}
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Thu Nov 16 15:06:17 2017 -0800
@@ -626,7 +626,7 @@
addPackageTableRows(table);
li.addContent(table.toContent());
if (table.needsScript()) {
- script.addContent(new RawHtml(table.getScript()));
+ mainBodyScript.append(table.getScript());
}
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -144,7 +144,7 @@
}
if (table.needsScript()) {
- getScript().addContent(table.getScript());
+ getMainBodyScript().append(table.getScript());
}
}
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Thu Nov 16 15:06:17 2017 -0800
@@ -42,6 +42,7 @@
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.Messages;
+import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
@@ -77,6 +78,7 @@
private final HtmlConfiguration configuration;
private final Messages messages;
+ private final Resources resources;
private final Utils utils;
private final DocletEnvironment docEnv;
@@ -93,6 +95,7 @@
DocPath outputdir) {
this.configuration = configuration;
this.messages = configuration.getMessages();
+ this.resources = configuration.resources;
this.utils = configuration.utils;
this.docEnv = rd;
this.outputdir = outputdir;
@@ -193,7 +196,7 @@
body.addContent((configuration.allowTag(HtmlTag.MAIN)) ? HtmlTree.MAIN(div) : div);
writeToFile(body, outputdir.resolve(DocPath.forClass(utils, te)));
} catch (IOException e) {
- String message = configuration.resources.getText("doclet.exception.read.file", fo.getName());
+ String message = resources.getText("doclet.exception.read.file", fo.getName());
throw new SimpleDocletException(message, e);
}
}
@@ -209,8 +212,7 @@
? DocType.HTML5
: DocType.TRANSITIONAL;
Content head = new HtmlTree(HtmlTag.HEAD);
- head.addContent(HtmlTree.TITLE(new StringContent(
- configuration.getText("doclet.Window_Source_title"))));
+ head.addContent(HtmlTree.TITLE(resources.getText("doclet.Window_Source_title")));
addStyleSheetProperties(head);
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
head, body);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/ContentBuilder.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/ContentBuilder.java Thu Nov 16 15:06:17 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -39,6 +39,14 @@
public class ContentBuilder extends Content {
protected List<Content> contents = Collections.emptyList();
+ public ContentBuilder() { }
+
+ public ContentBuilder(Content... contents) {
+ for (Content c : contents) {
+ addContent(c);
+ }
+ }
+
@Override
public void addContent(Content content) {
nullCheck(content);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java Thu Nov 16 15:06:17 2017 -0800
@@ -74,8 +74,8 @@
*/
public HtmlTree(HtmlTag tag, Content... contents) {
this(tag);
- for (Content content: contents)
- addContent(content);
+ for (Content c: contents)
+ addContent(c);
}
/**
@@ -86,8 +86,8 @@
*/
public HtmlTree(HtmlTag tag, List<Content> contents) {
this(tag);
- for (Content content: contents)
- addContent(content);
+ for (Content c: contents)
+ addContent(c);
}
/**
@@ -146,8 +146,8 @@
@Override
public void addContent(Content tagContent) {
if (tagContent instanceof ContentBuilder) {
- for (Content content: ((ContentBuilder)tagContent).contents) {
- addContent(content);
+ for (Content c: ((ContentBuilder)tagContent).contents) {
+ addContent(c);
}
}
else if (tagContent == HtmlTree.EMPTY || tagContent.isValid()) {
@@ -158,9 +158,9 @@
}
/**
- * This method adds a string content to the htmltree. If the last content member
+ * Adds String content to the HTML tree. If the last content member
* added is a StringContent, append the string to that StringContent or else
- * create a new StringContent and add it to the html tree.
+ * create a new StringContent and add it to the HTML tree.
*
* @param stringContent string content that needs to be added
*/
@@ -177,6 +177,10 @@
addContent(new StringContent(stringContent));
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public int charCount() {
int n = 0;
for (Content c : content)
@@ -185,7 +189,7 @@
}
/**
- * Given a string, escape all special html characters and
+ * Given a string, escape all special HTML characters and
* return the result.
*
* @param s The string to check.
@@ -717,24 +721,13 @@
/**
* Generates a SCRIPT tag with the type and src attributes.
*
- * @param type type of link
* @param src the path for the script
* @return an HtmlTree object for the SCRIPT tag
*/
public static HtmlTree SCRIPT(String src) {
- HtmlTree htmltree = HtmlTree.SCRIPT();
- htmltree.addAttr(HtmlAttr.SRC, nullCheck(src));
- return htmltree;
- }
-
- /**
- * Generates a SCRIPT tag with the type attribute.
- *
- * @return an HtmlTree object for the SCRIPT tag
- */
- public static HtmlTree SCRIPT() {
HtmlTree htmltree = new HtmlTree(HtmlTag.SCRIPT);
htmltree.addAttr(HtmlAttr.TYPE, "text/javascript");
+ htmltree.addAttr(HtmlAttr.SRC, nullCheck(src));
return htmltree;
}
@@ -912,8 +905,8 @@
* @param body content for the tag
* @return an HtmlTree object for the TITLE tag
*/
- public static HtmlTree TITLE(Content body) {
- HtmlTree htmltree = new HtmlTree(HtmlTag.TITLE, nullCheck(body));
+ public static HtmlTree TITLE(String body) {
+ HtmlTree htmltree = new HtmlTree(HtmlTag.TITLE, new StringContent(body));
return htmltree;
}
@@ -949,6 +942,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isEmpty() {
return (!hasContent() && !hasAttrs());
}
@@ -988,6 +982,7 @@
*
* @return true if the HTML tree is valid
*/
+ @Override
public boolean isValid() {
switch (htmlTag) {
case A :
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java Thu Nov 16 15:06:17 2017 -0800
@@ -29,15 +29,13 @@
import jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration;
import jdk.javadoc.internal.doclets.toolkit.Content;
-import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
-import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
/**
- * Class for the Html format code generation.
+ * Class for the HTML format code generation.
* Initializes PrintWriter with FileWriter, to enable print
* related methods to generate the code to the named File through FileWriter.
*
@@ -51,21 +49,8 @@
*/
public class HtmlWriter {
- /**
- * The window title of this file.
- */
- protected String winTitle;
-
- /**
- * The configuration.
- */
- protected HtmlConfiguration configuration;
-
private final DocFile docFile;
- protected Content script;
-
-
/**
* Constructor.
*
@@ -74,13 +59,7 @@
* or null if none to be created
*/
public HtmlWriter(HtmlConfiguration configuration, DocPath path) {
- this.configuration = configuration;
docFile = DocFile.createFileForOutput(configuration, path);
-
- // The following should be converted to shared Content objects
- // and moved to Contents, but that will require additional
- // changes at the use sites.
- Resources resources = configuration.getResources();
}
public void write(Content c) throws DocFileIOException {
@@ -90,171 +69,4 @@
throw new DocFileIOException(docFile, DocFileIOException.Mode.WRITE, e);
}
}
-
- /**
- * Returns an HtmlTree for the SCRIPT tag.
- *
- * @return an HtmlTree for the SCRIPT tag
- */
- protected HtmlTree getWinTitleScript(){
- HtmlTree scriptTree = HtmlTree.SCRIPT();
- if(winTitle != null && winTitle.length() > 0) {
- String scriptCode = "<!--\n" +
- " try {\n" +
- " if (location.href.indexOf('is-external=true') == -1) {\n" +
- " parent.document.title=\"" + escapeJavaScriptChars(winTitle) + "\";\n" +
- " }\n" +
- " }\n" +
- " catch(err) {\n" +
- " }\n" +
- "//-->\n";
- RawHtml scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
- scriptTree.addContent(scriptContent);
- }
- return scriptTree;
- }
-
- /**
- * Returns a String with escaped special JavaScript characters.
- *
- * @param s String that needs to be escaped
- * @return a valid escaped JavaScript string
- */
- private static String escapeJavaScriptChars(String s) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < s.length(); i++) {
- char ch = s.charAt(i);
- switch (ch) {
- case '\b':
- sb.append("\\b");
- break;
- case '\t':
- sb.append("\\t");
- break;
- case '\n':
- sb.append("\\n");
- break;
- case '\f':
- sb.append("\\f");
- break;
- case '\r':
- sb.append("\\r");
- break;
- case '"':
- sb.append("\\\"");
- break;
- case '\'':
- sb.append("\\\'");
- break;
- case '\\':
- sb.append("\\\\");
- break;
- default:
- if (ch < 32 || ch >= 127) {
- sb.append(String.format("\\u%04X", (int)ch));
- } else {
- sb.append(ch);
- }
- break;
- }
- }
- return sb.toString();
- }
-
- /**
- * Returns a content tree for the SCRIPT tag for the main page(index.html).
- *
- * @return a content for the SCRIPT tag
- */
- protected Content getFramesJavaScript() {
- HtmlTree scriptTree = HtmlTree.SCRIPT();
- String scriptCode = "\n" +
- " tmpTargetPage = \"\" + window.location.search;\n" +
- " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" +
- " tmpTargetPage = tmpTargetPage.substring(1);\n" +
- " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" +
- " tmpTargetPage = \"undefined\";\n" +
- " targetPage = tmpTargetPage;\n" +
- " function validURL(url) {\n" +
- " try {\n" +
- " url = decodeURIComponent(url);\n" +
- " }\n" +
- " catch (error) {\n" +
- " return false;\n" +
- " }\n" +
- " var pos = url.indexOf(\".html\");\n" +
- " if (pos == -1 || pos != url.length - 5)\n" +
- " return false;\n" +
- " var allowNumber = false;\n" +
- " var allowSep = false;\n" +
- " var seenDot = false;\n" +
- " for (var i = 0; i < url.length - 5; i++) {\n" +
- " var ch = url.charAt(i);\n" +
- " if ('a' <= ch && ch <= 'z' ||\n" +
- " 'A' <= ch && ch <= 'Z' ||\n" +
- " ch == '$' ||\n" +
- " ch == '_' ||\n" +
- " ch.charCodeAt(0) > 127) {\n" +
- " allowNumber = true;\n" +
- " allowSep = true;\n" +
- " } else if ('0' <= ch && ch <= '9'\n" +
- " || ch == '-') {\n" +
- " if (!allowNumber)\n" +
- " return false;\n" +
- " } else if (ch == '/' || ch == '.') {\n" +
- " if (!allowSep)\n" +
- " return false;\n" +
- " allowNumber = false;\n" +
- " allowSep = false;\n" +
- " if (ch == '.')\n" +
- " seenDot = true;\n" +
- " if (ch == '/' && seenDot)\n" +
- " return false;\n" +
- " } else {\n" +
- " return false;\n" +
- " }\n" +
- " }\n" +
- " return true;\n" +
- " }\n" +
- " function loadFrames() {\n" +
- " if (targetPage != \"\" && targetPage != \"undefined\")\n" +
- " top.classFrame.location = top.targetPage;\n" +
- " }\n";
- RawHtml scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
- scriptTree.addContent(scriptContent);
- return scriptTree;
- }
-
- /**
- * Returns an HtmlTree for the BODY tag.
- *
- * @param includeScript set true if printing windowtitle script
- * @param title title for the window
- * @return an HtmlTree for the BODY tag
- */
- public HtmlTree getBody(boolean includeScript, String title) {
- HtmlTree body = new HtmlTree(HtmlTag.BODY);
- // Set window title string which is later printed
- this.winTitle = title;
- // Don't print windowtitle script for overview-frame, allclasses-frame
- // and package-frame
- if (includeScript) {
- this.script = getWinTitleScript();
- body.addContent(script);
- Content noScript = HtmlTree.NOSCRIPT(
- HtmlTree.DIV(configuration.getContent("doclet.No_Script_Message")));
- body.addContent(noScript);
- }
- return body;
- }
-
- /**
- * Returns an HtmlTree for the TITLE tag.
- *
- * @return an HtmlTree for the TITLE tag
- */
- public HtmlTree getTitle() {
- HtmlTree title = HtmlTree.TITLE(new StringContent(winTitle));
- return title;
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Script.java Thu Nov 16 15:06:17 2017 -0800
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2003, 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.doclets.formats.html.markup;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
+
+/**
+ * A builder for HTML script elements.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class Script {
+ private final StringBuilder sb;
+
+ /**
+ * Creates an empty script.
+ */
+ public Script() {
+ sb = new StringBuilder();
+ }
+
+ /**
+ * Creates a new script containing the specified code.
+ *
+ * @param code the code
+ */
+ public Script(String code) {
+ this();
+ append(code);
+ }
+
+ /**
+ * Appends the given code to the content.
+ *
+ * @param code the code
+ * @return this object
+ */
+ public Script append(CharSequence code) {
+ sb.append(code);
+ return this;
+ }
+
+ /**
+ * Appends the given text as a string constant to the content.
+ * Characters within the string will be escaped as needed.
+ *
+ * @param text the text
+ * @return this object
+ */
+ public Script appendStringLiteral(CharSequence text) {
+ sb.append(stringLiteral(text, '"'));
+ return this;
+ }
+
+ /**
+ * Appends the given text as a string constant to the content.
+ * Characters within the string will be escaped as needed.
+ *
+ * @param text the text
+ * @param quoteChar the quote character to use
+ * @return this object
+ */
+ // The ability to specify the quote character is for backwards
+ // compatibility. Ideally, we should simplify the code so that
+ // the same quote character is always used.
+ public Script appendStringLiteral(CharSequence text, char quoteChar) {
+ sb.append(stringLiteral(text, quoteChar));
+ return this;
+ }
+
+ public Content asContent() {
+ ScriptContent scriptContent = new ScriptContent(sb);
+ HtmlTree tree = new HtmlTree(HtmlTag.SCRIPT) {
+ @Override
+ public void addContent(CharSequence s) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void addContent(Content c) {
+ if (c != scriptContent) {
+ throw new IllegalArgumentException();
+ }
+ super.addContent(scriptContent);
+ }
+ };
+ tree.addAttr(HtmlAttr.TYPE, "text/javascript");
+ tree.addContent(scriptContent);
+ return tree;
+ }
+
+ /**
+ * Returns a String with escaped special JavaScript characters.
+ *
+ * @param s String that needs to be escaped
+ * @return a valid escaped JavaScript string
+ */
+ public static String stringLiteral(CharSequence s) {
+ return stringLiteral(s, '"');
+ }
+
+ /**
+ * Returns a String with escaped special JavaScript characters.
+ *
+ * @param s String that needs to be escaped
+ * @param quoteChar the quote character to use for the literal
+ * @return a valid escaped JavaScript string
+ */
+ // The ability to specify the quote character is for backwards
+ // compatibility. Ideally, we should simplify the code so that
+ // the same quote character is always used.
+ public static String stringLiteral(CharSequence s, char quoteChar) {
+ if (quoteChar != '"' && quoteChar != '\'') {
+ throw new IllegalArgumentException();
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(quoteChar);
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ switch (ch) {
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '"':
+ sb.append("\\\"");
+ break;
+ case '\'':
+ sb.append("\\\'");
+ break;
+ case '\\':
+ sb.append("\\\\");
+ break;
+ default:
+ if (ch < 32 || ch >= 127) {
+ sb.append(String.format("\\u%04X", (int)ch));
+ } else {
+ sb.append(ch);
+ }
+ break;
+ }
+ }
+ sb.append(quoteChar);
+ return sb.toString();
+ }
+
+ private static class ScriptContent extends Content {
+ private final StringBuilder sb;
+
+ ScriptContent(StringBuilder sb) {
+ this.sb = sb;
+ }
+
+ @Override
+ public void addContent(Content content) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addContent(CharSequence code) {
+ sb.append(code);
+ }
+
+ @Override
+ public boolean write(Writer writer, boolean atNewline) throws IOException {
+ String s = sb.toString();
+ writer.write(s.replace("\n", DocletConstants.NL));
+ return s.endsWith("\n");
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+ }
+}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Table.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Table.java Thu Nov 16 15:06:17 2017 -0800
@@ -570,7 +570,12 @@
}
private void appendTabInfo(StringBuilder sb, int value, String id, String name) {
- sb.append(value).append(":[\"").append(id).append("\",").append("\"").append(name).append("\"]");
+ sb.append(value)
+ .append(":[")
+ .append(Script.stringLiteral(id))
+ .append(",")
+ .append(Script.stringLiteral(name))
+ .append("]");
}
private void appendStyleInfo(StringBuilder sb, HtmlStyle... styles) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java Thu Nov 16 15:01:45 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java Thu Nov 16 15:06:17 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -76,6 +76,10 @@
/**
* Writes content to a writer.
*
+ * @param writer the writer
+ * @param atNewline whether the writer has just written a newline
+ * @return whether the writer has just written a newline
+ * @throws IOException if an error occurs while writing the output
*/
public abstract boolean write(Writer writer, boolean atNewline) throws IOException ;
@@ -107,6 +111,7 @@
/**
* Checks for null values.
*
+ * @param <T> the type of the item being checked
* @param t reference type to check for null values
* @return the reference type if not null or else throws a null pointer exception
*/
--- a/test/langtools/jdk/javadoc/doclet/testGroupName/TestGroupName.java Thu Nov 16 15:01:45 2017 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testGroupName/TestGroupName.java Thu Nov 16 15:06:17 2017 -0800
@@ -64,10 +64,8 @@
checkExit(Exit.OK);
checkOutput("overview-summary.html", true,
- "<span><a href=\"javascript:showGroups(1);\">abc < & > def</a></span>");
-
- checkOutput("overview-summary.html", false,
- "abc < & > def");
+ "<span><a href=\"javascript:showGroups(1);\">abc < & > def</a></span>",
+ ",\"abc < & > def\"],");
}
@Test
@@ -99,10 +97,8 @@
checkExit(Exit.OK);
checkOutput("overview-summary.html", true,
- "<span><a href=\"javascript:showGroups(1);\">abc < & > def</a></span>");
-
- checkOutput("overview-summary.html", false,
- "abc < & > def");
+ "<span><a href=\"javascript:showGroups(1);\">abc < & > def</a></span>",
+ ",\"abc < & > def\"],");
}
}
--- a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java Thu Nov 16 15:01:45 2017 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java Thu Nov 16 15:06:17 2017 -0800
@@ -1100,7 +1100,7 @@
+ " </span></span><span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:showGroups(4);\">"
+ "Other Modules</a></span><span class=\"tabEnd\"> </span></span></caption>",
"var groups = {\"i0\":1,\"i1\":2,\"i2\":2,\"i3\":4};\n"
- + "var tabs = {65535:[\"t0\",\"All Modules\"],1:[\"t1\",\"Module Group A\"],2:[\"t2\",\"Module Group B & C\"],4:[\"t4\",\"Other Modules\"]};\n"
+ + "var tabs = {65535:[\"t0\",\"All Modules\"],1:[\"t1\",\"Module Group A\"],2:[\"t2\",\"Module Group B & C\"],4:[\"t4\",\"Other Modules\"]};\n"
+ "var altColor = \"altColor\";\n"
+ "var rowColor = \"rowColor\";\n"
+ "var tableTab = \"tableTab\";\n"