001package ball.xml;
002/*-
003 * ##########################################################################
004 * Utilities
005 * $Id: HTMLTemplates.java 8472 2021-08-22 16:52:50Z ball $
006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/ball-util/trunk/src/main/java/ball/xml/HTMLTemplates.java $
007 * %%
008 * Copyright (C) 2008 - 2021 Allen D. Ball
009 * %%
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 *      http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 * ##########################################################################
022 */
023import java.net.URI;
024import java.util.stream.Stream;
025import org.w3c.dom.Node;
026
027/**
028 * Common HTML templates.
029 *
030 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
031 * @version $Revision: 8472 $
032 */
033public interface HTMLTemplates extends XMLServices {
034
035    /**
036     * {@code <a href="}{@link URI#toASCIIString() href.toASCIIString()}{@code ">}{@link URI#toString() href.toString()}{@code </a>}
037     *
038     * @param   href            {@link URI}
039     *
040     * @return  {@link org.w3c.dom.Element}
041     */
042    default FluentNode a(URI href) { return a(href, (String) null); }
043
044    /**
045     * {@code <a href="}{@link URI#toASCIIString() href.toASCIIString()}{@code ">}{@link Node node}{@code </a>}
046     *
047     * @param   href            {@link URI}
048     * @param   node            {@link Node}
049     *
050     * @return  {@link org.w3c.dom.Element}
051     */
052    default FluentNode a(URI href, Node node) {
053        FluentNode a = element("a", node);
054
055        if (href != null) {
056            a.add(attr("href", href.toASCIIString()));
057        }
058
059        return a;
060    }
061
062    /**
063     * {@code <a href="}{@link URI#toASCIIString() href.toASCIIString()}{@code ">}{@link #text(String) text(content)}{@code </a>}
064     *
065     * @param   href            {@link URI}
066     * @param   content         {@link org.w3c.dom.Text} content
067     *
068     * @return  {@code <a/>} {@link org.w3c.dom.Element}
069     */
070    default FluentNode a(URI href, String content) {
071        return a(href, text((content != null) ? content : href.toString()));
072    }
073
074    /**
075     * {@code <b>}{@link Node node}{@code </b>}
076     *
077     * @param   node            {@link Node}
078     *
079     * @return  {@code <b/>} {@link org.w3c.dom.Element}
080     */
081    default FluentNode b(Node node) { return element("b", node); }
082
083    /**
084     * {@code <b>}{@link #text(String) text(content)}{@code </b>}
085     *
086     * @param   content         {@link org.w3c.dom.Text} content
087     *
088     * @return  {@link org.w3c.dom.Element}
089     */
090    default FluentNode b(String content) { return b(text(content)); }
091
092    /**
093     * {@code <code>}{@link String content}{@code </code>}
094     *
095     * @param   content         {@link org.w3c.dom.Text} content
096     *
097     * @return  {@link org.w3c.dom.Element}
098     */
099    default FluentNode code(String content) {
100        return element("code").content(content);
101    }
102
103    /**
104     * {@code <code>}{@link String#valueOf(boolean) String.valueOf(content)}{@code </code>}
105     *
106     * @param   content         {@link org.w3c.dom.Text} content
107     *
108     * @return  {@link org.w3c.dom.Element}
109     */
110    default FluentNode code(boolean content) {
111        return code(String.valueOf(content));
112    }
113
114    /**
115     * {@code <div>}{@link Node nodes...}{@code </div>}
116     *
117     * @param   stream          The {@link Stream} of {@link Node}s to
118     *                          append to the newly created
119     *                          {@link org.w3c.dom.Element}.
120     *
121     * @return  {@link org.w3c.dom.Element}
122     */
123    default FluentNode div(Stream<Node> stream) {
124        return div(stream.toArray(Node[]::new));
125    }
126
127    /**
128     * {@code <div>}{@link Node nodes...}{@code </div>}
129     *
130     * @param   nodes           The {@link Node}s to append to the newly
131     *                          created {@link org.w3c.dom.Element}.
132     *
133     * @return  {@link org.w3c.dom.Element}
134     */
135    default FluentNode div(Node... nodes) { return element("div", nodes); }
136
137    /**
138     * {@code <h1>}{@link Node nodes...}{@code </h1>}
139     *
140     * @param   stream          The {@link Stream} of {@link Node}s to
141     *                          append to the newly created
142     *                          {@link org.w3c.dom.Element}.
143     *
144     * @return  {@link org.w3c.dom.Element}
145     */
146    default FluentNode h1(Stream<Node> stream) {
147        return h1(stream.toArray(Node[]::new));
148    }
149
150    /**
151     * {@code <h1>}{@link Node nodes...}{@code </h1>}
152     *
153     * @param   nodes           The {@link Node}s to append to the newly
154     *                          created {@link org.w3c.dom.Element}.
155     *
156     * @return  {@link org.w3c.dom.Element}
157     */
158    default FluentNode h1(Node... nodes) { return element("h1", nodes); }
159
160    /**
161     * {@code <h1>}{@link #text(String) text(content)}{@code </h1>}
162     *
163     * @param   content         {@link org.w3c.dom.Text} content
164     *
165     * @return  {@link org.w3c.dom.Element}
166     */
167    default FluentNode h1(String content) { return h1(text(content)); }
168
169    /**
170     * {@code <h2>}{@link Node nodes...}{@code </h2>}
171     *
172     * @param   stream          The {@link Stream} of {@link Node}s to
173     *                          append to the newly created
174     *                          {@link org.w3c.dom.Element}.
175     *
176     * @return  {@link org.w3c.dom.Element}
177     */
178    default FluentNode h2(Stream<Node> stream) {
179        return h2(stream.toArray(Node[]::new));
180    }
181
182    /**
183     * {@code <h2>}{@link Node nodes...}{@code </h2>}
184     *
185     * @param   nodes           The {@link Node}s to append to the newly
186     *                          created {@link org.w3c.dom.Element}.
187     *
188     * @return  {@link org.w3c.dom.Element}
189     */
190    default FluentNode h2(Node... nodes) { return element("h2", nodes); }
191
192    /**
193     * {@code <h2>}{@link #text(String) text(content)}{@code </h2>}
194     *
195     * @param   content         {@link org.w3c.dom.Text} content
196     *
197     * @return  {@link org.w3c.dom.Element}
198     */
199    default FluentNode h2(String content) { return h2(text(content)); }
200
201    /**
202     * {@code <h3>}{@link Node nodes...}{@code </h3>}
203     *
204     * @param   stream          The {@link Stream} of {@link Node}s to
205     *                          append to the newly created
206     *                          {@link org.w3c.dom.Element}.
207     *
208     * @return  {@link org.w3c.dom.Element}
209     */
210    default FluentNode h3(Stream<Node> stream) {
211        return h3(stream.toArray(Node[]::new));
212    }
213
214    /**
215     * {@code <h3>}{@link Node nodes...}{@code </h3>}
216     *
217     * @param   nodes           The {@link Node}s to append to the newly
218     *                          created {@link org.w3c.dom.Element}.
219     *
220     * @return  {@link org.w3c.dom.Element}
221     */
222    default FluentNode h3(Node... nodes) { return element("h3", nodes); }
223
224    /**
225     * {@code <h3>}{@link #text(String) text(content)}{@code </h3>}
226     *
227     * @param   content         {@link org.w3c.dom.Text} content
228     *
229     * @return  {@link org.w3c.dom.Element}
230     */
231    default FluentNode h3(String content) { return h3(text(content)); }
232
233    /**
234     * {@code <h4>}{@link Node nodes...}{@code </h4>}
235     *
236     * @param   stream          The {@link Stream} of {@link Node}s to
237     *                          append to the newly created
238     *                          {@link org.w3c.dom.Element}.
239     *
240     * @return  {@link org.w3c.dom.Element}
241     */
242    default FluentNode h4(Stream<Node> stream) {
243        return h4(stream.toArray(Node[]::new));
244    }
245
246    /**
247     * {@code <h4>}{@link Node nodes...}{@code </h4>}
248     *
249     * @param   nodes           The {@link Node}s to append to the newly
250     *                          created {@link org.w3c.dom.Element}.
251     *
252     * @return  {@link org.w3c.dom.Element}
253     */
254    default FluentNode h4(Node... nodes) { return element("h4", nodes); }
255
256    /**
257     * {@code <h4>}{@link #text(String) text(content)}{@code </h4>}
258     *
259     * @param   content         {@link org.w3c.dom.Text} content
260     *
261     * @return  {@link org.w3c.dom.Element}
262     */
263    default FluentNode h4(String content) { return h4(text(content)); }
264
265    /**
266     * {@code <h5>}{@link Node nodes...}{@code </h5>}
267     *
268     * @param   stream          The {@link Stream} of {@link Node}s to
269     *                          append to the newly created
270     *                          {@link org.w3c.dom.Element}.
271     *
272     * @return  {@link org.w3c.dom.Element}
273     */
274    default FluentNode h5(Stream<Node> stream) {
275        return h5(stream.toArray(Node[]::new));
276    }
277
278    /**
279     * {@code <h5>}{@link Node nodes...}{@code </h5>}
280     *
281     * @param   nodes           The {@link Node}s to append to the newly
282     *                          created {@link org.w3c.dom.Element}.
283     *
284     * @return  {@link org.w3c.dom.Element}
285     */
286    default FluentNode h5(Node... nodes) { return element("h5", nodes); }
287
288    /**
289     * {@code <h5>}{@link #text(String) text(content)}{@code </h5>}
290     *
291     * @param   content         {@link org.w3c.dom.Text} content
292     *
293     * @return  {@link org.w3c.dom.Element}
294     */
295    default FluentNode h5(String content) { return h5(text(content)); }
296
297    /**
298     * {@code <h6>}{@link Node nodes...}{@code </h6>}
299     *
300     * @param   stream          The {@link Stream} of {@link Node}s to
301     *                          append to the newly created
302     *                          {@link org.w3c.dom.Element}.
303     *
304     * @return  {@link org.w3c.dom.Element}
305     */
306    default FluentNode h6(Stream<Node> stream) {
307        return h6(stream.toArray(Node[]::new));
308    }
309
310    /**
311     * {@code <h6>}{@link Node nodes...}{@code </h6>}
312     *
313     * @param   nodes           The {@link Node}s to append to the newly
314     *                          created {@link org.w3c.dom.Element}.
315     *
316     * @return  {@link org.w3c.dom.Element}
317     */
318    default FluentNode h6(Node... nodes) { return element("h6", nodes); }
319
320    /**
321     * {@code <h6>}{@link #text(String) text(content)}{@code </h6>}
322     *
323     * @param   content         {@link org.w3c.dom.Text} content
324     *
325     * @return  {@link org.w3c.dom.Element}
326     */
327    default FluentNode h6(String content) { return h6(text(content)); }
328
329    /**
330     * {@code <ol>}{@link Node nodes...}{@code </ol>}
331     *
332     * @param   stream          The {@link Stream} of {@link Node}s to
333     *                          append to the newly created
334     *                          {@link org.w3c.dom.Element}.
335     *
336     * @return  {@link org.w3c.dom.Element}
337     */
338    default FluentNode ol(Stream<Node> stream) {
339        return ol(stream.toArray(Node[]::new));
340    }
341
342    /**
343     * {@code <ol>}{@link Node nodes...}{@code </ol>}
344     *
345     * @param   nodes           The {@link Node}s to append to the newly
346     *                          created {@link org.w3c.dom.Element}.
347     *
348     * @return  {@link org.w3c.dom.Element}
349     */
350    default FluentNode ol(Node... nodes) { return element("ol", nodes); }
351
352    /**
353     * {@code <ul>}{@link Node nodes...}{@code </ul>}
354     *
355     * @param   stream          The {@link Stream} of {@link Node}s to
356     *                          append to the newly created
357     *                          {@link org.w3c.dom.Element}.
358     *
359     * @return  {@link org.w3c.dom.Element}
360     */
361    default FluentNode ul(Stream<Node> stream) {
362        return ul(stream.toArray(Node[]::new));
363    }
364
365    /**
366     * {@code <ul>}{@link Node nodes...}{@code </ul>}
367     *
368     * @param   nodes           The {@link Node}s to append to the newly
369     *                          created {@link org.w3c.dom.Element}.
370     *
371     * @return  {@link org.w3c.dom.Element}
372     */
373    default FluentNode ul(Node... nodes) { return element("ul", nodes); }
374
375    /**
376     * {@code <li>}{@link Node nodes...}{@code </li>}
377     *
378     * @param   stream          The {@link Stream} of {@link Node}s to
379     *                          append to the newly created
380     *                          {@link org.w3c.dom.Element}.
381     *
382     * @return  {@link org.w3c.dom.Element}
383     */
384    default FluentNode li(Stream<Node> stream) {
385        return li(stream.toArray(Node[]::new));
386    }
387
388    /**
389     * {@code <li>}{@link Node nodes...}{@code </li>}
390     *
391     * @param   nodes           The {@link Node}s to append to the newly
392     *                          created {@link org.w3c.dom.Element}.
393     *
394     * @return  {@link org.w3c.dom.Element}
395     */
396    default FluentNode li(Node... nodes) { return element("li", nodes); }
397
398    /**
399     * {@code <li>}{@link #text(String) text(content)}{@code </li>}
400     *
401     * @param   content         {@link org.w3c.dom.Text} content
402     *
403     * @return  {@link org.w3c.dom.Element}
404     */
405    default FluentNode li(String content) { return li(text(content)); }
406
407    /**
408     * {@code <p>}{@link Node nodes...}{@code </p>}
409     *
410     * @param   stream          The {@link Stream} of {@link Node}s to
411     *                          append to the newly created
412     *                          {@link org.w3c.dom.Element}.
413     *
414     * @return  {@link org.w3c.dom.Element}
415     */
416    default FluentNode p(Stream<Node> stream) {
417        return p(stream.toArray(Node[]::new));
418    }
419
420    /**
421     * {@code <p>}{@link Node nodes...}{@code </p>}
422     *
423     * @param   nodes           The {@link Node}s to append to the newly
424     *                          created {@link org.w3c.dom.Element}.
425     *
426     * @return  {@link org.w3c.dom.Element}
427     */
428    default FluentNode p(Node... nodes) { return element("p", nodes); }
429
430    /**
431     * {@code <p>}{@link #text(String) text(content)}{@code </p>}
432     *
433     * @param   content         {@link org.w3c.dom.Text} content
434     *
435     * @return  {@link org.w3c.dom.Element}
436     */
437    default FluentNode p(String content) { return p(text(content)); }
438
439    /**
440     * {@code <pre}{@code >}{@link String content}{@code <}{@code /pre>}
441     *
442     * @param   content         {@link org.w3c.dom.Text} content
443     *
444     * @return  {@link org.w3c.dom.Element}
445     */
446    default FluentNode pre(String content) {
447        return element("pre").content(content);
448    }
449
450    /**
451     * {@code <pre lang="lang"}{@code >}{@link String content}{@code <}{@code /pre>}
452     *
453     * @param   lang            {@link org.w3c.dom.Attr} {@code lang} value
454     * @param   content         {@link org.w3c.dom.Text} content
455     *
456     * @return  {@link org.w3c.dom.Element}
457     */
458    default FluentNode pre(String lang, String content) {
459        return pre(content).add(attr("lang", lang));
460    }
461
462    /**
463     * {@code <table>}{@link Node nodes...}{@code </table>}
464     *
465     * @param   stream          The {@link Stream} of {@link Node}s to
466     *                          append to the newly created
467     *                          {@link org.w3c.dom.Element}.
468     *
469     * @return  {@link org.w3c.dom.Element}
470     */
471    default FluentNode table(Stream<Node> stream) {
472        return table(stream.toArray(Node[]::new));
473    }
474
475    /**
476     * {@code <table>}{@link Node nodes...}{@code </table>}
477     *
478     * @param   nodes           The {@link Node}s to append to the newly
479     *                          created {@link org.w3c.dom.Element}.
480     *
481     * @return  {@link org.w3c.dom.Element}
482     */
483    default FluentNode table(Node... nodes) { return element("table", nodes); }
484
485    /**
486     * {@code <caption>}{@link String content}{@code </caption>}
487     *
488     * @param   content         {@link org.w3c.dom.Text} content
489     *
490     * @return  {@link org.w3c.dom.Element}
491     */
492    default FluentNode caption(String content) {
493        return element("caption").content(content);
494    }
495
496    /**
497     * {@code <thead>}{@link Node nodes...}{@code </thead>}
498     *
499     * @param   stream          The {@link Stream} of {@link Node}s to
500     *                          append to the newly created
501     *                          {@link org.w3c.dom.Element}.
502     *
503     * @return  {@link org.w3c.dom.Element}
504     */
505    default FluentNode thead(Stream<Node> stream) {
506        return thead(stream.toArray(Node[]::new));
507    }
508
509    /**
510     * {@code <thead>}{@link Node nodes...}{@code </thead>}
511     *
512     * @param   nodes           The {@link Node}s to append to the newly
513     *                          created {@link org.w3c.dom.Element}.
514     *
515     * @return  {@link org.w3c.dom.Element}
516     */
517    default FluentNode thead(Node... nodes) { return element("thead", nodes); }
518
519    /**
520     * {@code <tbody>}{@link Node nodes...}{@code </tbody>}
521     *
522     * @param   stream          The {@link Stream} of {@link Node}s to
523     *                          append to the newly created
524     *                          {@link org.w3c.dom.Element}.
525     *
526     * @return  {@link org.w3c.dom.Element}
527     */
528    default FluentNode tbody(Stream<Node> stream) {
529        return tbody(stream.toArray(Node[]::new));
530    }
531
532    /**
533     * {@code <tbody>}{@link Node nodes...}{@code </tbody>}
534     *
535     * @param   nodes           The {@link Node}s to append to the newly
536     *                          created {@link org.w3c.dom.Element}.
537     *
538     * @return  {@link org.w3c.dom.Element}
539     */
540    default FluentNode tbody(Node... nodes) { return element("tbody", nodes); }
541
542    /**
543     * {@code <tfoot>}{@link Node nodes...}{@code </tfoot>}
544     *
545     * @param   stream          The {@link Stream} of {@link Node}s to
546     *                          append to the newly created
547     *                          {@link org.w3c.dom.Element}.
548     *
549     * @return  {@link org.w3c.dom.Element}
550     */
551    default FluentNode tfoot(Stream<Node> stream) {
552        return tfoot(stream.toArray(Node[]::new));
553    }
554
555    /**
556     * {@code <tfoot>}{@link Node nodes...}{@code </tfoot>}
557     *
558     * @param   nodes           The {@link Node}s to append to the newly
559     *                          created {@link org.w3c.dom.Element}.
560     *
561     * @return  {@link org.w3c.dom.Element}
562     */
563    default FluentNode tfoot(Node... nodes) { return element("tfoot", nodes); }
564
565    /**
566     * {@code <tr>}{@link Node nodes...}{@code </tr>}
567     *
568     * @param   stream          The {@link Stream} of {@link Node}s to
569     *                          append to the newly created
570     *                          {@link org.w3c.dom.Element}.
571     *
572     * @return  {@link org.w3c.dom.Element}
573     */
574    default FluentNode tr(Stream<Node> stream) {
575        return tr(stream.toArray(Node[]::new));
576    }
577
578    /**
579     * {@code <tr>}{@link Node nodes...}{@code </tr>}
580     *
581     * @param   nodes           The {@link Node}s to append to the newly
582     *                          created {@link org.w3c.dom.Element}.
583     *
584     * @return  {@link org.w3c.dom.Element}
585     */
586    default FluentNode tr(Node... nodes) { return element("tr", nodes); }
587
588    /**
589     * {@code <th>}{@link Node node}{@code </th>}
590     *
591     * @param   node            {@link Node}
592     *
593     * @return  {@link org.w3c.dom.Element}
594     */
595    default FluentNode th(Node node) { return element("th", node); }
596
597    /**
598     * {@code <th>}{@link #text(String) text(content)}{@code </th>}
599     *
600     * @param   content         {@link org.w3c.dom.Text} content
601     *
602     * @return  {@link org.w3c.dom.Element}
603     */
604    default FluentNode th(String content) { return th(text(content)); }
605
606    /**
607     * {@code <td>}{@link Node node}{@code </td>}
608     *
609     * @param   node            {@link Node}
610     *
611     * @return  {@link org.w3c.dom.Element}
612     */
613    default FluentNode td(Node node) { return element("td", node); }
614
615    /**
616     * {@code <td>content</td>}
617     *
618     * @param   content         {@link org.w3c.dom.Text} content
619     *
620     * @return  {@code <td/>} {@link org.w3c.dom.Element}
621     */
622    default FluentNode td(String content) { return td(text(content)); }
623
624    /**
625     * {@code <u>}{@link Node node}{@code </u>}
626     *
627     * @param   node            {@link Node}
628     *
629     * @return  {@link org.w3c.dom.Element}
630     */
631    default FluentNode u(Node node) { return element("u", node); }
632
633    /**
634     * {@code <u>}{@link #text(String) text(content)}{@code </u>}
635     *
636     * @param   content         {@link org.w3c.dom.Text} content
637     *
638     * @return  {@link org.w3c.dom.Element}
639     */
640    default FluentNode u(String content) { return u(text(content)); }
641}