diff --git a/pom.xml b/pom.xml index 5d529808..10a33ef7 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,11 @@ + + org.apache.commons + commons-lang3 + 3.7 + junit junit @@ -52,12 +57,6 @@ 1.3 test - - org.apache.commons - commons-lang3 - 3.0 - test - com.carrotsearch junit-benchmarks diff --git a/src/main/java/j2html/TagCreator.java b/src/main/java/j2html/TagCreator.java index 4e20d0c0..82d238ed 100644 --- a/src/main/java/j2html/TagCreator.java +++ b/src/main/java/j2html/TagCreator.java @@ -1,6 +1,7 @@ package j2html; import j2html.attributes.Attr; +import j2html.tags.ATag; import j2html.tags.ContainerTag; import j2html.tags.DomContent; import j2html.tags.DomContentJoiner; @@ -319,28 +320,28 @@ public static EmptyTag wbr(Attr.ShortForm shortAttr) { } // ContainerTags, generated in class j2html.tags.TagCreatorCodeGenerator - public static ContainerTag a() { - return new ContainerTag("a"); + public static ATag a() { + return new ATag(); } - public static ContainerTag a(String text) { - return new ContainerTag("a").withText(text); + public static ATag a(String text) { + return new ATag().withText(text); } - public static ContainerTag a(DomContent... dc) { - return new ContainerTag("a").with(dc); + public static ATag a(DomContent... dc) { + return new ATag().with(dc); } - public static ContainerTag a(Attr.ShortForm shortAttr) { - return Attr.addTo(new ContainerTag("a"), shortAttr); + public static ATag a(Attr.ShortForm shortAttr) { + return Attr.addTo(new ATag(), shortAttr); } - public static ContainerTag a(Attr.ShortForm shortAttr, String text) { - return Attr.addTo(new ContainerTag("a").withText(text), shortAttr); + public static ATag a(Attr.ShortForm shortAttr, String text) { + return Attr.addTo(new ATag().withText(text), shortAttr); } - public static ContainerTag a(Attr.ShortForm shortAttr, DomContent... dc) { - return Attr.addTo(new ContainerTag("a").with(dc), shortAttr); + public static ATag a(Attr.ShortForm shortAttr, DomContent... dc) { + return Attr.addTo(new ATag().with(dc), shortAttr); } public static ContainerTag abbr() { diff --git a/src/main/java/j2html/attributes/Attr.java b/src/main/java/j2html/attributes/Attr.java index 17c8af6d..0740a8ad 100644 --- a/src/main/java/j2html/attributes/Attr.java +++ b/src/main/java/j2html/attributes/Attr.java @@ -140,6 +140,7 @@ private Attr() { public static final String READONLY = "readonly"; public static final String REL = "rel"; public static final String REQUIRED = "required"; + public static final String REV = "rev"; public static final String REVERSED = "reversed"; public static final String ROLE = "role"; public static final String ROWS = "rows"; diff --git a/src/main/java/j2html/tags/ATag.java b/src/main/java/j2html/tags/ATag.java new file mode 100644 index 00000000..ed39d37e --- /dev/null +++ b/src/main/java/j2html/tags/ATag.java @@ -0,0 +1,114 @@ +package j2html.tags; + +import j2html.attributes.Attr; + +public class ATag extends ContainerTag { + + public ATag() { + super("a"); + } + + public ATag withCharset(String charset) { + return attr(Attr.CHARSET, charset); + } + + public ATag withCondCharset(boolean condition, String charset) { + return condAttr(condition, Attr.CHARSET, charset); + } + + public ATag withCoords(String charset) { + return attr(Attr.COORDS, charset); + } + + public ATag withCondCoords(boolean condition, String coords) { + return condAttr(condition, Attr.COORDS, coords); + } + + public ATag withDownload(String download) { + return attr(Attr.DOWNLOAD, download); + } + + public ATag withCondDownload(boolean condition, String download) { + return condAttr(condition, Attr.COORDS, download); + } + + public ATag withHref(String href) { + return attr(Attr.HREF, href); + } + + public ATag withCondHref(boolean condition, String href) { + return condAttr(condition, Attr.HREF, href); + } + + public ATag withHreflang(String hreflang) { + return attr(Attr.HREFLANG, hreflang); + } + + public ATag withCondHreflang(boolean condition, String hreflang) { + return condAttr(condition, Attr.HREFLANG, hreflang); + } + + public ATag withMedia(String media) { + return attr(Attr.MEDIA, media); + } + + public ATag withCondMedia(boolean condition, String media) { + return condAttr(condition, Attr.MEDIA, media); + } + + public ATag withName(String name) { + return attr(Attr.NAME, name); + } + + public ATag withCondName(boolean condition, String name) { + return condAttr(condition, Attr.NAME, name); + } + + public ATag withPing(String ping) { + return attr(Attr.PING, ping); + } + + public ATag withCondPing(boolean condition, String ping) { + return condAttr(condition, Attr.PING, ping); + } + + public ATag withRel(String rel) { + return attr(Attr.REL, rel); + } + + public ATag withCondRel(boolean condition, String rel) { + return condAttr(condition, Attr.REL, rel); + } + + public ATag withRev(String rev) { + return attr(Attr.REV, rev); + } + + public ATag withCondRev(boolean condition, String rev) { + return condAttr(condition, Attr.REV, rev); + } + + public ATag withShape(String shape) { + return attr(Attr.SHAPE, shape); + } + + public ATag withCondShape(boolean condition, String shape) { + return condAttr(condition, Attr.SHAPE, shape); + } + + public ATag withTarget(String target) { + return attr(Attr.TARGET, target); + } + + public ATag withCondTarget(boolean condition, String target) { + return condAttr(condition, Attr.TARGET, target); + } + + public ATag withType(String type) { + return attr(Attr.TYPE, type); + } + + public ATag withCondType(boolean condition, String type) { + return condAttr(condition, Attr.TYPE, type); + } +} diff --git a/src/main/java/j2html/tags/ContainerTag.java b/src/main/java/j2html/tags/ContainerTag.java index dbd7a7ae..78e99e87 100644 --- a/src/main/java/j2html/tags/ContainerTag.java +++ b/src/main/java/j2html/tags/ContainerTag.java @@ -5,7 +5,7 @@ import java.util.ArrayList; import java.util.List; -public class ContainerTag extends Tag { +public class ContainerTag> extends Tag { private List children; @@ -21,15 +21,15 @@ public ContainerTag(String tagName) { * @param child DomContent-object to be appended * @return itself for easy chaining */ - public ContainerTag with(DomContent child) { + public T with(DomContent child) { if (this == child) { throw new RuntimeException("Cannot append a tag to itself."); } if (child == null) { - return this; // in some cases, like when using iff(), we ignore null children + return (T) this; // in some cases, like when using iff(), we ignore null children } children.add(child); - return this; + return (T) this; } @@ -41,8 +41,8 @@ public ContainerTag with(DomContent child) { * @param child DomContent-object to be appended if condition met * @return itself for easy chaining */ - public ContainerTag condWith(boolean condition, DomContent child) { - return condition ? this.with(child) : this; + public T condWith(boolean condition, DomContent child) { + return condition ? this.with(child) : (T) this; } @@ -52,13 +52,13 @@ public ContainerTag condWith(boolean condition, DomContent child) { * @param children DomContent-objects to be appended * @return itself for easy chaining */ - public ContainerTag with(Iterable children) { + public T with(Iterable children) { if (children != null) { for (DomContent child : children) { this.with(child); } } - return this; + return (T) this; } @@ -70,8 +70,8 @@ public ContainerTag with(Iterable children) { * @param children DomContent-objects to be appended if condition met * @return itself for easy chaining */ - public ContainerTag condWith(boolean condition, Iterable children) { - return condition ? this.with(children) : this; + public T condWith(boolean condition, Iterable children) { + return condition ? this.with(children) : (T) this; } @@ -81,11 +81,11 @@ public ContainerTag condWith(boolean condition, Iterable c * @param children DomContent-objects to be appended * @return itself for easy chaining */ - public ContainerTag with(DomContent... children) { + public T with(DomContent... children) { for (DomContent child : children) { with(child); } - return this; + return (T) this; } @@ -97,8 +97,8 @@ public ContainerTag with(DomContent... children) { * @param children DomContent-objects to be appended if condition met * @return itself for easy chaining */ - public ContainerTag condWith(boolean condition, DomContent... children) { - return condition ? this.with(children) : this; + public T condWith(boolean condition, DomContent... children) { + return condition ? this.with(children) : (T) this; } @@ -108,7 +108,7 @@ public ContainerTag condWith(boolean condition, DomContent... children) { * @param text the text to be appended * @return itself for easy chaining */ - public ContainerTag withText(String text) { + public T withText(String text) { return with(new Text(text)); } diff --git a/src/main/java/j2html/tags/EmptyTag.java b/src/main/java/j2html/tags/EmptyTag.java index 7dd63f49..e9854e0e 100644 --- a/src/main/java/j2html/tags/EmptyTag.java +++ b/src/main/java/j2html/tags/EmptyTag.java @@ -4,7 +4,7 @@ import j2html.attributes.Attribute; import java.io.IOException; -public class EmptyTag extends Tag { +public class EmptyTag> extends Tag { public EmptyTag(String tagName) { super(tagName); diff --git a/src/main/java/j2html/tags/Tag.java b/src/main/java/j2html/tags/Tag.java index 888a8dee..b4063f09 100644 --- a/src/main/java/j2html/tags/Tag.java +++ b/src/main/java/j2html/tags/Tag.java @@ -144,6 +144,7 @@ public boolean equals(Object obj) { return ((Tag) obj).render().equals(this.render()); } + // TODO Remove below attribute accessors and add only those which are common to all HTML elements: https://www.w3.org/TR/2010/WD-html-markup-20100624/common-attributes.html /** * Convenience methods that call attr with predefined attributes * diff --git a/src/main/java/j2html/tags/TagCreatorCodeGenerator.java b/src/main/java/j2html/tags/TagCreatorCodeGenerator.java index e8a04165..f12e27fb 100644 --- a/src/main/java/j2html/tags/TagCreatorCodeGenerator.java +++ b/src/main/java/j2html/tags/TagCreatorCodeGenerator.java @@ -3,16 +3,19 @@ import java.util.Arrays; import java.util.List; +import static org.apache.commons.lang3.StringUtils.capitalize; + class TagCreatorCodeGenerator { public static void main(String[] args) { System.out.println("// EmptyTags, generated in " + TagCreatorCodeGenerator.class); for (String tag : emptyTags()) { - String emptyA1 = "public static EmptyTag " + tag + "()"; - String emptyA2 = "{ return new EmptyTag(\"" + tag + "\"); }"; + String classNamePrefix = capitalize(tag); + String emptyA1 = "public static " + classNamePrefix + "Tag " + tag + "()"; + String emptyA2 = "{ return new " + classNamePrefix + "Tag(); }"; // Attr shorthands - String emptyB1 = "public static EmptyTag " + tag + "(Attr.ShortForm shortAttr)"; - String emptyB2 = "{ return Attr.addTo(new EmptyTag(\"" + tag + "\"), shortAttr); }"; + String emptyB1 = "public static " + classNamePrefix + "Tag " + tag + "(Attr.ShortForm shortAttr)"; + String emptyB2 = "{ return Attr.addTo(new " + classNamePrefix + "Tag(), shortAttr); }"; // Print System.out.println(String.format("%-80s%1s", emptyA1, emptyA2)); System.out.println(String.format("%-80s%1s", emptyB1, emptyB2)); @@ -20,19 +23,20 @@ public static void main(String[] args) { } System.out.println("// ContainerTags, generated in " + TagCreatorCodeGenerator.class); for (String tag : containerTags()) { - String containerA1 = "public static ContainerTag " + tag + "()"; - String containerA2 = "{ return new ContainerTag(\"" + tag + "\"); }"; - String containerB1 = "public static ContainerTag " + tag + "(String text)"; - String containerB2 = "{ return new ContainerTag(\"" + tag + "\").withText(text); }"; - String containerC1 = "public static ContainerTag " + tag + "(DomContent... dc)"; - String containerC2 = "{ return new ContainerTag(\"" + tag + "\").with(dc); }"; + String classNamePrefix = capitalize(tag); + String containerA1 = "public static " + classNamePrefix + "Tag " + tag + "()"; + String containerA2 = "{ return new " + classNamePrefix + "Tag(); }"; + String containerB1 = "public static " + classNamePrefix + "Tag " + tag + "(String text)"; + String containerB2 = "{ return new " + classNamePrefix + "Tag().withText(text); }"; + String containerC1 = "public static " + classNamePrefix + "Tag " + tag + "(DomContent... dc)"; + String containerC2 = "{ return new " + classNamePrefix + "Tag().with(dc); }"; // Attr shorthands - String containerD1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr)"; - String containerD2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\"), shortAttr); }"; - String containerE1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr, String text)"; - String containerE2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\").withText(text), shortAttr); }"; - String containerF1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr, DomContent... dc)"; - String containerF2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\").with(dc), shortAttr); }"; + String containerD1 = "public static " + classNamePrefix + "Tag " + tag + "(Attr.ShortForm shortAttr)"; + String containerD2 = "{ return Attr.addTo(new " + classNamePrefix + "Tag(), shortAttr); }"; + String containerE1 = "public static " + classNamePrefix + "Tag " + tag + "(Attr.ShortForm shortAttr, String text)"; + String containerE2 = "{ return Attr.addTo(new " + classNamePrefix + "Tag().withText(text), shortAttr); }"; + String containerF1 = "public static " + classNamePrefix + "Tag " + tag + "(Attr.ShortForm shortAttr, DomContent... dc)"; + String containerF2 = "{ return Attr.addTo(new " + classNamePrefix + "Tag().with(dc), shortAttr); }"; // Print System.out.println(String.format("%-80s%1s", containerA1, containerA2)); System.out.println(String.format("%-80s%1s", containerB1, containerB2)); @@ -47,121 +51,121 @@ public static void main(String[] args) { // This is a method that contains all ContainerTags, there is nothing below it private static List emptyTags() { return Arrays.asList( - "area", - "base", - "br", - "col", - //"!DOCTYPE html", - "embed", - "hr", - "img", - "input", - "keygen", - "link", - "meta", - "param", - "source", - "track", - "wbr" + "area", + "base", + "br", + "col", + //"!DOCTYPE html", + "embed", + "hr", + "img", + "input", + "keygen", + "link", + "meta", + "param", + "source", + "track", + "wbr" ); } private static List containerTags() { return Arrays.asList( - "a", - "abbr", - "address", - "article", - "aside", - "audio", - "b", - "bdi", - "bdo", - "blockquote", - "body", - "button", - "canvas", - "caption", - "cite", - "code", - "colgroup", - "datalist", - "dd", - "del", - "details", - "dfn", - "dialog", - "div", - "dl", - "dt", - "em", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "html", - "i", - "iframe", - "ins", - "kbd", - "label", - "legend", - "li", - "main", - "map", - "mark", - "menu", - "menuitem", - "meter", - "nav", - "noscript", - "object", - "ol", - "optgroup", - "option", - "output", - "p", - "pre", - "progress", - "q", - "rp", - "rt", - "ruby", - "s", - "samp", - "script", - "section", - "select", - "small", - "span", - "strong", - "style", - "sub", - "summary", - "sup", - "table", - "tbody", - "td", - "textarea", - "tfoot", - "th", - "thead", - "time", - "title", - "tr", - "u", - "ul", - "var", - "video" + "a", + "abbr", + "address", + "article", + "aside", + "audio", + "b", + "bdi", + "bdo", + "blockquote", + "body", + "button", + "canvas", + "caption", + "cite", + "code", + "colgroup", + "datalist", + "dd", + "del", + "details", + "dfn", + "dialog", + "div", + "dl", + "dt", + "em", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "html", + "i", + "iframe", + "ins", + "kbd", + "label", + "legend", + "li", + "main", + "map", + "mark", + "menu", + "menuitem", + "meter", + "nav", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "pre", + "progress", + "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", + "section", + "select", + "small", + "span", + "strong", + "style", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "u", + "ul", + "var", + "video" ); } }