001package ball.xml;
002/*-
003 * ##########################################################################
004 * Utilities
005 * $Id: HTMLTemplates.java 5285 2020-02-05 04:23:21Z 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 - 2020 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: 5285 $
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
132     *                          {@link org.w3c.dom.Element}.
133     *
134     * @return  {@link org.w3c.dom.Element}
135     */
136    default FluentNode div(Node... nodes) { return element("div", nodes); }
137
138    /**
139     * {@code <h1>}{@link Node nodes...}{@code </h1>}
140     *
141     * @param   stream          The {@link Stream} of {@link Node}s to
142     *                          append to the newly created
143     *                          {@link org.w3c.dom.Element}.
144     *
145     * @return  {@link org.w3c.dom.Element}
146     */
147    default FluentNode h1(Stream<Node> stream) {
148        return h1(stream.toArray(Node[]::new));
149    }
150
151    /**
152     * {@code <h1>}{@link Node nodes...}{@code </h1>}
153     *
154     * @param   nodes           The {@link Node}s to append to the newly
155     *                          created
156     *                          {@link org.w3c.dom.Element}.
157     *
158     * @return  {@link org.w3c.dom.Element}
159     */
160    default FluentNode h1(Node... nodes) { return element("h1", nodes); }
161
162    /**
163     * {@code <h1>}{@link #text(String) text(content)}{@code </h1>}
164     *
165     * @param   content         {@link org.w3c.dom.Text} content
166     *
167     * @return  {@link org.w3c.dom.Element}
168     */
169    default FluentNode h1(String content) { return h1(text(content)); }
170
171    /**
172     * {@code <h2>}{@link Node nodes...}{@code </h2>}
173     *
174     * @param   stream          The {@link Stream} of {@link Node}s to
175     *                          append to the newly created
176     *                          {@link org.w3c.dom.Element}.
177     *
178     * @return  {@link org.w3c.dom.Element}
179     */
180    default FluentNode h2(Stream<Node> stream) {
181        return h2(stream.toArray(Node[]::new));
182    }
183
184    /**
185     * {@code <h2>}{@link Node nodes...}{@code </h2>}
186     *
187     * @param   nodes           The {@link Node}s to append to the newly
188     *                          created
189     *                          {@link org.w3c.dom.Element}.
190     *
191     * @return  {@link org.w3c.dom.Element}
192     */
193    default FluentNode h2(Node... nodes) { return element("h2", nodes); }
194
195    /**
196     * {@code <h2>}{@link #text(String) text(content)}{@code </h2>}
197     *
198     * @param   content         {@link org.w3c.dom.Text} content
199     *
200     * @return  {@link org.w3c.dom.Element}
201     */
202    default FluentNode h2(String content) { return h2(text(content)); }
203
204    /**
205     * {@code <h3>}{@link Node nodes...}{@code </h3>}
206     *
207     * @param   stream          The {@link Stream} of {@link Node}s to
208     *                          append to the newly created
209     *                          {@link org.w3c.dom.Element}.
210     *
211     * @return  {@link org.w3c.dom.Element}
212     */
213    default FluentNode h3(Stream<Node> stream) {
214        return h3(stream.toArray(Node[]::new));
215    }
216
217    /**
218     * {@code <h3>}{@link Node nodes...}{@code </h3>}
219     *
220     * @param   nodes           The {@link Node}s to append to the newly
221     *                          created
222     *                          {@link org.w3c.dom.Element}.
223     *
224     * @return  {@link org.w3c.dom.Element}
225     */
226    default FluentNode h3(Node... nodes) { return element("h3", nodes); }
227
228    /**
229     * {@code <h3>}{@link #text(String) text(content)}{@code </h3>}
230     *
231     * @param   content         {@link org.w3c.dom.Text} content
232     *
233     * @return  {@link org.w3c.dom.Element}
234     */
235    default FluentNode h3(String content) { return h3(text(content)); }
236
237    /**
238     * {@code <h4>}{@link Node nodes...}{@code </h4>}
239     *
240     * @param   stream          The {@link Stream} of {@link Node}s to
241     *                          append to the newly created
242     *                          {@link org.w3c.dom.Element}.
243     *
244     * @return  {@link org.w3c.dom.Element}
245     */
246    default FluentNode h4(Stream<Node> stream) {
247        return h4(stream.toArray(Node[]::new));
248    }
249
250    /**
251     * {@code <h4>}{@link Node nodes...}{@code </h4>}
252     *
253     * @param   nodes           The {@link Node}s to append to the newly
254     *                          created
255     *                          {@link org.w3c.dom.Element}.
256     *
257     * @return  {@link org.w3c.dom.Element}
258     */
259    default FluentNode h4(Node... nodes) { return element("h4", nodes); }
260
261    /**
262     * {@code <h4>}{@link #text(String) text(content)}{@code </h4>}
263     *
264     * @param   content         {@link org.w3c.dom.Text} content
265     *
266     * @return  {@link org.w3c.dom.Element}
267     */
268    default FluentNode h4(String content) { return h4(text(content)); }
269
270    /**
271     * {@code <h5>}{@link Node nodes...}{@code </h5>}
272     *
273     * @param   stream          The {@link Stream} of {@link Node}s to
274     *                          append to the newly created
275     *                          {@link org.w3c.dom.Element}.
276     *
277     * @return  {@link org.w3c.dom.Element}
278     */
279    default FluentNode h5(Stream<Node> stream) {
280        return h5(stream.toArray(Node[]::new));
281    }
282
283    /**
284     * {@code <h5>}{@link Node nodes...}{@code </h5>}
285     *
286     * @param   nodes           The {@link Node}s to append to the newly
287     *                          created
288     *                          {@link org.w3c.dom.Element}.
289     *
290     * @return  {@link org.w3c.dom.Element}
291     */
292    default FluentNode h5(Node... nodes) { return element("h5", nodes); }
293
294    /**
295     * {@code <h5>}{@link #text(String) text(content)}{@code </h5>}
296     *
297     * @param   content         {@link org.w3c.dom.Text} content
298     *
299     * @return  {@link org.w3c.dom.Element}
300     */
301    default FluentNode h5(String content) { return h5(text(content)); }
302
303    /**
304     * {@code <h6>}{@link Node nodes...}{@code </h6>}
305     *
306     * @param   stream          The {@link Stream} of {@link Node}s to
307     *                          append to the newly created
308     *                          {@link org.w3c.dom.Element}.
309     *
310     * @return  {@link org.w3c.dom.Element}
311     */
312    default FluentNode h6(Stream<Node> stream) {
313        return h6(stream.toArray(Node[]::new));
314    }
315
316    /**
317     * {@code <h6>}{@link Node nodes...}{@code </h6>}
318     *
319     * @param   nodes           The {@link Node}s to append to the newly
320     *                          created
321     *                          {@link org.w3c.dom.Element}.
322     *
323     * @return  {@link org.w3c.dom.Element}
324     */
325    default FluentNode h6(Node... nodes) { return element("h6", nodes); }
326
327    /**
328     * {@code <h6>}{@link #text(String) text(content)}{@code </h6>}
329     *
330     * @param   content         {@link org.w3c.dom.Text} content
331     *
332     * @return  {@link org.w3c.dom.Element}
333     */
334    default FluentNode h6(String content) { return h6(text(content)); }
335
336    /**
337     * {@code <ol>}{@link Node nodes...}{@code </ol>}
338     *
339     * @param   stream          The {@link Stream} of {@link Node}s to
340     *                          append to the newly created
341     *                          {@link org.w3c.dom.Element}.
342     *
343     * @return  {@link org.w3c.dom.Element}
344     */
345    default FluentNode ol(Stream<Node> stream) {
346        return ol(stream.toArray(Node[]::new));
347    }
348
349    /**
350     * {@code <ol>}{@link Node nodes...}{@code </ol>}
351     *
352     * @param   nodes           The {@link Node}s to append to the newly
353     *                          created
354     *                          {@link org.w3c.dom.Element}.
355     *
356     * @return  {@link org.w3c.dom.Element}
357     */
358    default FluentNode ol(Node... nodes) { return element("ol", nodes); }
359
360    /**
361     * {@code <ul>}{@link Node nodes...}{@code </ul>}
362     *
363     * @param   stream          The {@link Stream} of {@link Node}s to
364     *                          append to the newly created
365     *                          {@link org.w3c.dom.Element}.
366     *
367     * @return  {@link org.w3c.dom.Element}
368     */
369    default FluentNode ul(Stream<Node> stream) {
370        return ul(stream.toArray(Node[]::new));
371    }
372
373    /**
374     * {@code <ul>}{@link Node nodes...}{@code </ul>}
375     *
376     * @param   nodes           The {@link Node}s to append to the newly
377     *                          created
378     *                          {@link org.w3c.dom.Element}.
379     *
380     * @return  {@link org.w3c.dom.Element}
381     */
382    default FluentNode ul(Node... nodes) { return element("ul", nodes); }
383
384    /**
385     * {@code <li>}{@link Node nodes...}{@code </li>}
386     *
387     * @param   stream          The {@link Stream} of {@link Node}s to
388     *                          append to the newly created
389     *                          {@link org.w3c.dom.Element}.
390     *
391     * @return  {@link org.w3c.dom.Element}
392     */
393    default FluentNode li(Stream<Node> stream) {
394        return li(stream.toArray(Node[]::new));
395    }
396
397    /**
398     * {@code <li>}{@link Node nodes...}{@code </li>}
399     *
400     * @param   nodes           The {@link Node}s to append to the newly
401     *                          created
402     *                          {@link org.w3c.dom.Element}.
403     *
404     * @return  {@link org.w3c.dom.Element}
405     */
406    default FluentNode li(Node... nodes) { return element("li", nodes); }
407
408    /**
409     * {@code <li>}{@link #text(String) text(content)}{@code </li>}
410     *
411     * @param   content         {@link org.w3c.dom.Text} content
412     *
413     * @return  {@link org.w3c.dom.Element}
414     */
415    default FluentNode li(String content) { return li(text(content)); }
416
417    /**
418     * {@code <p>}{@link Node nodes...}{@code </p>}
419     *
420     * @param   stream          The {@link Stream} of {@link Node}s to
421     *                          append to the newly created
422     *                          {@link org.w3c.dom.Element}.
423     *
424     * @return  {@link org.w3c.dom.Element}
425     */
426    default FluentNode p(Stream<Node> stream) {
427        return p(stream.toArray(Node[]::new));
428    }
429
430    /**
431     * {@code <p>}{@link Node nodes...}{@code </p>}
432     *
433     * @param   nodes           The {@link Node}s to append to the newly
434     *                          created
435     *                          {@link org.w3c.dom.Element}.
436     *
437     * @return  {@link org.w3c.dom.Element}
438     */
439    default FluentNode p(Node... nodes) { return element("p", nodes); }
440
441    /**
442     * {@code <p>}{@link #text(String) text(content)}{@code </p>}
443     *
444     * @param   content         {@link org.w3c.dom.Text} content
445     *
446     * @return  {@link org.w3c.dom.Element}
447     */
448    default FluentNode p(String content) { return p(text(content)); }
449
450    /**
451     * {@code <pre}{@code >}{@link String content}{@code <}{@code /pre>}
452     *
453     * @param   content         {@link org.w3c.dom.Text} content
454     *
455     * @return  {@link org.w3c.dom.Element}
456     */
457    default FluentNode pre(String content) {
458        return element("pre").content(content);
459    }
460
461    /**
462     * {@code <pre lang="lang"}{@code >}{@link String content}{@code <}{@code /pre>}
463     *
464     * @param   lang            {@link org.w3c.dom.Attr} {@code lang} value
465     * @param   content         {@link org.w3c.dom.Text} content
466     *
467     * @return  {@link org.w3c.dom.Element}
468     */
469    default FluentNode pre(String lang, String content) {
470        return pre(content).add(attr("lang", lang));
471    }
472
473    /**
474     * {@code <table>}{@link Node nodes...}{@code </table>}
475     *
476     * @param   stream          The {@link Stream} of {@link Node}s to
477     *                          append to the newly created
478     *                          {@link org.w3c.dom.Element}.
479     *
480     * @return  {@link org.w3c.dom.Element}
481     */
482    default FluentNode table(Stream<Node> stream) {
483        return table(stream.toArray(Node[]::new));
484    }
485
486    /**
487     * {@code <table>}{@link Node nodes...}{@code </table>}
488     *
489     * @param   nodes           The {@link Node}s to append to the newly
490     *                          created
491     *                          {@link org.w3c.dom.Element}.
492     *
493     * @return  {@link org.w3c.dom.Element}
494     */
495    default FluentNode table(Node... nodes) { return element("table", nodes); }
496
497    /**
498     * {@code <caption>}{@link String content}{@code </caption>}}
499     *
500     * @param   content         {@link org.w3c.dom.Text} content
501     *
502     * @return  {@link org.w3c.dom.Element}
503     */
504    default FluentNode caption(String content) {
505        return element("caption").content(content);
506    }
507
508    /**
509     * {@code <thead>}{@link Node nodes...}{@code </thead>}
510     *
511     * @param   stream          The {@link Stream} of {@link Node}s to
512     *                          append to the newly created
513     *                          {@link org.w3c.dom.Element}.
514     *
515     * @return  {@link org.w3c.dom.Element}
516     */
517    default FluentNode thead(Stream<Node> stream) {
518        return thead(stream.toArray(Node[]::new));
519    }
520
521    /**
522     * {@code <thead>}{@link Node nodes...}{@code </thead>}
523     *
524     * @param   nodes           The {@link Node}s to append to the newly
525     *                          created
526     *                          {@link org.w3c.dom.Element}.
527     *
528     * @return  {@link org.w3c.dom.Element}
529     */
530    default FluentNode thead(Node... nodes) { return element("thead", nodes); }
531
532    /**
533     * {@code <tbody>}{@link Node nodes...}{@code </tbody>}
534     *
535     * @param   stream          The {@link Stream} of {@link Node}s to
536     *                          append to the newly created
537     *                          {@link org.w3c.dom.Element}.
538     *
539     * @return  {@link org.w3c.dom.Element}
540     */
541    default FluentNode tbody(Stream<Node> stream) {
542        return tbody(stream.toArray(Node[]::new));
543    }
544
545    /**
546     * {@code <tbody>}{@link Node nodes...}{@code </tbody>}
547     *
548     * @param   nodes           The {@link Node}s to append to the newly
549     *                          created
550     *                          {@link org.w3c.dom.Element}.
551     *
552     * @return  {@link org.w3c.dom.Element}
553     */
554    default FluentNode tbody(Node... nodes) { return element("tbody", nodes); }
555
556    /**
557     * {@code <tfoot>}{@link Node nodes...}{@code </tfoot>}
558     *
559     * @param   stream          The {@link Stream} of {@link Node}s to
560     *                          append to the newly created
561     *                          {@link org.w3c.dom.Element}.
562     *
563     * @return  {@link org.w3c.dom.Element}
564     */
565    default FluentNode tfoot(Stream<Node> stream) {
566        return tfoot(stream.toArray(Node[]::new));
567    }
568
569    /**
570     * {@code <tfoot>}{@link Node nodes...}{@code </tfoot>}
571     *
572     * @param   nodes           The {@link Node}s to append to the newly
573     *                          created
574     *                          {@link org.w3c.dom.Element}.
575     *
576     * @return  {@link org.w3c.dom.Element}
577     */
578    default FluentNode tfoot(Node... nodes) { return element("tfoot", nodes); }
579
580    /**
581     * {@code <tr>}{@link Node nodes...}{@code </tr>}
582     *
583     * @param   stream          The {@link Stream} of {@link Node}s to
584     *                          append to the newly created
585     *                          {@link org.w3c.dom.Element}.
586     *
587     * @return  {@link org.w3c.dom.Element}
588     */
589    default FluentNode tr(Stream<Node> stream) {
590        return tr(stream.toArray(Node[]::new));
591    }
592
593    /**
594     * {@code <tr>}{@link Node nodes...}{@code </tr>}
595     *
596     * @param   nodes           The {@link Node}s to append to the newly
597     *                          created
598     *                          {@link org.w3c.dom.Element}.
599     *
600     * @return  {@link org.w3c.dom.Element}
601     */
602    default FluentNode tr(Node... nodes) { return element("tr", nodes); }
603
604    /**
605     * {@code <th>}{@link Node node}{@code </th>}
606     *
607     * @param   node            {@link Node}
608     *
609     * @return  {@link org.w3c.dom.Element}
610     */
611    default FluentNode th(Node node) { return element("th", node); }
612
613    /**
614     * {@code <th>}{@link #text(String) text(content)}{@code </th>}
615     *
616     * @param   content         {@link org.w3c.dom.Text} content
617     *
618     * @return  {@link org.w3c.dom.Element}
619     */
620    default FluentNode th(String content) { return th(text(content)); }
621
622    /**
623     * {@code <td>}{@link Node node}{@code </td>}
624     *
625     * @param   node            {@link Node}
626     *
627     * @return  {@link org.w3c.dom.Element}
628     */
629    default FluentNode td(Node node) { return element("td", node); }
630
631    /**
632     * {@code <td>content</td>}
633     *
634     * @param   content         {@link org.w3c.dom.Text} content
635     *
636     * @return  {@code <td/>} {@link org.w3c.dom.Element}
637     */
638    default FluentNode td(String content) { return td(text(content)); }
639
640    /**
641     * {@code <u>}{@link Node node}{@code </u>}
642     *
643     * @param   node            {@link Node}
644     *
645     * @return  {@link org.w3c.dom.Element}
646     */
647    default FluentNode u(Node node) { return element("u", node); }
648
649    /**
650     * {@code <u>}{@link #text(String) text(content)}{@code </u>}
651     *
652     * @param   content         {@link org.w3c.dom.Text} content
653     *
654     * @return  {@link org.w3c.dom.Element}
655     */
656    default FluentNode u(String content) { return u(text(content)); }
657}