params, Tag... children) {
18 | return build(params,children);
19 | }
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Head.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.typeref.Parameters;
4 |
5 | import static com.benjiweber.html.HtmlDsl.build;
6 |
7 | public class Head extends Tag {
8 |
9 | public interface Dsl {
10 | default Head head(Tag... children) {
11 | return build($->{},children);
12 | }
13 | default Head head(Parameters params, Tag... children) {
14 | return build(params,children);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Html.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.typeref.Parameters;
4 |
5 | import static com.benjiweber.html.HtmlDsl.build;
6 | import static com.benjiweber.html.StreamUtils.array;
7 |
8 | public class Html extends Tag {
9 |
10 | public interface Dsl {
11 | default Html html(Head head, Body body) {
12 | return build($->{}, array(head,body));
13 | }
14 | default Html html(Parameters params, Head head, Body body) {
15 | return build(params,array(head,body));
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Img.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.html.values.PixelMeasurement;
4 | import com.benjiweber.typeref.Parameters;
5 |
6 | import static com.benjiweber.html.HtmlDsl.build;
7 |
8 | public class Img extends ReflectiveTag implements Content {
9 | public String src;
10 | public PixelMeasurement width;
11 | public PixelMeasurement height;
12 |
13 | public interface Dsl {
14 | default Img img(Parameters
![]()
params, Tag... children) {
15 | return build(params, children);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Link.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.html.values.Rel;
4 | import com.benjiweber.html.values.Style;
5 | import com.benjiweber.typeref.Parameters;
6 |
7 | import static com.benjiweber.html.HtmlDsl.build;
8 |
9 | public class Link extends ReflectiveTag implements Content {
10 | public Rel rel;
11 | public Style type;
12 | public String href;
13 |
14 | public interface Dsl {
15 | default Link link(Parameters
params, Tag... children) {
16 | return build(params, children);
17 | }
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Literal.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import org.apache.commons.lang.StringEscapeUtils;
4 |
5 | public class Literal extends Tag implements Content {
6 | public Literal(String literal) {
7 | this.innerText = literal;
8 | }
9 |
10 | @Override
11 | public String toString() {
12 | return StringEscapeUtils.escapeHtml(innerText);
13 | }
14 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Meta.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.typeref.Parameters;
4 |
5 | import static com.benjiweber.html.HtmlDsl.build;
6 |
7 | public class Meta extends ReflectiveTag {
8 | public String charset;
9 | public interface Dsl {
10 | default Meta meta(Parameters
params, Tag... children) {
11 | return build(params, children);
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/P.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.typeref.Parameters;
4 |
5 | import static com.benjiweber.html.HtmlDsl.build;
6 |
7 | public class P extends Tag implements Content {
8 | public interface Dsl {
9 |
10 | default P p(String literal) {
11 | return p(new Literal(literal));
12 | }
13 | default
P p(T... children) {
14 | return build($->{}, children);
15 | }
16 | default P p(Parameters params, T... children) {
17 | return build(params, children);
18 | }
19 | default P p(Parameters
params, String literal) {
20 | return build(params, new Literal(literal) );
21 | }
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/ReflectiveTag.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import java.util.List;
4 | import java.util.stream.Stream;
5 |
6 | import static com.benjiweber.html.StreamUtils.unchecked;
7 | import static java.util.stream.Collectors.toList;
8 |
9 | public class ReflectiveTag extends Tag {
10 | public List attrs() {
11 | return Stream.concat(
12 | super.attrs().stream(),
13 | Stream.of(getClass().getDeclaredFields())
14 | .filter(field -> !field.getType().isAssignableFrom(List.class))
15 | .peek(field -> field.setAccessible(true))
16 | .map(field -> unchecked(() -> new Attr(field.getName(), field.get(this))))
17 | .filter(Attr::hasValue)
18 | ).collect(toList());
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/java/com/benjiweber/html/tags/Script.java:
--------------------------------------------------------------------------------
1 | package com.benjiweber.html.tags;
2 |
3 | import com.benjiweber.html.values.Rel;
4 | import com.benjiweber.html.values.ScriptType;
5 | import com.benjiweber.html.values.Style;
6 | import com.benjiweber.typeref.Parameters;
7 |
8 | import static com.benjiweber.html.HtmlDsl.build;
9 |
10 | public class Script extends ReflectiveTag {
11 | public ScriptType type;
12 | public String src;
13 |
14 | public interface Dsl {
15 | default Script script(Parameters
24 |
25 |
26 |
27 |
28 | Click Here
29 |
30 |
31 |
32 | some text
33 |
block
34 |
35 |
36 |
37 |
38 | """.trim(),
39 | html(
40 | head(
41 | title("Hello Html World"),
42 | meta($ -> $.charset = "utf-8"),
43 | link($->{ $.rel=stylesheet; $.type=css; $.href="/foo.css"; }),
44 | script($->{ $.type= javascript; $.src="/some.js"; })
45 | ),
46 | body(
47 | div($-> $.cssClass = "article",
48 | a($-> $.href="https://benjiweber.com/",
49 | span($->$.cssClass="label", "Click Here"),
50 | img($->{$.src="/myimg.jpg"; $.width=px(25); $.height=px(25); })
51 | ),
52 | p(span("some text"), div("block"))
53 | )
54 | )
55 | ).formatted()
56 | );
57 | }
58 |
59 | @Test
60 | public void example_generated_doc() {
61 | assertEquals(
62 | """
63 |
64 |
65 |
66 |
67 |
68 | Paragraph one
69 | Paragraph two
70 | Paragraph three
71 |
72 |
73 | """.trim(),
74 | html(
75 | head(
76 | meta($ -> $.charset = "utf-8")
77 | ),
78 | body(
79 | Stream.of("one","two","three")
80 | .map(number -> "Paragraph " + number)
81 | .map(content -> p(content))
82 | )
83 | ).formatted()
84 | );
85 | }
86 |
87 | @Test
88 | public void example_escaped_user_content() {
89 | assertEquals(
90 | """
91 |
92 |
93 |
94 |
95 |
96 | <script src="attack.js"></script>
97 |
98 |
99 | """.trim(),
100 | html(
101 | head(
102 | meta($-> $.charset = "utf-8")
103 | ),
104 | body(
105 | p("")
106 | )
107 | ).formatted()
108 | );
109 | }
110 |
111 |
112 | }
113 |
--------------------------------------------------------------------------------