1 /* |
|
2 * Copyright (c) 1997, 2019, 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. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package jdk.javadoc.internal.doclets.formats.html; |
|
27 |
|
28 import jdk.javadoc.internal.doclets.formats.html.markup.Head; |
|
29 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr; |
|
30 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument; |
|
31 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; |
|
32 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; |
|
33 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; |
|
34 import jdk.javadoc.internal.doclets.formats.html.markup.Script; |
|
35 import jdk.javadoc.internal.doclets.toolkit.Content; |
|
36 import jdk.javadoc.internal.doclets.toolkit.util.DocFile; |
|
37 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; |
|
38 import jdk.javadoc.internal.doclets.toolkit.util.DocPath; |
|
39 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; |
|
40 |
|
41 |
|
42 /** |
|
43 * Generate the documentation in the Html "frame" format in the browser. The |
|
44 * generated documentation will have two or three frames depending upon the |
|
45 * number of packages on the command line. In general there will be three frames |
|
46 * in the output, a left-hand top frame will have a list of all packages with |
|
47 * links to target left-hand bottom frame. The left-hand bottom frame will have |
|
48 * the particular package contents or the all-classes list, where as the single |
|
49 * right-hand frame will have overview or package summary or class file. Also |
|
50 * take care of browsers which do not support Html frames. |
|
51 * |
|
52 * <p><b>This is NOT part of any supported API. |
|
53 * If you write code that depends on this, you do so at your own risk. |
|
54 * This code and its internal interfaces are subject to change or |
|
55 * deletion without notice.</b> |
|
56 * |
|
57 * @author Atul M Dambalkar |
|
58 */ |
|
59 public class FrameOutputWriter extends HtmlDocletWriter { |
|
60 |
|
61 /** |
|
62 * Number of packages specified on the command line. |
|
63 */ |
|
64 int noOfPackages; |
|
65 |
|
66 /** |
|
67 * Constructor to construct FrameOutputWriter object. |
|
68 * |
|
69 * @param configuration for this run |
|
70 * @param filename File to be generated. |
|
71 */ |
|
72 public FrameOutputWriter(HtmlConfiguration configuration, DocPath filename) { |
|
73 super(configuration, filename); |
|
74 noOfPackages = configuration.packages.size(); |
|
75 } |
|
76 |
|
77 /** |
|
78 * Construct FrameOutputWriter object and then use it to generate the Html |
|
79 * file which will have the description of all the frames in the |
|
80 * documentation. The name of the generated file is "index.html" which is |
|
81 * the default first file for Html documents. |
|
82 * @param configuration the configuration for this doclet |
|
83 * @throws DocFileIOException if there is a problem generating the frame file |
|
84 */ |
|
85 public static void generate(HtmlConfiguration configuration) throws DocFileIOException { |
|
86 FrameOutputWriter framegen = new FrameOutputWriter(configuration, DocPaths.INDEX); |
|
87 framegen.generateFrameFile(); |
|
88 } |
|
89 |
|
90 /** |
|
91 * Generate the constants in the "index.html" file. Print the frame details |
|
92 * as well as warning if browser is not supporting the Html frames. |
|
93 * @throws DocFileIOException if there is a problem generating the frame file |
|
94 */ |
|
95 protected void generateFrameFile() throws DocFileIOException { |
|
96 Content frame = getFrameDetails(); |
|
97 HtmlTree body = new HtmlTree(HtmlTag.BODY); |
|
98 body.put(HtmlAttr.CLASS, "frames"); |
|
99 body.put(HtmlAttr.ONLOAD, "loadFrames()"); |
|
100 String topFilePath = configuration.topFile.getPath(); |
|
101 Script script = new Script( |
|
102 "\nif (targetPage == \"\" || targetPage == \"undefined\")\n" + |
|
103 " window.location.replace(") |
|
104 .appendStringLiteral(topFilePath, '\'') |
|
105 .append(");\n"); |
|
106 body.add(script.asContent()); |
|
107 Content noScript = HtmlTree.NOSCRIPT(contents.noScriptMessage); |
|
108 body.add(noScript); |
|
109 HtmlTree main = HtmlTree.MAIN(frame); |
|
110 body.add(main); |
|
111 if (configuration.windowtitle.length() > 0) { |
|
112 printFramesDocument(configuration.windowtitle, body); |
|
113 } else { |
|
114 printFramesDocument(resources.getText("doclet.Generated_Docs_Untitled"), body); |
|
115 } |
|
116 } |
|
117 |
|
118 /** |
|
119 * Print the frames version of the Html file header. |
|
120 * Called only when generating an HTML frames file. |
|
121 * |
|
122 * @param title Title of this HTML document |
|
123 * @param body the body content tree to be added to the HTML document |
|
124 * @throws DocFileIOException if there is an error writing the frames document |
|
125 */ |
|
126 private void printFramesDocument(String title, HtmlTree body) throws DocFileIOException { |
|
127 Content htmlComment = contents.newPage; |
|
128 Head head = new Head(path, configuration.docletVersion) |
|
129 .setTimestamp(!configuration.notimestamp) |
|
130 .setTitle(title) |
|
131 .setDescription("frames") |
|
132 .setGenerator(getGenerator(getClass())) |
|
133 .setCharset(configuration.charset) |
|
134 .setStylesheets(configuration.getMainStylesheet(), configuration.getAdditionalStylesheets()) |
|
135 .addDefaultScript(false) |
|
136 .addScript(getFramesScript()); |
|
137 |
|
138 Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), head.toContent(), body); |
|
139 HtmlDocument htmlDocument = new HtmlDocument(htmlComment, htmlTree); |
|
140 htmlDocument.write(DocFile.createFileForOutput(configuration, path)); |
|
141 } |
|
142 |
|
143 /** |
|
144 * Get the frame sizes and their contents. |
|
145 * |
|
146 * @return a content tree for the frame details |
|
147 */ |
|
148 protected Content getFrameDetails() { |
|
149 HtmlTree leftContainerDiv = new HtmlTree(HtmlTag.DIV); |
|
150 HtmlTree rightContainerDiv = new HtmlTree(HtmlTag.DIV); |
|
151 leftContainerDiv.setStyle(HtmlStyle.leftContainer); |
|
152 rightContainerDiv.setStyle(HtmlStyle.rightContainer); |
|
153 if (configuration.showModules && configuration.modules.size() > 1) { |
|
154 addAllModulesFrameTag(leftContainerDiv); |
|
155 } else if (noOfPackages > 1) { |
|
156 addAllPackagesFrameTag(leftContainerDiv); |
|
157 } |
|
158 addAllClassesFrameTag(leftContainerDiv); |
|
159 addClassFrameTag(rightContainerDiv); |
|
160 HtmlTree mainContainer = HtmlTree.DIV(HtmlStyle.mainContainer, leftContainerDiv); |
|
161 mainContainer.add(rightContainerDiv); |
|
162 return mainContainer; |
|
163 } |
|
164 |
|
165 /** |
|
166 * Add the IFRAME tag for the frame that lists all modules. |
|
167 * |
|
168 * @param contentTree to which the information will be added |
|
169 */ |
|
170 private void addAllModulesFrameTag(Content contentTree) { |
|
171 HtmlTree frame = HtmlTree.IFRAME(DocPaths.MODULE_OVERVIEW_FRAME.getPath(), |
|
172 "packageListFrame", resources.getText("doclet.All_Modules")); |
|
173 HtmlTree leftTop = HtmlTree.DIV(HtmlStyle.leftTop, frame); |
|
174 contentTree.add(leftTop); |
|
175 } |
|
176 |
|
177 /** |
|
178 * Add the IFRAME tag for the frame that lists all packages. |
|
179 * |
|
180 * @param contentTree the content tree to which the information will be added |
|
181 */ |
|
182 private void addAllPackagesFrameTag(Content contentTree) { |
|
183 HtmlTree frame = HtmlTree.IFRAME(DocPaths.OVERVIEW_FRAME.getPath(), |
|
184 "packageListFrame", resources.getText("doclet.All_Packages")); |
|
185 HtmlTree leftTop = HtmlTree.DIV(HtmlStyle.leftTop, frame); |
|
186 contentTree.add(leftTop); |
|
187 } |
|
188 |
|
189 /** |
|
190 * Add the IFRAME tag for the frame that lists all classes. |
|
191 * |
|
192 * @param contentTree the content tree to which the information will be added |
|
193 */ |
|
194 private void addAllClassesFrameTag(Content contentTree) { |
|
195 HtmlTree frame = HtmlTree.IFRAME(DocPaths.ALLCLASSES_FRAME.getPath(), |
|
196 "packageFrame", resources.getText("doclet.All_classes_and_interfaces")); |
|
197 HtmlTree leftBottom = HtmlTree.DIV(HtmlStyle.leftBottom, frame); |
|
198 contentTree.add(leftBottom); |
|
199 } |
|
200 |
|
201 /** |
|
202 * Add the IFRAME tag for the frame that describes the class in detail. |
|
203 * |
|
204 * @param contentTree the content tree to which the information will be added |
|
205 */ |
|
206 private void addClassFrameTag(Content contentTree) { |
|
207 HtmlTree frame = HtmlTree.IFRAME(configuration.topFile.getPath(), "classFrame", |
|
208 resources.getText("doclet.Package_class_and_interface_descriptions")); |
|
209 frame.setStyle(HtmlStyle.rightIframe); |
|
210 contentTree.add(frame); |
|
211 } |
|
212 |
|
213 /** |
|
214 * Returns a content tree for the SCRIPT tag for the main page(index.html). |
|
215 * |
|
216 * @return a content for the SCRIPT tag |
|
217 */ |
|
218 protected Script getFramesScript() { |
|
219 return new Script("\n" + |
|
220 " tmpTargetPage = \"\" + window.location.search;\n" + |
|
221 " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" + |
|
222 " tmpTargetPage = tmpTargetPage.substring(1);\n" + |
|
223 " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" + |
|
224 " tmpTargetPage = \"undefined\";\n" + |
|
225 " targetPage = tmpTargetPage;\n" + |
|
226 " function validURL(url) {\n" + |
|
227 " try {\n" + |
|
228 " url = decodeURIComponent(url);\n" + |
|
229 " }\n" + |
|
230 " catch (error) {\n" + |
|
231 " return false;\n" + |
|
232 " }\n" + |
|
233 " var pos = url.indexOf(\".html\");\n" + |
|
234 " if (pos == -1 || pos != url.length - 5)\n" + |
|
235 " return false;\n" + |
|
236 " var allowNumber = false;\n" + |
|
237 " var allowSep = false;\n" + |
|
238 " var seenDot = false;\n" + |
|
239 " for (var i = 0; i < url.length - 5; i++) {\n" + |
|
240 " var ch = url.charAt(i);\n" + |
|
241 " if ('a' <= ch && ch <= 'z' ||\n" + |
|
242 " 'A' <= ch && ch <= 'Z' ||\n" + |
|
243 " ch == '$' ||\n" + |
|
244 " ch == '_' ||\n" + |
|
245 " ch.charCodeAt(0) > 127) {\n" + |
|
246 " allowNumber = true;\n" + |
|
247 " allowSep = true;\n" + |
|
248 " } else if ('0' <= ch && ch <= '9'\n" + |
|
249 " || ch == '-') {\n" + |
|
250 " if (!allowNumber)\n" + |
|
251 " return false;\n" + |
|
252 " } else if (ch == '/' || ch == '.') {\n" + |
|
253 " if (!allowSep)\n" + |
|
254 " return false;\n" + |
|
255 " allowNumber = false;\n" + |
|
256 " allowSep = false;\n" + |
|
257 " if (ch == '.')\n" + |
|
258 " seenDot = true;\n" + |
|
259 " if (ch == '/' && seenDot)\n" + |
|
260 " return false;\n" + |
|
261 " } else {\n" + |
|
262 " return false;\n" + |
|
263 " }\n" + |
|
264 " }\n" + |
|
265 " return true;\n" + |
|
266 " }\n" + |
|
267 " function loadFrames() {\n" + |
|
268 " if (targetPage != \"\" && targetPage != \"undefined\")\n" + |
|
269 " top.classFrame.location = top.targetPage;\n" + |
|
270 " }\n"); |
|
271 } |
|
272 } |
|