1 /******************************************************************************* 2 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors 3 * This program and the accompanying materials are made available under 4 * the terms of the Eclipse Public License 2.0 which is available at 5 * http://www.eclipse.org/legal/epl-2.0 6 * 7 * SPDX-License-Identifier: EPL-2.0 8 * 9 * Contributors: 10 * Marc R. Hoffmann - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.report.internal.html; 14 15 import java.io.IOException; 16 import java.io.OutputStream; 17 18 import org.jacoco.report.internal.ReportOutputFolder; 19 import org.jacoco.report.internal.xml.XMLElement; 20 21 /** 22 * A {@link XMLElement} with utility methods to create XHTML documents. It 23 * provides methods of HTML tags to avoid magic strings in the generators. 24 */ 25 public class HTMLElement extends XMLElement { 26 27 private static final String PUBID = "-//W3C//DTD XHTML 1.0 Strict//EN"; 28 29 private static final String SYSTEM = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"; 30 31 /** 32 * Creates a <code>html</code> root element of a XHTML document. 33 * 34 * @param encoding 35 * character encoding used for output 36 * @param output 37 * output stream will be closed if the root element is closed 38 * @throws IOException 39 * in case of problems with the underlying output 40 */ HTMLElement(final OutputStream output, final String encoding)41 public HTMLElement(final OutputStream output, final String encoding) 42 throws IOException { 43 super("html", PUBID, SYSTEM, false, encoding, output); 44 attr("xmlns", "http://www.w3.org/1999/xhtml"); 45 } 46 HTMLElement(final String name, final HTMLElement parent)47 private HTMLElement(final String name, final HTMLElement parent) 48 throws IOException { 49 super(name, parent); 50 } 51 52 @Override element(final String name)53 public HTMLElement element(final String name) throws IOException { 54 return new HTMLElement(name, this); 55 } 56 classattr(final String classattr)57 private void classattr(final String classattr) throws IOException { 58 attr("class", classattr); 59 } 60 61 /** 62 * Creates a 'head' element. 63 * 64 * @return 'head' element 65 * @throws IOException 66 * in case of problems with the underlying output 67 */ head()68 public HTMLElement head() throws IOException { 69 return element("head"); 70 } 71 72 /** 73 * Creates a 'body' element. 74 * 75 * @return 'body' element 76 * @throws IOException 77 * in case of problems with the underlying output 78 */ body()79 public HTMLElement body() throws IOException { 80 return element("body"); 81 } 82 83 /** 84 * Creates a 'meta' element. 85 * 86 * @param httpequivattr 87 * value of the http-equiv attribute 88 * @param contentattr 89 * value for the content attribute 90 * @return 'meta' element 91 * @throws IOException 92 * in case of problems with the underlying output 93 */ meta(final String httpequivattr, final String contentattr)94 public HTMLElement meta(final String httpequivattr, 95 final String contentattr) throws IOException { 96 final HTMLElement meta = element("meta"); 97 meta.attr("http-equiv", httpequivattr); 98 meta.attr("content", contentattr); 99 return meta; 100 } 101 102 /** 103 * Creates a 'link' element. 104 * 105 * @param relattr 106 * value of the rel attribute 107 * @param hrefattr 108 * value for the href attribute 109 * @param typeattr 110 * value for the type attribute 111 * @return 'link' element 112 * @throws IOException 113 * in case of problems with the underlying output 114 */ link(final String relattr, final String hrefattr, final String typeattr)115 public HTMLElement link(final String relattr, final String hrefattr, 116 final String typeattr) throws IOException { 117 final HTMLElement link = element("link"); 118 link.attr("rel", relattr); 119 link.attr("href", hrefattr); 120 link.attr("type", typeattr); 121 return link; 122 } 123 124 /** 125 * Creates a 'title' element. 126 * 127 * @return 'title' element 128 * @throws IOException 129 * in case of problems with the underlying output 130 */ title()131 public HTMLElement title() throws IOException { 132 return element("title"); 133 } 134 135 /** 136 * Creates a 'h1' element. 137 * 138 * @return 'h1' element 139 * @throws IOException 140 * in case of problems with the underlying output 141 */ h1()142 public HTMLElement h1() throws IOException { 143 return element("h1"); 144 } 145 146 /** 147 * Creates a 'p' element. 148 * 149 * @return 'p' element 150 * @throws IOException 151 * in case of problems with the underlying output 152 */ p()153 public HTMLElement p() throws IOException { 154 return element("p"); 155 } 156 157 /** 158 * Creates a 'span' element. 159 * 160 * @return 'span' element 161 * @throws IOException 162 * in case of problems with the underlying output 163 */ span()164 public HTMLElement span() throws IOException { 165 return element("span"); 166 } 167 168 /** 169 * Creates a 'span' element. 170 * 171 * @param classattr 172 * value of the class attribute 173 * @return 'span' element 174 * @throws IOException 175 * in case of problems with the underlying output 176 */ span(final String classattr)177 public HTMLElement span(final String classattr) throws IOException { 178 final HTMLElement span = span(); 179 span.classattr(classattr); 180 return span; 181 } 182 183 /** 184 * Creates a 'span' element. 185 * 186 * @param classattr 187 * value of the class attribute 188 * @param idattr 189 * value of the id attribute 190 * @return 'span' element 191 * @throws IOException 192 * in case of problems with the underlying output 193 */ span(final String classattr, final String idattr)194 public HTMLElement span(final String classattr, final String idattr) 195 throws IOException { 196 final HTMLElement span = span(classattr); 197 span.attr("id", idattr); 198 return span; 199 } 200 201 /** 202 * Creates a 'div' element. 203 * 204 * @param classattr 205 * value of the class attribute 206 * @return 'div' element 207 * @throws IOException 208 * in case of problems with the underlying output 209 */ div(final String classattr)210 public HTMLElement div(final String classattr) throws IOException { 211 final HTMLElement div = element("div"); 212 div.classattr(classattr); 213 return div; 214 } 215 216 /** 217 * Creates a 'code' element. 218 * 219 * @return 'code' element 220 * @throws IOException 221 * in case of problems with the underlying output 222 */ code()223 public HTMLElement code() throws IOException { 224 return element("code"); 225 } 226 227 /** 228 * Creates a 'pre' element. 229 * 230 * @param classattr 231 * value of the class attribute 232 * @return 'pre' element 233 * @throws IOException 234 * in case of problems with the underlying output 235 */ pre(final String classattr)236 public HTMLElement pre(final String classattr) throws IOException { 237 final HTMLElement pre = element("pre"); 238 pre.classattr(classattr); 239 return pre; 240 } 241 242 /** 243 * Creates a 'a' element. 244 * 245 * @param hrefattr 246 * value of the href attribute 247 * @return 'a' element 248 * @throws IOException 249 * in case of problems with the underlying output 250 */ a(final String hrefattr)251 public HTMLElement a(final String hrefattr) throws IOException { 252 final HTMLElement a = element("a"); 253 a.attr("href", hrefattr); 254 return a; 255 } 256 257 /** 258 * Creates a 'a' element. 259 * 260 * @param hrefattr 261 * value of the href attribute 262 * @param classattr 263 * value of the class attribute 264 * @return 'a' element 265 * @throws IOException 266 * in case of problems with the underlying output 267 */ a(final String hrefattr, final String classattr)268 public HTMLElement a(final String hrefattr, final String classattr) 269 throws IOException { 270 final HTMLElement a = a(hrefattr); 271 a.classattr(classattr); 272 return a; 273 } 274 275 /** 276 * Creates a link to the given {@link ILinkable}. 277 * 278 * @param linkable 279 * object to link to 280 * @param base 281 * base folder where the link should be placed 282 * @return 'a' element or 'span' element, if the link target does not exist 283 * @throws IOException 284 * in case of problems with the underlying output 285 */ a(final ILinkable linkable, final ReportOutputFolder base)286 public HTMLElement a(final ILinkable linkable, 287 final ReportOutputFolder base) throws IOException { 288 final HTMLElement a; 289 final String link = linkable.getLink(base); 290 if (link == null) { 291 a = span(linkable.getLinkStyle()); 292 } else { 293 a = a(link, linkable.getLinkStyle()); 294 } 295 a.text(linkable.getLinkLabel()); 296 return a; 297 } 298 299 /** 300 * Creates a 'table' element. 301 * 302 * @param classattr 303 * value of the class attribute 304 * @return 'table' element 305 * @throws IOException 306 * in case of problems with the underlying output 307 */ table(final String classattr)308 public HTMLElement table(final String classattr) throws IOException { 309 final HTMLElement table = element("table"); 310 table.classattr(classattr); 311 table.attr("cellspacing", "0"); 312 return table; 313 } 314 315 /** 316 * Creates a 'thead' element. 317 * 318 * @return 'thead' element 319 * @throws IOException 320 * in case of problems with the underlying output 321 */ thead()322 public HTMLElement thead() throws IOException { 323 return element("thead"); 324 } 325 326 /** 327 * Creates a 'tfoot' element. 328 * 329 * @return 'tfoot' element 330 * @throws IOException 331 * in case of problems with the underlying output 332 */ tfoot()333 public HTMLElement tfoot() throws IOException { 334 return element("tfoot"); 335 } 336 337 /** 338 * Creates a 'tbody' element. 339 * 340 * @return 'tbody' element 341 * @throws IOException 342 * in case of problems with the underlying output 343 */ tbody()344 public HTMLElement tbody() throws IOException { 345 return element("tbody"); 346 } 347 348 /** 349 * Creates a 'tr' element. 350 * 351 * @return 'tr' element 352 * @throws IOException 353 * in case of problems with the underlying output 354 */ tr()355 public HTMLElement tr() throws IOException { 356 return element("tr"); 357 } 358 359 /** 360 * Creates a 'td' element. 361 * 362 * @return 'td' element 363 * @throws IOException 364 * in case of problems with the underlying output 365 */ td()366 public HTMLElement td() throws IOException { 367 return element("td"); 368 } 369 370 /** 371 * Creates a 'td' element. 372 * 373 * @param classattr 374 * value of the class attribute 375 * @return 'td' element 376 * @throws IOException 377 * in case of problems with the underlying output 378 */ td(final String classattr)379 public HTMLElement td(final String classattr) throws IOException { 380 final HTMLElement td = td(); 381 td.classattr(classattr); 382 return td; 383 } 384 385 /** 386 * Creates a 'img' element. 387 * 388 * @param srcattr 389 * value of the src attribute 390 * @param widthattr 391 * value of the width attribute 392 * @param heightattr 393 * value of the height attribute 394 * @param titleattr 395 * value of the title and alt attribute 396 * @throws IOException 397 * in case of problems with the underlying output 398 */ img(final String srcattr, final int widthattr, final int heightattr, final String titleattr)399 public void img(final String srcattr, final int widthattr, 400 final int heightattr, final String titleattr) throws IOException { 401 final HTMLElement img = element("img"); 402 img.attr("src", srcattr); 403 img.attr("width", widthattr); 404 img.attr("height", heightattr); 405 img.attr("title", titleattr); 406 img.attr("alt", titleattr); 407 img.close(); 408 } 409 410 /** 411 * Creates a JavaScript 'script' element. 412 * 413 * @param srcattr 414 * value of the src attribute 415 * @throws IOException 416 * in case of problems with the underlying output 417 */ script(final String srcattr)418 public void script(final String srcattr) throws IOException { 419 final HTMLElement script = element("script"); 420 script.attr("type", "text/javascript"); 421 script.attr("src", srcattr); 422 // Enforce open and closing tag otherwise it won't work in browsers: 423 script.text(""); 424 script.close(); 425 } 426 427 } 428