52 Commits

Author SHA1 Message Date
David
10a400ac28 [maven-release-plugin] prepare release j2html-0.88 2017-01-29 21:32:34 +01:00
David
e0b0425da4 Remove stringutils and add simple escaper (#34) 2017-01-29 17:26:54 +01:00
David
f44d62d93a Change 'unsafeHtml' to 'rawHtml' (#44) 2017-01-29 16:43:50 +01:00
David
652b6921c7 Use assertThat instead of assertEquals 2017-01-29 16:27:19 +01:00
David
d7e56686d1 Add equals method to Tag (#28) 2017-01-29 15:49:36 +01:00
David
cc289b8430 Fix imports in rendertest 2017-01-29 14:46:14 +01:00
David
85d0ab023c Add withStyle method 2017-01-29 14:22:33 +01:00
David
0b3ca28cf3 Sort attributes 2017-01-29 14:16:14 +01:00
David
45a7c32d88 Auto format files 2017-01-29 13:20:18 +01:00
David
733199cd15 Remove closure in favor of a simple JSMin implementation
Closure is a great js-minifier, but js-minification is really
outside the scope of this project.
A simple space/line stripper should be suffcient.
2017-01-29 12:55:30 +01:00
David
df1e4da96d Autoformat CSSMin 2017-01-29 12:07:08 +01:00
David
05dcf6d679 Merge pull request #39 from dellgreen/java8doclintFixs
updated javadoc comments to pass doclint checks in java 8
2017-01-15 20:56:07 +01:00
David
b5d7f5fe18 Merge pull request #38 from dellgreen/renameTestResource
renamed test java resource to match its declared class name
2017-01-15 20:55:07 +01:00
David
872baeeeea Merge pull request #36 from charphi/optional-dep
Set closure-compiler dependency as optional.
2017-01-15 20:54:58 +01:00
David
fcc42cfd8f Merge pull request #35 from tipsy/pr/31
created render(Appendable)-method as a faster alternative to converting to string and writing then.
2017-01-15 20:54:47 +01:00
Dell Green
db8d968f7e updated javadoc comments to pass doclint checks in java 8 2017-01-13 11:42:11 +00:00
Dell Green
673a19faaa renamed test java resource to match its declared class name, otherwise Netbeans flags it as an error 2017-01-13 11:32:09 +00:00
Philippe Charles
96020f8396 Set closure-compiler dependency as optional. 2017-01-09 11:50:53 +01:00
Abius
91c3f42696 created render(Appendable)-method as a faster alternative to converting
to string and writing then.
2017-01-07 16:09:11 +01:00
David
0efd3c6f0c Tell travis to use latest sdk 2017-01-07 16:03:18 +01:00
David
b73c5d0c14 Merge pull request #27 from amaembo/master
Several cosmetic fixes
2016-06-12 10:19:00 +02:00
lan
977c31dad5 Cosmetic fixes:
1. Attr: all public static constants declared final
2. Tag: f-bounded type declaration
3. Tag::renderOpenTag: StringBuilder used
4. ContainerTag::with, condWith: Iterable and PECS arguments used
2016-06-06 15:49:08 +06:00
David
0c1cb2be10 Merge pull request #24 from DevFactory/release/general-code-quality-fix-1
Use isEmpty in TagContainer and collapse some if's in CSSMin
2016-04-26 22:36:27 +02:00
David
d09eb8597c Merge pull request #23 from DevFactory/release/exception-classes-should-be-immutable-fix-1
Code quality fix - Exception classes should be immutable.
2016-04-26 22:33:57 +02:00
David
b8a3882529 Merge pull request #22 from DevFactory/release/utility-classes-should-not-have-public-constructors-fix-1
Code quality fix - Utility classes should not have public constructors.
2016-04-26 22:33:12 +02:00
tipsy
b366207e30 Bump travis jdk version 2016-04-24 16:05:47 +02:00
tipsy
3821671a65 Add 'each' and 'filter' methods 2016-04-24 15:53:58 +02:00
Faisal Hameed
66fff8db69 Fixing squid:S1066, squid:S1155 2016-04-22 12:33:44 +05:00
Faisal Hameed
b11af765fa Fixing squid:S1165 - Exception classes should be immutable. 2016-04-22 12:03:36 +05:00
Faisal Hameed
d331789074 Fixing squid:S1118 - Utility classes should not have public constructors. 2016-04-22 11:55:40 +05:00
David
314de2459a Update README.md 2016-04-16 21:57:25 +02:00
tipsy
2beb4e903e Refactor core classes
- Introduce DomContent class with render method
- Make Tag and Text/UnescapedText extend DomContent (Text/UnescapedText don't extend Tag anymore)
- Use generics to remove duplicate code from ContainerTag and EmptyTag
- Remove setParent method
- Make setAttribute private
2016-04-02 18:08:37 +02:00
tipsy
d29da958e1 Auto format / organize imports 2016-04-01 22:45:01 +02:00
tipsy
595d658a15 Clean up CSSMin slightly 2016-04-01 22:44:42 +02:00
tipsy
dd4a025ad0 Add missing tests 2016-04-01 22:43:55 +02:00
David
3c42c7d4f4 Merge pull request #15 from arnzel/patch-1
Add Attribute "role"
2016-04-01 14:22:36 +02:00
Arne Zelasko
871405c414 Update EmptyTag.java 2016-04-01 10:54:22 +02:00
David
e7588aeb6a Merge pull request #16 from snaketl/master
Adjusted junit dependency to use only on scope test
2016-04-01 08:31:26 +02:00
Luiz Henrique Feltes
074aae4609 Adjusted junit dependency to use only on scope test 2016-03-31 21:10:17 -03:00
Arne Zelasko
66479f52c5 Update ContainerTag.java 2016-03-31 12:54:47 +02:00
Arne Zelasko
a5e79b536d Update Attr.java 2016-03-31 12:52:50 +02:00
tipsy
79e062355e Bump closure 2015-12-18 12:44:10 +01:00
David
947f12d5a1 Update README.md 2015-11-22 17:03:17 +01:00
tipsy
a46ba46bda Dat newline again 2015-11-22 16:39:41 +01:00
tipsy
41da131bbc Dat newline 2015-11-22 16:38:22 +01:00
tipsy
9428bf7397 Dat travis 2015-11-22 16:37:41 +01:00
tipsy
67e1c887b8 Formatting 2015-11-07 01:02:55 +01:00
David
bdd8dcbd2c Merge pull request #9 from ronanlg/master
Enable developpment under Linux and with Eclipse
2015-11-07 00:59:47 +01:00
RaG
b9d1f3a74d make end of line in test more independent from the OS 2015-11-06 20:56:00 +01:00
RaG
530565c9df add ignore rules specific to eclipse 2015-11-06 20:55:15 +01:00
David
30d1331c28 Update README.md 2015-10-25 11:45:11 +01:00
tipsy
58b2444ed4 [maven-release-plugin] prepare for next development iteration 2015-10-24 14:36:58 +02:00
24 changed files with 1169 additions and 675 deletions

5
.gitignore vendored
View File

@@ -93,4 +93,9 @@ pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
### Eclipse ###
.classpath
.project
.settings/
buildNumber.properties

8
.travis.yml Normal file
View File

@@ -0,0 +1,8 @@
language: java
jdk:
- oraclejdk8
sudo: false
addons:
apt:
packages:
- oracle-java8-installer

View File

@@ -1,7 +1,11 @@
![](https://img.shields.io/travis/tipsy/j2html.svg)
![](https://img.shields.io/github/license/tipsy/j2html.svg)
![](https://img.shields.io/maven-central/v/com.j2html/j2html.svg)
# j2html
Java to HTML generator. Enjoy typesafe HTML generation.
The project webpage is [j2html.com](http://j2html.com)
The project webpage is [j2html.com](http://j2html.com).
##Getting started
###Add the maven dependency
@@ -9,7 +13,7 @@ The project webpage is [j2html.com](http://j2html.com)
<dependency>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>0.5.0</version>
<version>0.7</version>
</dependency>
```

22
pom.xml
View File

@@ -10,7 +10,7 @@
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>0.7</version>
<version>0.88</version>
<name>j2html</name>
<description>Java to HTML builder with a fluent API</description>
@@ -44,16 +44,13 @@
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>com.google.javascript</groupId>
<artifactId>closure-compiler</artifactId>
<version>r2388</version>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -66,8 +63,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>1.8</source>
<target>1.8</target>
<optimize>true</optimize>
</configuration>
</plugin>
@@ -84,7 +81,7 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[1.7,)</version>
<version>[1.8,)</version>
</requireJavaVersion>
</rules>
</configuration>
@@ -99,7 +96,6 @@
</configuration>
</plugin>
</plugins>
</build>
<profiles>

View File

@@ -1,24 +1,79 @@
package j2html;
import j2html.tags.*;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import j2html.tags.ContainerTag;
import j2html.tags.DomContent;
import j2html.tags.EmptyTag;
import j2html.tags.InlineStaticResource;
import j2html.tags.Text;
import j2html.tags.UnescapedText;
public class TagCreator {
private TagCreator() {}
/**
* Creates a DomContent object containing HTML using a mapping function on a collection
* Intended usage: {@literal each(numbers, n -> li(n.toString()))}
*
* @param <T> The derived generic parameter type
* @param collection the collection to iterate over, ex: a list of values "1, 2, 3"
* @param mapper the mapping function, ex: {@literal "n -> li(n.toString())"}
* @return rawHtml containing mapped data {@literal (ex. docs: <li>1</li><li>2</li><li>3</li>)}
*/
public static <T> DomContent each(Collection<T> collection, Function<? super T, DomContent> mapper) {
return rawHtml(collection.stream().map(mapper.andThen(DomContent::render)).collect(Collectors.joining()));
}
/**
* Filters a collection to a list, to be used with {@link j2html.TagCreator#each}
* Intended usage: {@literal each(filter(numbers, n -> n % 2 == 0), n -> li(n.toString()))}
*
* @param <T> The derived generic parameter type
* @param collection the collection to filter, ex: a list of values "1, 2, 3"
* @param filter the filter predicate, {@literal ex: "n -> n % 2 == 0"}
* @return the filtered collection as a list (ex. docs: 2)
*/
public static <T> List<T> filter(Collection<T> collection, Predicate<? super T> filter) {
return collection.stream().filter(filter).collect(Collectors.toList());
}
/**
* Wraps a String in an UnescapedText element
*
* @param html the input html
* @return the input html wrapped in an UnescapedText element
*/
public static UnescapedText rawHtml(String html) {
return new UnescapedText(html);
}
/**
* Wraps a String in a Text element (does html-escaping)
*
* @param text the input string
* @return the input string, html-escaped
*/
public static Text text(String text) {
return new Text(text);
}
//Special tags
public static ContainerTag tag(String tagName) { return new ContainerTag(tagName); }
public static EmptyTag emptyTag(String tagName) { return new EmptyTag(tagName); }
public static Text text(String text) { return new Text(text); }
public static UnescapedText unsafeHtml(String html) { return new UnescapedText(html); }
public static Tag styleWithInlineFile(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.CSS); }
public static Tag scriptWithInlineFile(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.JS); }
public static Tag styleWithInlineFile_min(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.CSS_MIN); }
public static Tag scriptWithInlineFile_min(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.JS_MIN); }
public static UnescapedText fileAsString(String path) { return new UnescapedText(InlineStaticResource.getFileAsString(path)); }
public static Text fileAsEscapedString(String path) { return new Text(InlineStaticResource.getFileAsString(path)); }
public static Text fileAsEscapedString(String path) { return text(InlineStaticResource.getFileAsString(path)); }
public static UnescapedText fileAsString(String path) { return rawHtml(InlineStaticResource.getFileAsString(path)); }
public static ContainerTag styleWithInlineFile(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.CSS); }
public static ContainerTag scriptWithInlineFile(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.JS); }
public static ContainerTag styleWithInlineFile_min(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.CSS_MIN); }
public static ContainerTag scriptWithInlineFile_min(String path) { return InlineStaticResource.get(path, InlineStaticResource.TargetFormat.JS_MIN); }
//EmptyTags
public static EmptyTag area() { return new EmptyTag("area"); }

View File

@@ -1,114 +1,119 @@
package j2html.attributes;
public class Attr {
public static String HIDDEN = "hidden";
public static String HIGH = "high";
public static String HREF = "href";
public static String HREFLANG = "hreflang";
public static String HTTP_EQUIV = "http-equiv";
public static String ICON = "icon";
public static String ID = "id";
public static String ISMAP = "ismap";
public static String ITEMPROP = "itemprop";
public static String KEYTYPE = "keytype";
public static String KIND = "kind";
public static String LABEL = "label";
public static String LANG = "lang";
public static String LANGUAGE = "language";
public static String LIST = "list";
public static String LOOP = "loop";
public static String LOW = "low";
public static String MANIFEST = "manifest";
public static String MAX = "max";
public static String MAXLENGTH = "maxlength";
public static String MEDIA = "media";
public static String METHOD = "method";
public static String MIN = "min";
public static String MULTIPLE = "multiple";
public static String NAME = "name";
public static String NOVALIDATE = "novalidate";
public static String OPEN = "open";
public static String OPTIMUM = "optimum";
public static String PATTERN = "pattern";
public static String PING = "ping";
public static String PLACEHOLDER = "placeholder";
public static String POSTER = "poster";
public static String PRELOAD = "preload";
public static String PUBDATE = "pubdate";
public static String RADIOGROUP = "radiogroup";
public static String READONLY = "readonly";
public static String REL = "rel";
public static String REQUIRED = "required";
public static String REVERSED = "reversed";
public static String ROWS = "rows";
public static String ROWSPAN = "rowspan";
public static String SANDBOX = "sandbox";
public static String SPELLCHECK = "spellcheck";
public static String SCOPE = "scope";
public static String SCOPED = "scoped";
public static String SEAMLESS = "seamless";
public static String SELECTED = "selected";
public static String SHAPE = "shape";
public static String SIZE = "size";
public static String SIZES = "sizes";
public static String SPAN = "span";
public static String SRC = "src";
public static String SRCDOC = "srcdoc";
public static String SRCLANG = "srclang";
public static String SRCSET = "srcset";
public static String START = "start";
public static String STEP = "step";
public static String STYLE = "style";
public static String SUMMARY = "summary";
public static String TABINDEX = "tabindex";
public static String TARGET = "target";
public static String TITLE = "title";
public static String TYPE = "type";
public static String USEMAP = "usemap";
public static String VALUE = "value";
public static String WIDTH = "width";
public static String WRAP = "wrap";
public static String BORDER = "border";
public static String BUFFERED = "buffered";
public static String CHALLENGE = "challenge";
public static String CHARSET = "charset";
public static String CHECKED = "checked";
public static String CITE = "cite";
public static String CLASS = "class";
public static String COLOR = "color";
public static String COLS = "cols";
public static String COLSPAN = "colspan";
public static String CONTENT = "content";
public static String CONTENTEDITABLE = "contenteditable";
public static String CONTEXTMENU = "contextmenu";
public static String CONTROLS = "controls";
public static String COORDS = "coords";
public static String DATA = "data";
public static String DATETIME = "datetime";
public static String DEFAULT = "default";
public static String DEFER = "defer";
public static String DIR = "dir";
public static String DIRNAME = "dirname";
public static String DISABLED = "disabled";
public static String DOWNLOAD = "download";
public static String DRAGGABLE = "draggable";
public static String DROPZONE = "dropzone";
public static String ENCTYPE = "enctype";
public static String FOR = "for";
public static String FORM = "form";
public static String FORMACTION = "formaction";
public static String HEADERS = "headers";
public static String HEIGHT = "height";
public static String ACCEPT = "accept";
public static String ACCEPT_CHARSET = "accept-charset";
public static String ACCESSKEY = "accesskey";
public static String ACTION = "action";
public static String ALIGN = "align";
public static String ALT = "alt";
public static String ASYNC = "async";
public static String AUTOCOMPLETE = "autocomplete";
public static String AUTOFOCUS = "autofocus";
public static String AUTOPLAY = "autoplay";
public static String AUTOSAVE = "autosave";
private Attr() {
}
public static final String ACCEPT = "accept";
public static final String ACCEPT_CHARSET = "accept-charset";
public static final String ACCESSKEY = "accesskey";
public static final String ACTION = "action";
public static final String ALIGN = "align";
public static final String ALT = "alt";
public static final String ASYNC = "async";
public static final String AUTOCOMPLETE = "autocomplete";
public static final String AUTOFOCUS = "autofocus";
public static final String AUTOPLAY = "autoplay";
public static final String AUTOSAVE = "autosave";
public static final String BORDER = "border";
public static final String BUFFERED = "buffered";
public static final String CHALLENGE = "challenge";
public static final String CHARSET = "charset";
public static final String CHECKED = "checked";
public static final String CITE = "cite";
public static final String CLASS = "class";
public static final String COLOR = "color";
public static final String COLS = "cols";
public static final String COLSPAN = "colspan";
public static final String CONTENT = "content";
public static final String CONTENTEDITABLE = "contenteditable";
public static final String CONTEXTMENU = "contextmenu";
public static final String CONTROLS = "controls";
public static final String COORDS = "coords";
public static final String DATA = "data";
public static final String DATETIME = "datetime";
public static final String DEFAULT = "default";
public static final String DEFER = "defer";
public static final String DIR = "dir";
public static final String DIRNAME = "dirname";
public static final String DISABLED = "disabled";
public static final String DOWNLOAD = "download";
public static final String DRAGGABLE = "draggable";
public static final String DROPZONE = "dropzone";
public static final String ENCTYPE = "enctype";
public static final String FOR = "for";
public static final String FORM = "form";
public static final String FORMACTION = "formaction";
public static final String HEADERS = "headers";
public static final String HEIGHT = "height";
public static final String HIDDEN = "hidden";
public static final String HIGH = "high";
public static final String HREF = "href";
public static final String HREFLANG = "hreflang";
public static final String HTTP_EQUIV = "http-equiv";
public static final String ICON = "icon";
public static final String ID = "id";
public static final String ISMAP = "ismap";
public static final String ITEMPROP = "itemprop";
public static final String KEYTYPE = "keytype";
public static final String KIND = "kind";
public static final String LABEL = "label";
public static final String LANG = "lang";
public static final String LANGUAGE = "language";
public static final String LIST = "list";
public static final String LOOP = "loop";
public static final String LOW = "low";
public static final String MANIFEST = "manifest";
public static final String MAX = "max";
public static final String MAXLENGTH = "maxlength";
public static final String MEDIA = "media";
public static final String METHOD = "method";
public static final String MIN = "min";
public static final String MULTIPLE = "multiple";
public static final String NAME = "name";
public static final String NOVALIDATE = "novalidate";
public static final String OPEN = "open";
public static final String OPTIMUM = "optimum";
public static final String PATTERN = "pattern";
public static final String PING = "ping";
public static final String PLACEHOLDER = "placeholder";
public static final String POSTER = "poster";
public static final String PRELOAD = "preload";
public static final String PUBDATE = "pubdate";
public static final String RADIOGROUP = "radiogroup";
public static final String READONLY = "readonly";
public static final String REL = "rel";
public static final String REQUIRED = "required";
public static final String REVERSED = "reversed";
public static final String ROLE = "role";
public static final String ROWS = "rows";
public static final String ROWSPAN = "rowspan";
public static final String SANDBOX = "sandbox";
public static final String SCOPE = "scope";
public static final String SCOPED = "scoped";
public static final String SEAMLESS = "seamless";
public static final String SELECTED = "selected";
public static final String SHAPE = "shape";
public static final String SIZE = "size";
public static final String SIZES = "sizes";
public static final String SPAN = "span";
public static final String SPELLCHECK = "spellcheck";
public static final String SRC = "src";
public static final String SRCDOC = "srcdoc";
public static final String SRCLANG = "srclang";
public static final String SRCSET = "srcset";
public static final String START = "start";
public static final String STEP = "step";
public static final String STYLE = "style";
public static final String SUMMARY = "summary";
public static final String TABINDEX = "tabindex";
public static final String TARGET = "target";
public static final String TITLE = "title";
public static final String TYPE = "type";
public static final String USEMAP = "usemap";
public static final String VALUE = "value";
public static final String WIDTH = "width";
public static final String WRAP = "wrap";
}

View File

@@ -1,6 +1,7 @@
package j2html.attributes;
import static org.apache.commons.lang3.StringEscapeUtils.*;
import j2html.utils.SimpleEscaper;
public class Attribute {
private String name;
@@ -8,7 +9,7 @@ public class Attribute {
public Attribute(String name, String value) {
this.name = name;
this.value = escapeHtml4(value);
this.value = SimpleEscaper.escape(value);
}
public Attribute(String name) {
@@ -17,9 +18,13 @@ public class Attribute {
}
public String render() {
if (name == null) { return ""; }
if (value == null) { return " "+name; }
return(" "+name+"=\""+value+"\"");
if (name == null) {
return "";
}
if (value == null) {
return " " + name;
}
return (" " + name + "=\"" + value + "\"");
}
@Override

View File

@@ -1,88 +1,105 @@
package j2html.tags;
import j2html.attributes.Attr;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ContainerTag extends Tag {
public class ContainerTag extends Tag<ContainerTag> {
public List<Tag> children;
private List<DomContent> children;
public ContainerTag(String tagType) {
super(tagType);
public ContainerTag(String tagName) {
super(tagName);
this.children = new ArrayList<>();
}
/**
* Appends a tag to the end of this element
* Appends a DomContent-object to the end of this element
*
* @param child tag to be appended
* @param child DomContent-object to be appended
* @return itself for easy chaining
*/
public ContainerTag with(Tag child) {
public ContainerTag with(DomContent child) {
if (this == child) {
throw new Error("Cannot append a tag to itself.");
}
child.setParent(this);
children.add(child);
return this;
}
/**
* Call with-method based on condition
* {@link #with(Tag child)}
* {@link #with(DomContent child)}
*
* @param condition the condition to use
* @param child DomContent-object to be appended if condition met
* @return itself for easy chaining
*/
public ContainerTag condWith(boolean condition, Tag child) {
public ContainerTag condWith(boolean condition, DomContent child) {
return condition ? this.with(child) : this;
}
/**
* Appends a list of tags to the end of this element
* Appends a list of DomContent-objects to the end of this element
*
* @param children tags to be appended
* @param children DomContent-objects to be appended
* @return itself for easy chaining
*/
public ContainerTag with(List<Tag> children) {
public ContainerTag with(Iterable<? extends DomContent> children) {
if (children != null) {
for (Tag child : children) {
for (DomContent child : children) {
this.with(child);
}
}
return this;
}
/**
* Call with-method based on condition
* {@link #with(List children)}
* {@link #with(java.lang.Iterable)}
*
* @param condition the condition to use
* @param children DomContent-objects to be appended if condition met
* @return itself for easy chaining
*/
public ContainerTag condWith(boolean condition, List<Tag> children) {
public ContainerTag condWith(boolean condition, Iterable<? extends DomContent> children) {
return condition ? this.with(children) : this;
}
/**
* Appends the tags to the end of this element
* Appends the DomContent-objects to the end of this element
*
* @param children tags to be appended
* @param children DomContent-objects to be appended
* @return itself for easy chaining
*/
public ContainerTag with(Tag... children) {
for (Tag aChildren : children) {
with(aChildren);
public ContainerTag with(DomContent... children) {
for (DomContent child : children) {
with(child);
}
return this;
}
/**
* Call with-method based on condition
* {@link #with(Tag... children)}
* {@link #with(DomContent... children)}
*
* @param condition the condition to use
* @param children DomContent-objects to be appended if condition met
* @return itself for easy chaining
*/
public ContainerTag condWith(boolean condition, Tag... children) {
public ContainerTag condWith(boolean condition, DomContent... children) {
return condition ? this.with(children) : this;
}
/**
* Appends a text tag to this element
* Appends a Text-object to this element
*
* @param text the text to be appended
* @return itself for easy chaining
@@ -91,34 +108,17 @@ public class ContainerTag extends Tag {
return with(new Text(text));
}
/**
* Sets a custom attribute
* Render the ContainerTag and its children
*
* @param attribute the attribute name
* @param value the attribute value
* @return itself for easy chaining
*/
public ContainerTag attr(String attribute, String value) {
setAttribute(attribute, value);
return this;
}
/**
* Call attr-method based on condition
* {@link #attr(String attribute, String value)}
*/
public ContainerTag condAttr(boolean condition, String attribute, String value) {
return condition ? attr(attribute, value) : this;
}
/**
* Render the tag and its children
* @return the rendered string
*/
@Override
public String render() {
StringBuilder rendered = new StringBuilder(renderOpenTag());
if (children != null && children.size() > 0) {
for (Tag child : children) {
if (children != null && !children.isEmpty()) {
for (DomContent child : children) {
rendered.append(child.render());
}
}
@@ -127,56 +127,14 @@ public class ContainerTag extends Tag {
}
@Override
public String toString() {
return this.render();
public void render(Appendable writer) throws IOException {
writer.append(renderOpenTag());
if (children != null && !children.isEmpty()) {
for (DomContent child : children) {
child.render(writer);
}
}
writer.append(renderCloseTag());
}
/**
* Methods below this point are convenience methods
* that call attr with a predefined attribute.
*/
//TODO: TEST ?
public ContainerTag isAutoComplete() { return attr(Attr.AUTOCOMPLETE, null); }
public ContainerTag isAutoFocus() { return attr(Attr.AUTOFOCUS, null); }
public ContainerTag isHidden() { return attr(Attr.HIDDEN, null); }
public ContainerTag isRequired() { return attr(Attr.REQUIRED, null); }
public ContainerTag withAlt(String alt) { return attr(Attr.ALT, alt); }
public ContainerTag withAction(String action) { return attr(Attr.ACTION, action); }
public ContainerTag withCharset(String charset) { return attr(Attr.CHARSET, charset); }
public ContainerTag withClass(String className) { return attr(Attr.CLASS, className); }
public ContainerTag withContent(String content) { return attr(Attr.CONTENT, content); }
public ContainerTag withHref(String href) { return attr(Attr.HREF, href); }
public ContainerTag withId(String id) { return attr(Attr.ID, id); }
public ContainerTag withData(String dataAttr, String value) { return attr(Attr.DATA + "-" + dataAttr, value); }
public ContainerTag withMethod(String method) { return attr(Attr.METHOD, method); }
public ContainerTag withName(String name) { return attr(Attr.NAME, name); }
public ContainerTag withPlaceholder(String placeholder) { return attr(Attr.PLACEHOLDER, placeholder); }
public ContainerTag withTarget(String target) { return attr(Attr.TARGET, target); }
public ContainerTag withType(String type) { return attr(Attr.TYPE, type); }
public ContainerTag withRel(String rel) { return attr(Attr.REL, rel); }
public ContainerTag withSrc(String src) { return attr(Attr.SRC, src); }
public ContainerTag withValue(String value) { return attr(Attr.VALUE, value); }
public ContainerTag withCondAutoComplete(boolean condition) { return condAttr(condition, Attr.AUTOCOMPLETE, null); }
public ContainerTag withCondAutoFocus(boolean condition) { return condAttr(condition, Attr.AUTOFOCUS, null); }
public ContainerTag withCondHidden(boolean condition) { return condAttr(condition, Attr.HIDDEN, null); }
public ContainerTag withCondRequired(boolean condition) { return condAttr(condition, Attr.REQUIRED, null); }
public ContainerTag withCondAlt(boolean condition, String alt) { return condAttr(condition, Attr.ALT, alt); }
public ContainerTag withCondAction(boolean condition, String action) { return condAttr(condition, Attr.ACTION, action); }
public ContainerTag withCharset(boolean condition, String charset) { return condAttr(condition, Attr.CHARSET, charset); }
public ContainerTag withCondClass(boolean condition, String className) { return condAttr(condition, Attr.CLASS, className); }
public ContainerTag withCondContent(boolean condition, String content) { return condAttr(condition, Attr.CONTENT, content); }
public ContainerTag withCondHref(boolean condition, String href) { return condAttr(condition, Attr.HREF, href); }
public ContainerTag withCondId(boolean condition, String id) { return condAttr(condition, Attr.ID, id); }
public ContainerTag withCondData(boolean condition, String dataAttr, String value) { return condAttr(condition, Attr.DATA + "-" + dataAttr, value); }
public ContainerTag withCondMethod(boolean condition, String method) { return condAttr(condition, Attr.METHOD, method); }
public ContainerTag withCondName(boolean condition, String name) { return condAttr(condition, Attr.NAME, name); }
public ContainerTag withCondPlaceholder(boolean condition, String placeholder) { return condAttr(condition, Attr.PLACEHOLDER, placeholder); }
public ContainerTag withCondTarget(boolean condition, String target) { return condAttr(condition, Attr.TARGET, target); }
public ContainerTag withCondType(boolean condition, String type) { return condAttr(condition, Attr.TYPE, type); }
public ContainerTag withCondRel(boolean condition, String rel) { return condAttr(condition, Attr.REL, rel); }
public ContainerTag withCondSrc(boolean condition, String src) { return condAttr(condition, Attr.SRC, src); }
public ContainerTag withCondValue(boolean condition, String value) { return condAttr(condition, Attr.VALUE, value); }
}

View File

@@ -0,0 +1,18 @@
package j2html.tags;
import java.io.IOException;
public abstract class DomContent {
public abstract String render();
public void render(Appendable writer) throws IOException {
writer.append(render());
}
@Override
public String toString() {
return render();
}
}

View File

@@ -1,94 +1,14 @@
package j2html.tags;
import j2html.attributes.Attr;
import j2html.attributes.Attribute;
public class EmptyTag extends Tag<EmptyTag> {
public class EmptyTag extends Tag {
public EmptyTag(String tagType) {
super(tagType);
}
/**
* Sets a custom attribute
*
* @param attribute the attribute name
* @param value the attribute value
* @return itself for easy chaining
*/
public EmptyTag attr(String attribute, String value) {
setAttribute(attribute, value);
return this;
}
/**
* Call attr-method based on condition
* {@link #attr(String attribute, String value)}
*/
public EmptyTag condAttr(boolean condition, String attribute, String value) {
return condition ? attr(attribute, value) : this;
}
public String render() {
String tagAttributes = "";
for (Attribute attribute : attributes) {
tagAttributes += attribute;
}
return "<" + tag + tagAttributes + ">";
public EmptyTag(String tagName) {
super(tagName);
}
@Override
public String toString() {
return this.render();
public String render() {
return renderOpenTag();
}
/**
* Methods below this point are convenience methods
* that call attr with a predefined attribute.
*/
//TODO: TEST ?
public EmptyTag isAutoComplete() { return attr(Attr.AUTOCOMPLETE, null); }
public EmptyTag isAutoFocus() { return attr(Attr.AUTOFOCUS, null); }
public EmptyTag isHidden() { return attr(Attr.HIDDEN, null); }
public EmptyTag isRequired() { return attr(Attr.REQUIRED, null); }
public EmptyTag withAlt(String alt) { return attr(Attr.ALT, alt); }
public EmptyTag withAction(String action) { return attr(Attr.ACTION, action); }
public EmptyTag withCharset(String charset) { return attr(Attr.CHARSET, charset); }
public EmptyTag withClass(String className) { return attr(Attr.CLASS, className); }
public EmptyTag withContent(String content) { return attr(Attr.CONTENT, content); }
public EmptyTag withHref(String href) { return attr(Attr.HREF, href); }
public EmptyTag withId(String id) { return attr(Attr.ID, id); }
public EmptyTag withData(String dataAttr, String value) { return attr(Attr.DATA + "-" + dataAttr, value); }
public EmptyTag withMethod(String method) { return attr(Attr.METHOD, method); }
public EmptyTag withName(String name) { return attr(Attr.NAME, name); }
public EmptyTag withPlaceholder(String placeholder) { return attr(Attr.PLACEHOLDER, placeholder); }
public EmptyTag withTarget(String target) { return attr(Attr.TARGET, target); }
public EmptyTag withType(String type) { return attr(Attr.TYPE, type); }
public EmptyTag withRel(String rel) { return attr(Attr.REL, rel); }
public EmptyTag withSrc(String src) { return attr(Attr.SRC, src); }
public EmptyTag withValue(String value) { return attr(Attr.VALUE, value); }
public EmptyTag withCondAutoComplete(boolean condition) { return condAttr(condition, Attr.AUTOCOMPLETE, null); }
public EmptyTag withCondAutoFocus(boolean condition) { return condAttr(condition, Attr.AUTOFOCUS, null); }
public EmptyTag withCondHidden(boolean condition) { return condAttr(condition, Attr.HIDDEN, null); }
public EmptyTag withCondRequired(boolean condition) { return condAttr(condition, Attr.REQUIRED, null); }
public EmptyTag withCondAlt(boolean condition, String alt) { return condAttr(condition, Attr.ALT, alt); }
public EmptyTag withCondAction(boolean condition, String action) { return condAttr(condition, Attr.ACTION, action); }
public EmptyTag withCharset(boolean condition, String charset) { return condAttr(condition, Attr.CHARSET, charset); }
public EmptyTag withCondClass(boolean condition, String className) { return condAttr(condition, Attr.CLASS, className); }
public EmptyTag withCondContent(boolean condition, String content) { return condAttr(condition, Attr.CONTENT, content); }
public EmptyTag withCondHref(boolean condition, String href) { return condAttr(condition, Attr.HREF, href); }
public EmptyTag withCondId(boolean condition, String id) { return condAttr(condition, Attr.ID, id); }
public EmptyTag withCondData(boolean condition, String dataAttr, String value) { return condAttr(condition, Attr.DATA + "-" + dataAttr, value); }
public EmptyTag withCondMethod(boolean condition, String method) { return condAttr(condition, Attr.METHOD, method); }
public EmptyTag withCondName(boolean condition, String name) { return condAttr(condition, Attr.NAME, name); }
public EmptyTag withCondPlaceholder(boolean condition, String placeholder) { return condAttr(condition, Attr.PLACEHOLDER, placeholder); }
public EmptyTag withCondTarget(boolean condition, String target) { return condAttr(condition, Attr.TARGET, target); }
public EmptyTag withCondType(boolean condition, String type) { return condAttr(condition, Attr.TYPE, type); }
public EmptyTag withCondRel(boolean condition, String rel) { return condAttr(condition, Attr.REL, rel); }
public EmptyTag withCondSrc(boolean condition, String src) { return condAttr(condition, Attr.SRC, src); }
public EmptyTag withCondValue(boolean condition, String value) { return condAttr(condition, Attr.VALUE, value); }
}

View File

@@ -1,22 +1,28 @@
package j2html.tags;
import j2html.utils.*;
import java.nio.file.*;
import static j2html.TagCreator.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import j2html.utils.CSSMin;
import j2html.utils.JSMin;
import static j2html.TagCreator.script;
import static j2html.TagCreator.style;
import static j2html.TagCreator.rawHtml;
public class InlineStaticResource {
public enum TargetFormat { CSS_MIN, CSS, JS_MIN, JS }
public enum TargetFormat {CSS_MIN, CSS, JS_MIN, JS}
public static ContainerTag get(String path, TargetFormat format) {
ContainerTag errorAlert = script().with(unsafeHtml("alert('Unable to read file. File: \"" + path + "\", Type: \"" + format + "\"')"));
ContainerTag errorAlert = script().with(rawHtml("alert('Unable to read file. File: \"" + path + "\", Type: \"" + format + "\"')"));
String fileString = getFileAsString(path);
if(fileString != null) {
switch(format) {
case CSS_MIN : return style().with(unsafeHtml(compressCss(fileString)));
case JS_MIN : return script().with(unsafeHtml(compressJs(fileString, path)));
case CSS : return style().with(unsafeHtml(fileString));
case JS : return script().with(unsafeHtml(fileString));
case CSS_MIN : return style().with(rawHtml(compressCss(fileString)));
case JS_MIN : return script().with(rawHtml(compressJs(fileString)));
case CSS : return style().with(rawHtml(fileString));
case JS : return script().with(rawHtml(fileString));
default : return errorAlert;
}
}
@@ -35,8 +41,8 @@ public class InlineStaticResource {
return CSSMin.compress(code);
}
private static String compressJs(String code, String debugPath) {
return JSMin.compressJs(code, debugPath);
private static String compressJs(String code) {
return JSMin.compressJs(code);
}
}

View File

@@ -1,31 +1,43 @@
package j2html.tags;
import j2html.attributes.Attribute;
import java.util.ArrayList;
public abstract class Tag {
import j2html.attributes.Attr;
import j2html.attributes.Attribute;
protected String tag;
protected ArrayList<Attribute> attributes;
protected Tag parent;
public abstract class Tag<T extends Tag<T>> extends DomContent {
protected Tag(String tagType) {
this.tag = tagType;
protected String tagName;
private ArrayList<Attribute> attributes;
protected Tag(String tagName) {
this.tagName = tagName;
this.attributes = new ArrayList<>();
}
public void setParent(Tag parent) {
this.parent = parent;
String renderOpenTag() {
StringBuilder sb = new StringBuilder("<").append(tagName);
for (Attribute attribute : attributes) {
sb.append(attribute.render());
}
sb.append(">");
return sb.toString();
}
String renderCloseTag() {
return "</" + tagName + ">";
}
/**
* Sets an attribute on an element
*
* @param name the attribute
* @param value the attribute value
*/
public boolean setAttribute(String name, String value) {
boolean setAttribute(String name, String value) {
if (value == null) {
return attributes.add(new Attribute(name));
}
@@ -38,25 +50,90 @@ public abstract class Tag {
return attributes.add(new Attribute(name, value));
}
public String render() {
return renderOpenTag() + renderCloseTag();
/**
* Sets a custom attribute
*
* @param attribute the attribute name
* @param value the attribute value
* @return itself for easy chaining
*/
public T attr(String attribute, String value) {
setAttribute(attribute, value);
return (T) this;
}
/**
* Call attr-method based on condition
* {@link #attr(String attribute, String value)}
*
* @param condition the condition
* @param attribute the attribute name
* @param value the attribute value
* @return itself for easy chaining
*/
public T condAttr(boolean condition, String attribute, String value) {
return (condition ? attr(attribute, value) : (T) this);
}
@Override
public String toString() {
return this.render();
}
public String renderOpenTag() {
String tagAttributes = "";
for (Attribute attribute : attributes) {
tagAttributes += attribute.render();
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Tag)) {
return false;
}
return "<" + tag + tagAttributes + ">";
return ((Tag) obj).render().equals(this.render());
}
public String renderCloseTag() {
return "</" + tag + ">";
}
/**
* Convenience methods that call attr with predefined attributes
* @return itself for easy chaining
*/
public T isAutoComplete() { return attr(Attr.AUTOCOMPLETE, null); }
public T isAutoFocus() { return attr(Attr.AUTOFOCUS, null); }
public T isHidden() { return attr(Attr.HIDDEN, null); }
public T isRequired() { return attr(Attr.REQUIRED, null); }
public T withAlt(String alt) { return attr(Attr.ALT, alt); }
public T withAction(String action) { return attr(Attr.ACTION, action); }
public T withCharset(String charset) { return attr(Attr.CHARSET, charset); }
public T withClass(String className) { return attr(Attr.CLASS, className); }
public T withContent(String content) { return attr(Attr.CONTENT, content); }
public T withHref(String href) { return attr(Attr.HREF, href); }
public T withId(String id) { return attr(Attr.ID, id); }
public T withData(String dataAttr, String value) { return attr(Attr.DATA + "-" + dataAttr, value); }
public T withMethod(String method) { return attr(Attr.METHOD, method); }
public T withName(String name) { return attr(Attr.NAME, name); }
public T withPlaceholder(String placeholder) { return attr(Attr.PLACEHOLDER, placeholder); }
public T withTarget(String target) { return attr(Attr.TARGET, target); }
public T withType(String type) { return attr(Attr.TYPE, type); }
public T withRel(String rel) { return attr(Attr.REL, rel); }
public T withRole(String role) { return attr(Attr.ROLE, role); }
public T withSrc(String src) { return attr(Attr.SRC, src); }
public T withStyle(String style) { return attr(Attr.STYLE, style); }
public T withValue(String value) { return attr(Attr.VALUE, value); }
public T withCondAutoComplete(boolean condition) { return condAttr(condition, Attr.AUTOCOMPLETE, null); }
public T withCondAutoFocus(boolean condition) { return condAttr(condition, Attr.AUTOFOCUS, null); }
public T withCondHidden(boolean condition) { return condAttr(condition, Attr.HIDDEN, null); }
public T withCondRequired(boolean condition) { return condAttr(condition, Attr.REQUIRED, null); }
public T withCondAlt(boolean condition, String alt) { return condAttr(condition, Attr.ALT, alt); }
public T withCondAction(boolean condition, String action) { return condAttr(condition, Attr.ACTION, action); }
public T withCharset(boolean condition, String charset) { return condAttr(condition, Attr.CHARSET, charset); }
public T withCondClass(boolean condition, String className) { return condAttr(condition, Attr.CLASS, className); }
public T withCondContent(boolean condition, String content) { return condAttr(condition, Attr.CONTENT, content); }
public T withCondHref(boolean condition, String href) { return condAttr(condition, Attr.HREF, href); }
public T withCondId(boolean condition, String id) { return condAttr(condition, Attr.ID, id); }
public T withCondData(boolean condition, String dataAttr, String value) { return condAttr(condition, Attr.DATA + "-" + dataAttr, value); }
public T withCondMethod(boolean condition, String method) { return condAttr(condition, Attr.METHOD, method); }
public T withCondName(boolean condition, String name) { return condAttr(condition, Attr.NAME, name); }
public T withCondPlaceholder(boolean condition, String placeholder) { return condAttr(condition, Attr.PLACEHOLDER, placeholder); }
public T withCondTarget(boolean condition, String target) { return condAttr(condition, Attr.TARGET, target); }
public T withCondType(boolean condition, String type) { return condAttr(condition, Attr.TYPE, type); }
public T withCondRel(boolean condition, String rel) { return condAttr(condition, Attr.REL, rel); }
public T withCondSrc(boolean condition, String src) { return condAttr(condition, Attr.SRC, src); }
public T withCondStyle(boolean condition, String style) { return condAttr(condition, Attr.STYLE, style); }
public T withCondValue(boolean condition, String value) { return condAttr(condition, Attr.VALUE, value); }
}

View File

@@ -1,21 +1,18 @@
package j2html.tags;
import static org.apache.commons.lang3.StringEscapeUtils.*;
import j2html.utils.SimpleEscaper;
public class Text extends Tag {
public class Text extends DomContent {
private String text;
public Text(String text) {
super(text);
this.text = text;
}
@Override
public String render() {
return escapeHtml4(tag);
}
@Override
public String toString() {
return this.render();
return SimpleEscaper.escape(text);
}
}

View File

@@ -1,19 +1,16 @@
package j2html.tags;
public class UnescapedText extends Tag {
public class UnescapedText extends DomContent {
private String text;
public UnescapedText(String text) {
super(text);
this.text = text;
}
@Override
public String render() {
return tag;
}
@Override
public String toString() {
return this.render();
return text;
}
}

View File

@@ -1,27 +1,27 @@
/**
* * CSSMin Copyright License Agreement (BSD License)
*
* <p>
* Copyright (c) 2011-2014, Barry van Oudtshoorn
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* <p>
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* <p>
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* <p>
* - Neither the name of Barryvan nor the names of its
* contributors may be used to endorse or promote products
* derived from this software without specific prior
* written permission.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,17 +33,17 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* <p>
* CSSMin takes in well-formed, human-readable CSS and reduces its size substantially.
* It removes unnecessary whitespace and comments, and orders the contents of CSS
* selectors alphabetically to enhance GZIP compression.
*
* <p>
* Originally by Barry van Oudtshoorn, with bug reports, fixes, and contributions by
* <ul>
* <li>Kevin de Groote</li>
* <li>Pedro Pinheiro</li>
* <li>Asier Lostalé</li>
* <li>David Åse</li>
* <li>Kevin de Groote</li>
* <li>Pedro Pinheiro</li>
* <li>Asier Lostalé</li>
* <li>David Åse</li>
* </ul>
* Some code is based on the YUI CssCompressor code, by Julien Lecomte.
*
@@ -53,27 +53,37 @@
package j2html.utils;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import java.util.regex.*;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class CSSMin {
private CSSMin() {
}
private static final Logger LOG = Logger.getLogger(CSSMin.class.getName());
protected static boolean debugLogging = false;
static boolean debugLogging = false;
/**
* Minify CSS from a reader to a printstream.
* Minify supplied CSS.
*
* @param input Where to read the CSS from
* @param input the CSS
* @return the compressed version
*/
public static String compress(String input) {
try {
int k,
j, // Number of open braces
n; // Current position in stream
j, // Number of open braces
n; // Current position in stream
char curr;
BufferedReader br = new BufferedReader(new StringReader(input));
@@ -84,7 +94,9 @@ public class CSSMin {
}
String s;
while ((s = br.readLine()) != null) {
if (s.trim().equals("")) continue;
if (s.trim().equals("")) {
continue;
}
sb.append(s);
}
@@ -178,7 +190,7 @@ class Selector {
* @param selector The selector; for example, "div { border: solid 1px red; color: blue; }"
* @throws IncompleteSelectorException, UnterminatedSelectorException, EmptySelectorBodyException If the selector is incomplete and cannot be parsed.
*/
public Selector(String selector) throws IncompleteSelectorException, UnterminatedSelectorException, EmptySelectorBodyException {
Selector(String selector) throws IncompleteSelectorException, UnterminatedSelectorException, EmptySelectorBodyException {
String[] parts = selector.split("\\{"); // We have to escape the { with a \ for the regex, which itself requires escaping for the string. Sigh.
if (parts.length < 2) {
throw new IncompleteSelectorException(selector);
@@ -189,7 +201,6 @@ class Selector {
// Simplify combinators
this.selector = this.selector.replaceAll("\\s?(\\+|~|,|=|~=|\\^=|\\$=|\\*=|\\|=|>)\\s?", "$1");
// We're dealing with a nested property, eg @-webkit-keyframes
if (parts.length > 2) {
this.subSelectors = new Vector<>();
@@ -266,15 +277,21 @@ class Selector {
} else if (contents.charAt(i) == '"') {
bInsideString = true;
} else if (contents.charAt(i) == '(') {
if ((i - 3) > 0 && "url".equals(contents.substring(i - 3, i))) bInsideURL = true;
if ((i - 3) > 0 && "url".equals(contents.substring(i - 3, i))) {
bInsideURL = true;
}
} else if (contents.charAt(i) == ';') {
substr = contents.substring(j, i);
if (!(substr.trim().equals(""))) parts.add(substr);
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
j = i + 1;
}
}
substr = contents.substring(j, contents.length());
if (!(substr.trim().equals(""))) parts.add(substr);
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
ArrayList<Property> results = new ArrayList<>();
for (String part : parts) {
@@ -302,8 +319,8 @@ class Property implements Comparable<Property> {
private static final Logger LOG = Logger.getLogger(Property.class.getName());
protected String property;
protected Part[] parts;
private String property;
private Part[] parts;
/**
* Creates a new Property using the supplied strings. Parses out the values of the property selector.
@@ -311,7 +328,7 @@ class Property implements Comparable<Property> {
* @param property The property; for example, "border: solid 1px red;" or "-moz-box-shadow: 3px 3px 3px rgba(255, 255, 0, 0.5);".
* @throws IncompletePropertyException If the property is incomplete and cannot be parsed.
*/
public Property(String property) throws IncompletePropertyException {
Property(String property) throws IncompletePropertyException {
try {
// Parse the property.
ArrayList<String> parts = new ArrayList<>();
@@ -326,14 +343,18 @@ class Property implements Comparable<Property> {
bCanSplit = (property.charAt(i) == '"');
} else if (property.charAt(i) == '"') {
bCanSplit = false;
} else if (property.charAt(i) == ':' && parts.size() < 1) {
} else if (property.charAt(i) == ':' && parts.isEmpty()) {
substr = property.substring(j, i);
if (!(substr.trim().equals(""))) parts.add(substr);
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
j = i + 1;
}
}
substr = property.substring(j, property.length());
if (!(substr.trim().equals(""))) parts.add(substr);
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
if (parts.size() < 2) {
throw new IncompletePropertyException(property);
}
@@ -375,24 +396,17 @@ class Property implements Comparable<Property> {
*/
public int compareTo(Property other) {
// We can't just use String.compareTo(), because we need to sort properties that have hack prefixes last -- eg, *display should come after display.
String thisProp = this.property;
String thatProp = other.property;
return sort(this.property).compareTo(sort(other.property));
}
private String sort(String thisProp) {
if (thisProp.charAt(0) == '-') {
thisProp = thisProp.substring(1);
thisProp = thisProp.substring(thisProp.indexOf('-') + 1);
} else if (thisProp.charAt(0) < 65) {
thisProp = thisProp.substring(1);
}
if (thatProp.charAt(0) == '-') {
thatProp = thatProp.substring(1);
thatProp = thatProp.substring(thatProp.indexOf('-') + 1);
} else if (thatProp.charAt(0) < 65) {
thatProp = thatProp.substring(1);
}
return thisProp.compareTo(thatProp);
return thisProp;
}
/**
@@ -456,8 +470,8 @@ class Property implements Comparable<Property> {
}
class Part {
String contents;
String property;
private String contents;
private String property;
/**
* Create a new property by parsing the given string.
@@ -465,7 +479,7 @@ class Part {
* @param contents The string to parse.
* @throws Exception If the part cannot be parsed.
*/
public Part(String contents, String property) throws Exception {
Part(String contents, String property) throws Exception {
// Many of these regular expressions are adapted from those used in the YUI CSS Compressor.
// For simpler regexes.
@@ -486,9 +500,15 @@ class Part {
this.contents = this.contents.trim();
// Simplify multiple zeroes
if (this.contents.equals("0 0 0 0")) this.contents = "0";
if (this.contents.equals("0 0 0")) this.contents = "0";
if (this.contents.equals("0 0")) this.contents = "0";
if (this.contents.equals("0 0 0 0")) {
this.contents = "0";
}
if (this.contents.equals("0 0 0")) {
this.contents = "0";
}
if (this.contents.equals("0 0")) {
this.contents = "0";
}
// Simplify multiple-parameter properties
simplifyParameters();
@@ -505,31 +525,27 @@ class Part {
}
private void simplifyParameters() {
if (this.property.equals("background-size")) return;
if (this.property.equals("background-size")) {
return;
}
StringBuilder newContents = new StringBuilder();
String[] params = this.contents.split(" ");
if (params.length == 4) {
if (params.length == 4 && params[1].equalsIgnoreCase(params[3])) {
// We can drop off the fourth item if the second and fourth items match
// ie turn 3px 0 3px 0 into 3px 0 3px
if (params[1].equalsIgnoreCase(params[3])) {
params = Arrays.copyOf(params, 3);
}
params = Arrays.copyOf(params, 3);
}
if (params.length == 3) {
if (params.length == 3 && params[0].equalsIgnoreCase(params[2])) {
// We can drop off the third item if the first and third items match
// ie turn 3px 0 3px into 3px 0
if (params[0].equalsIgnoreCase(params[2])) {
params = Arrays.copyOf(params, 2);
}
params = Arrays.copyOf(params, 2);
}
if (params.length == 2) {
if (params.length == 2 && params[0].equalsIgnoreCase(params[1])) {
// We can drop off the second item if the first and second items match
// ie turn 3px 3px into 3px
if (params[0].equalsIgnoreCase(params[1])) {
params = Arrays.copyOf(params, 1);
}
params = Arrays.copyOf(params, 1);
}
for (String param : params) {
@@ -541,7 +557,9 @@ class Part {
}
private void simplifyFontWeights() {
if (!this.property.equals("font-weight")) return;
if (!this.property.equals("font-weight")) {
return;
}
String lcContents = this.contents.toLowerCase();
@@ -615,14 +633,16 @@ class Part {
}
}
class UnterminatedCommentException extends Exception {}
class UnterminatedCommentException extends Exception {
}
class UnbalancedBracesException extends Exception {}
class UnbalancedBracesException extends Exception {
}
class IncompletePropertyException extends Exception {
String message = null;
private final String message;
public IncompletePropertyException(String message) {
IncompletePropertyException(String message) {
this.message = message;
}
@@ -632,9 +652,9 @@ class IncompletePropertyException extends Exception {
}
class EmptySelectorBodyException extends Exception {
String message = null;
private final String message;
public EmptySelectorBodyException(String message) {
EmptySelectorBodyException(String message) {
this.message = message;
}
@@ -644,9 +664,9 @@ class EmptySelectorBodyException extends Exception {
}
class UnterminatedSelectorException extends Exception {
String message = null;
private final String message;
public UnterminatedSelectorException(String message) {
UnterminatedSelectorException(String message) {
this.message = message;
}
@@ -656,9 +676,9 @@ class UnterminatedSelectorException extends Exception {
}
class IncompleteSelectorException extends Exception {
String message = null;
private final String message;
public IncompleteSelectorException(String message) {
IncompleteSelectorException(String message) {
this.message = message;
}
@@ -668,8 +688,8 @@ class IncompleteSelectorException extends Exception {
}
class Constants {
static final String[] htmlColourNames = { "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", "indianred ", "indigo ", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgrey", "lightgreen", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen" };
static final String[] htmlColourValues = { "#f0f8ff", "#faebd7", "#00ffff", "#7fffd4", "#f0ffff", "#f5f5dc", "#ffe4c4", "#000", "#ffebcd", "#00f", "#8a2be2", "#a52a2a", "#deb887", "#5f9ea0", "#7fff00", "#d2691e", "#ff7f50", "#6495ed", "#fff8dc", "#dc143c", "#0ff", "#00008b", "#008b8b", "#b8860b", "#a9a9a9", "#006400", "#bdb76b", "#8b008b", "#556b2f", "#ff8c00", "#9932cc", "#8b0000", "#e9967a", "#8fbc8f", "#483d8b", "#2f4f4f", "#00ced1", "#9400d3", "#ff1493", "#00bfff", "#696969", "#1e90ff", "#b22222", "#fffaf0", "#228b22", "#f0f", "#dcdcdc", "#f8f8ff", "#ffd700", "#daa520", "#808080", "#008000", "#adff2f", "#f0fff0", "#ff69b4", "#cd5c5c", "#4b0082", "#fffff0", "#f0e68c", "#e6e6fa", "#fff0f5", "#7cfc00", "#fffacd", "#add8e6", "#f08080", "#e0ffff", "#fafad2", "#d3d3d3", "#90ee90", "#ffb6c1", "#ffa07a", "#20b2aa", "#87cefa", "#789", "#b0c4de", "#ffffe0", "#0f0", "#32cd32", "#faf0e6", "#f0f", "#800000", "#66cdaa", "#0000cd", "#ba55d3", "#9370d8", "#3cb371", "#7b68ee", "#00fa9a", "#48d1cc", "#c71585", "#191970", "#f5fffa", "#ffe4e1", "#ffe4b5", "#ffdead", "#000080", "#fdf5e6", "#808000", "#6b8e23", "#ffa500", "#ff4500", "#da70d6", "#eee8aa", "#98fb98", "#afeeee", "#d87093", "#ffefd5", "#ffdab9", "#cd853f", "#ffc0cb", "#dda0dd", "#b0e0e6", "#800080", "#f00", "#bc8f8f", "#4169e1", "#8b4513", "#fa8072", "#f4a460", "#2e8b57", "#fff5ee", "#a0522d", "#c0c0c0", "#87ceeb", "#6a5acd", "#708090", "#fffafa", "#00ff7f", "#4682b4", "#d2b48c", "#008080", "#d8bfd8", "#ff6347", "#40e0d0", "#ee82ee", "#f5deb3", "#fff", "#f5f5f5", "#ff0", "#9acd32" };
static final String[] fontWeightNames = { "normal", "bold", "bolder", "lighter" };
static final String[] fontWeightValues = { "400", "700", "900", "100" };
static final String[] htmlColourNames = {"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", "indianred ", "indigo ", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgrey", "lightgreen", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen"};
static final String[] htmlColourValues = {"#f0f8ff", "#faebd7", "#00ffff", "#7fffd4", "#f0ffff", "#f5f5dc", "#ffe4c4", "#000", "#ffebcd", "#00f", "#8a2be2", "#a52a2a", "#deb887", "#5f9ea0", "#7fff00", "#d2691e", "#ff7f50", "#6495ed", "#fff8dc", "#dc143c", "#0ff", "#00008b", "#008b8b", "#b8860b", "#a9a9a9", "#006400", "#bdb76b", "#8b008b", "#556b2f", "#ff8c00", "#9932cc", "#8b0000", "#e9967a", "#8fbc8f", "#483d8b", "#2f4f4f", "#00ced1", "#9400d3", "#ff1493", "#00bfff", "#696969", "#1e90ff", "#b22222", "#fffaf0", "#228b22", "#f0f", "#dcdcdc", "#f8f8ff", "#ffd700", "#daa520", "#808080", "#008000", "#adff2f", "#f0fff0", "#ff69b4", "#cd5c5c", "#4b0082", "#fffff0", "#f0e68c", "#e6e6fa", "#fff0f5", "#7cfc00", "#fffacd", "#add8e6", "#f08080", "#e0ffff", "#fafad2", "#d3d3d3", "#90ee90", "#ffb6c1", "#ffa07a", "#20b2aa", "#87cefa", "#789", "#b0c4de", "#ffffe0", "#0f0", "#32cd32", "#faf0e6", "#f0f", "#800000", "#66cdaa", "#0000cd", "#ba55d3", "#9370d8", "#3cb371", "#7b68ee", "#00fa9a", "#48d1cc", "#c71585", "#191970", "#f5fffa", "#ffe4e1", "#ffe4b5", "#ffdead", "#000080", "#fdf5e6", "#808000", "#6b8e23", "#ffa500", "#ff4500", "#da70d6", "#eee8aa", "#98fb98", "#afeeee", "#d87093", "#ffefd5", "#ffdab9", "#cd853f", "#ffc0cb", "#dda0dd", "#b0e0e6", "#800080", "#f00", "#bc8f8f", "#4169e1", "#8b4513", "#fa8072", "#f4a460", "#2e8b57", "#fff5ee", "#a0522d", "#c0c0c0", "#87ceeb", "#6a5acd", "#708090", "#fffafa", "#00ff7f", "#4682b4", "#d2b48c", "#008080", "#d8bfd8", "#ff6347", "#40e0d0", "#ee82ee", "#f5deb3", "#fff", "#f5f5f5", "#ff0", "#9acd32"};
static final String[] fontWeightNames = {"normal", "bold", "bolder", "lighter"};
static final String[] fontWeightValues = {"400", "700", "900", "100"};
}

View File

@@ -1,18 +1,305 @@
package j2html.utils;
/*
* JSMin.java 2006-02-13
*
* Copyright (c) 2006 John Reilly (www.inconspicuous.org)
*
* This work is a translation from C to Java of jsmin.c published by
* Douglas Crockford. Permission is hereby granted to use the Java
* version under the same conditions as the jsmin.c on which it is
* based.
*
*
*
*
* jsmin.c 2003-04-21
*
* Copyright (c) 2002 Douglas Crockford (www.crockford.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* The Software shall be used for Good, not Evil.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// package org.inconspicuous.jsmin;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import com.google.javascript.jscomp.*;
import com.google.javascript.jscomp.Compiler;
public class JSMin {
public static String compressJs(String code, String sourcePath) {
com.google.javascript.jscomp.Compiler compiler = new Compiler();
CompilerOptions options = new CompilerOptions();
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
SourceFile extern = SourceFile.fromCode("externs.js", "");
SourceFile input = SourceFile.fromCode(sourcePath, code);
compiler.compile(extern, input, options);
return compiler.toSource();
/**
* Compress a JS-string
*
* @param code the js-code you want to compress
* @return the compressed code
*/
public static String compressJs(String code) {
InputStream inStream = new ByteArrayInputStream(code.getBytes());
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
JSMin jsmin = new JSMin(inStream, outStream);
try {
jsmin.jsmin();
return outStream.toString().trim();
} catch (IOException | UnterminatedRegExpLiteralException | UnterminatedCommentException | UnterminatedStringLiteralException e) {
e.printStackTrace();
return "";
}
}
}
private static final int EOF = -1;
private PushbackInputStream in;
private OutputStream out;
private int theA;
private int theB;
private JSMin(InputStream in, OutputStream out) {
this.in = new PushbackInputStream(in);
this.out = out;
}
/**
* isAlphanum -- return true if the character is a letter, digit,
* underscore, dollar sign, or non-ASCII character.
*/
private static boolean isAlphanum(int c) {
return ((c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'Z') ||
c == '_' ||
c == '$' ||
c == '\\' ||
c > 126);
}
/**
* get -- return the next character from stdin. Watch out for lookahead. If
* the character is a control character, translate it to a space or
* linefeed.
*/
private int get() throws IOException {
int c = in.read();
if (c >= ' ' || c == '\n' || c == EOF) {
return c;
}
if (c == '\r') {
return '\n';
}
return ' ';
}
/**
* Get the next character without getting it.
*/
private int peek() throws IOException {
int lookaheadChar = in.read();
in.unread(lookaheadChar);
return lookaheadChar;
}
/**
* next -- get the next character, excluding comments. peek() is used to see
* if a '/' is followed by a '/' or '*'.
*/
private int next() throws IOException, UnterminatedCommentException {
int c = get();
if (c == '/') {
switch (peek()) {
case '/':
for (; ; ) {
c = get();
if (c <= '\n') {
return c;
}
}
case '*':
get();
for (; ; ) {
switch (get()) {
case '*':
if (peek() == '/') {
get();
return ' ';
}
break;
case EOF:
throw new UnterminatedCommentException();
}
}
default:
return c;
}
}
return c;
}
/**
* action -- do something! What you do is determined by the argument: 1
* Output A. Copy B to A. Get the next B. 2 Copy B to A. Get the next B.
* (Delete A). 3 Get the next B. (Delete B). action treats a string as a
* single character. Wow! action recognizes a regular expression if it is
* preceded by ( or , or =.
*/
private void action(int d) throws IOException, UnterminatedRegExpLiteralException,
UnterminatedCommentException, UnterminatedStringLiteralException {
switch (d) {
case 1:
out.write(theA);
case 2:
theA = theB;
if (theA == '\'' || theA == '"') {
for (; ; ) {
out.write(theA);
theA = get();
if (theA == theB) {
break;
}
if (theA <= '\n') {
throw new UnterminatedStringLiteralException();
}
if (theA == '\\') {
out.write(theA);
theA = get();
}
}
}
case 3:
theB = next();
if (theB == '/' && (theA == '(' || theA == ',' || theA == '=')) {
out.write(theA);
out.write(theB);
for (; ; ) {
theA = get();
if (theA == '/') {
break;
} else if (theA == '\\') {
out.write(theA);
theA = get();
} else if (theA <= '\n') {
throw new UnterminatedRegExpLiteralException();
}
out.write(theA);
}
theB = next();
}
}
}
/**
* jsmin -- Copy the input to the output, deleting the characters which are
* insignificant to JavaScript. Comments will be removed. Tabs will be
* replaced with spaces. Carriage returns will be replaced with linefeeds.
* Most spaces and linefeeds will be removed.
*/
public void jsmin() throws IOException, UnterminatedRegExpLiteralException, UnterminatedCommentException, UnterminatedStringLiteralException {
theA = '\n';
action(3);
while (theA != EOF) {
switch (theA) {
case ' ':
if (isAlphanum(theB)) {
action(1);
} else {
action(2);
}
break;
case '\n':
switch (theB) {
case '{':
case '[':
case '(':
case '+':
case '-':
action(1);
break;
case ' ':
action(3);
break;
default:
if (isAlphanum(theB)) {
action(1);
} else {
action(2);
}
}
break;
default:
switch (theB) {
case ' ':
if (isAlphanum(theA)) {
action(1);
break;
}
action(3);
break;
case '\n':
switch (theA) {
case '}':
case ']':
case ')':
case '+':
case '-':
case '"':
case '\'':
action(1);
break;
default:
if (isAlphanum(theA)) {
action(1);
} else {
action(3);
}
}
break;
default:
action(1);
break;
}
}
}
out.flush();
}
private class UnterminatedCommentException extends Exception {
}
private class UnterminatedStringLiteralException extends Exception {
}
private class UnterminatedRegExpLiteralException extends Exception {
}
}

View File

@@ -0,0 +1,28 @@
package j2html.utils;
import java.util.HashMap;
import java.util.Map;
public class SimpleEscaper {
private static Map<Character, String> map = new HashMap<Character, String>() {{
put('&', "&amp;");
put('<', "&lt;");
put('>', "&gt;");
put('"', "&quot;");
put('\'', "&#x27;");
}};
public static String escape(String s) {
if(s == null) {
return null;
}
String escapedString = "";
for(char c : s.toCharArray()) {
String escaped = map.get(c);
escapedString += escaped != null ? escaped : c;
}
return escapedString;
}
}

View File

@@ -1,30 +1,32 @@
package j2html.attributes;
import j2html.tags.ContainerTag;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import j2html.tags.ContainerTag;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class AttributeTest {
@Test
public void testRender() throws Exception {
Attribute attributeWithValue = new Attribute("href", "http://example.com");
assertEquals(attributeWithValue.render(), " href=\"http://example.com\"");
assertThat(attributeWithValue.render(), is(" href=\"http://example.com\""));
Attribute attribute = new Attribute("required", null);
assertEquals(attribute.render(), " required");
assertThat(attribute.render(), is(" required"));
Attribute nullAttribute = new Attribute(null, null);
assertEquals(nullAttribute.render(), "");
assertThat(nullAttribute.render(), is(""));
}
@Test
public void testSetAttribute() throws Exception {
ContainerTag testTag = new ContainerTag("a");
testTag.setAttribute("href", "http://example.com");
testTag.setAttribute("href", "http://example.org");
assertEquals(testTag.render(), "<a href=\"http://example.org\"></a>");
testTag.attr("href", "http://example.com");
testTag.attr("href", "http://example.org");
assertThat(testTag.render(), is("<a href=\"http://example.org\"></a>"));
}
}
}

View File

@@ -2,8 +2,26 @@ package j2html.tags;
import org.junit.Test;
import static j2html.TagCreator.*;
import static org.junit.Assert.assertEquals;
import j2html.attributes.Attr;
import static j2html.TagCreator.a;
import static j2html.TagCreator.body;
import static j2html.TagCreator.button;
import static j2html.TagCreator.div;
import static j2html.TagCreator.document;
import static j2html.TagCreator.footer;
import static j2html.TagCreator.h1;
import static j2html.TagCreator.h2;
import static j2html.TagCreator.head;
import static j2html.TagCreator.header;
import static j2html.TagCreator.html;
import static j2html.TagCreator.input;
import static j2html.TagCreator.main;
import static j2html.TagCreator.script;
import static j2html.TagCreator.text;
import static j2html.TagCreator.title;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class ComplexRenderTest {
@@ -17,20 +35,21 @@ public class ComplexRenderTest {
),
body().with(
header().with(
h1("Test Header")
h1().with(
text("Test Header "),
a("with link").withHref("http://example.com"),
text(".")
)
),
main().with(
h2("Test Form"),
div().with(
input().withType("email").withName("email").withPlaceholder("Email"),
input().withType("password").withName("password").withPlaceholder("Password")
).condWith(USER_SHOULD_LOG_IN,
button().withType("submit").withText("Login")
).condWith(USER_SHOULD_SIGN_UP,
button().withType("submit").withText("Signup")
)
).condWith(USER_SHOULD_LOG_IN, button().withType("submit").withText("Login")
).condWith(USER_SHOULD_SIGN_UP, button().withType("submit").withText("Signup"))
),
footer().withText("Test Footer"),
footer().attr(Attr.CLASS, "footer").condAttr(1 == 1, Attr.ID, "id").withText("Test Footer"),
script().withSrc("/testScript.js")
)
).render();
@@ -38,7 +57,7 @@ public class ComplexRenderTest {
@Test
public void testComplexRender() {
String expectedResult = "<!DOCTYPE html><html><head><title>Test</title></head><body><header><h1>Test Header</h1></header><main><h2>Test Form</h2><div><input type=\"email\" name=\"email\" placeholder=\"Email\"><input type=\"password\" name=\"password\" placeholder=\"Password\"><button type=\"submit\">Login</button></div></main><footer>Test Footer</footer><script src=\"/testScript.js\"></script></body></html>";
assertEquals(renderTest(), expectedResult);
String expectedResult = "<!DOCTYPE html><html><head><title>Test</title></head><body><header><h1>Test Header <a href=\"http://example.com\">with link</a>.</h1></header><main><h2>Test Form</h2><div><input type=\"email\" name=\"email\" placeholder=\"Email\"><input type=\"password\" name=\"password\" placeholder=\"Password\"><button type=\"submit\">Login</button></div></main><footer class=\"footer\" id=\"id\">Test Footer</footer><script src=\"/testScript.js\"></script></body></html>";
assertThat(renderTest(), is(expectedResult));
}
}

View File

@@ -2,32 +2,41 @@ package j2html.tags;
import org.junit.Test;
import static j2html.TagCreator.*;
import static org.junit.Assert.assertEquals;
import static j2html.TagCreator.a;
import static j2html.TagCreator.div;
import static j2html.TagCreator.form;
import static j2html.TagCreator.img;
import static j2html.TagCreator.input;
import static j2html.TagCreator.link;
import static j2html.TagCreator.meta;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class ConvenienceMethodTest {
@Test
public void testAllConvenienceMethods() throws Exception {
assertEquals(input().isAutoComplete().render(), "<input autocomplete>");
assertEquals(input().isAutoFocus().render(), "<input autofocus>");
assertEquals(input().isHidden().render(), "<input hidden>");
assertEquals(input().isRequired().render(), "<input required>");
assertEquals(img().withAlt("An image").render(), "<img alt=\"An image\">");
assertEquals(form().withAction("post").render(), "<form action=\"post\"></form>");
assertEquals(meta().withCharset("UTF-8").render(), "<meta charset=\"UTF-8\">");
assertEquals(div().withClass("test-class").render(), "<div class=\"test-class\"></div>");
assertEquals(meta().withContent("Test Content").render(), "<meta content=\"Test Content\">");
assertEquals(a().withHref("http://example.com").render(), "<a href=\"http://example.com\"></a>");
assertEquals(div().withId("test-id").render(), "<div id=\"test-id\"></div>");
assertEquals(div().withData("testdata", "test").render(), "<div data-testdata=\"test\"></div>");
assertEquals(form().withMethod("get").render(), "<form method=\"get\"></form>");
assertEquals(input().withName("test-name").render(), "<input name=\"test-name\">");
assertEquals(input().withPlaceholder("test-placeholder").render(), "<input placeholder=\"test-placeholder\">");
assertEquals(a().withTarget("_blank").render(), "<a target=\"_blank\"></a>");
assertEquals(input().withType("email").render(), "<input type=\"email\">");
assertEquals(link().withRel("stylesheet").render(), "<link rel=\"stylesheet\">");
assertEquals(img().withSrc("/img/test.png").render(), "<img src=\"/img/test.png\">");
assertEquals(input().withValue("test-value").render(), "<input value=\"test-value\">");
assertThat(input().isAutoComplete().render(), is("<input autocomplete>"));
assertThat(input().isAutoFocus().render(), is("<input autofocus>"));
assertThat(input().isHidden().render(), is("<input hidden>"));
assertThat(input().isRequired().render(), is("<input required>"));
assertThat(img().withAlt("An image").render(), is("<img alt=\"An image\">"));
assertThat(form().withAction("post").render(), is("<form action=\"post\"></form>"));
assertThat(meta().withCharset("UTF-8").render(), is("<meta charset=\"UTF-8\">"));
assertThat(div().withClass("test-class").render(), is("<div class=\"test-class\"></div>"));
assertThat(meta().withContent("Test Content").render(), is("<meta content=\"Test Content\">"));
assertThat(a().withHref("http://example.com").render(), is("<a href=\"http://example.com\"></a>"));
assertThat(div().withId("test-id").render(), is("<div id=\"test-id\"></div>"));
assertThat(div().withData("testdata", "test").render(), is("<div data-testdata=\"test\"></div>"));
assertThat(form().withMethod("get").render(), is("<form method=\"get\"></form>"));
assertThat(input().withName("test-name").render(), is("<input name=\"test-name\">"));
assertThat(input().withPlaceholder("test-placeholder").render(), is("<input placeholder=\"test-placeholder\">"));
assertThat(a().withTarget("_blank").render(), is("<a target=\"_blank\"></a>"));
assertThat(input().withType("email").render(), is("<input type=\"email\">"));
assertThat(link().withRel("stylesheet").render(), is("<link rel=\"stylesheet\">"));
assertThat(link().withRole("role").render(), is("<link role=\"role\">"));
assertThat(img().withSrc("/img/test.png").render(), is("<img src=\"/img/test.png\">"));
assertThat(div().withStyle("background:red;").render(), is("<div style=\"background:red;\"></div>"));
assertThat(input().withValue("test-value").render(), is("<input value=\"test-value\">"));
}
}

View File

@@ -1,178 +1,229 @@
package j2html.tags;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import static j2html.TagCreator.*;
import static org.junit.Assert.assertEquals;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class TagCreatorTest {
private static final String EOL = System.getProperty("line.separator"); // System independent End Of Line
List<Employee> employees = Arrays.asList(new Employee(1, "Name 1", "Title 1"), new Employee(2, "Name 2", "Title 2"), new Employee(3, "Name 3", "Title 3"));
@Test
public void testEach() throws Exception {
String j2htmlMap = ul().with(
li("Begin list"),
each(employees, employee -> li().with(
h2(employee.name),
p(employee.title)
))
).render();
String javaMap = ul().with(
li("Begin list"),
rawHtml(employees.stream().map(employee -> li().with(
h2(employee.name),
p(employee.title)
)).map(DomContent::render).collect(Collectors.joining()))
).render();
assertThat(j2htmlMap.equals(javaMap), is(true));
assertThat(j2htmlMap, is("<ul><li>Begin list</li><li><h2>Name 1</h2><p>Title 1</p></li><li><h2>Name 2</h2><p>Title 2</p></li><li><h2>Name 3</h2><p>Title 3</p></li></ul>"));
}
@Test
public void testFilter() throws Exception {
String j2htmlFilter = ul().with(
li("Begin list"),
each(filter(employees, e -> e.id % 2 == 1), employee -> li().with(
h2(employee.name),
p(employee.title)
))
).render();
String javaFilter = ul().with(
li("Begin list"),
rawHtml(employees.stream().filter(e -> e.id % 2 == 1).map(employee -> li().with(
h2(employee.name),
p(employee.title)
)).map(DomContent::render).collect(Collectors.joining()))
).render();
assertThat(j2htmlFilter.equals(javaFilter), is(true));
assertThat(j2htmlFilter, is("<ul><li>Begin list</li><li><h2>Name 1</h2><p>Title 1</p></li><li><h2>Name 3</h2><p>Title 3</p></li></ul>"));
}
@Test
public void testAllTags() throws Exception {
//Special Tags
assertEquals(tag("tagname").render(), "<tagname></tagname>");
assertEquals(emptyTag("tagname").render(), "<tagname>");
assertEquals(text("text").render(), "text");
assertEquals(text("<script> and \"</script>\"").render(), "&lt;script&gt; and &quot;&lt;/script&gt;&quot;");
assertEquals(unsafeHtml("<script>").render(), "<script>");
assertEquals(styleWithInlineFile_min("/test.css").render(), "<style>body{background:#daa520;margin-bottom:10px;margin-left:10px;margin-right:10px;margin-top:10px}</style>");
assertEquals(scriptWithInlineFile_min("/test.js").render(), "<script>(function(){console.log(15)})();</script>");
assertEquals(fileAsString("/test.html").render(), "<body>\r\n"+" Any content\r\n"+"</body>\r\n");
assertEquals(fileAsEscapedString("/test.html").render(), "&lt;body&gt;\r\n"+" Any content\r\n"+"&lt;/body&gt;\r\n");
assertEquals(fileAsString("/test.java").render(), "public class AnyContent{}\r\n");
assertThat(tag("tagname").render(), is("<tagname></tagname>"));
assertThat(emptyTag("tagname").render(), is("<tagname>"));
assertThat(text("text").render(), is("text"));
assertThat(text("<script> and \"</script>\"").render(), is("&lt;script&gt; and &quot;&lt;/script&gt;&quot;"));
assertThat(rawHtml("<script>").render(), is("<script>"));
assertThat(styleWithInlineFile_min("/test.css").render(), is("<style>body{background:#daa520;margin-bottom:10px;margin-left:10px;margin-right:10px;margin-top:10px}</style>"));
assertThat(scriptWithInlineFile_min("/test.js").render(), is("<script>(function(){var test=5;var tast=10;var testTast=test+tast;console.log(testTast);})();</script>"));
assertThat(fileAsString("/test.html").render(), is("<body>" + EOL + " Any content" + EOL + "</body>" + EOL));
assertThat(fileAsEscapedString("/test.html").render(), is("&lt;body&gt;" + EOL + " Any content" + EOL + "&lt;/body&gt;" + EOL));
assertThat(fileAsString("/AnyContent.java").render(), is("public class AnyContent{}" + EOL));
//EmptyTags
assertEquals(document().render(), "<!DOCTYPE html>");
assertEquals(area().render(), "<area>");
assertEquals(base().render(), "<base>");
assertEquals(br().render(), "<br>");
assertEquals(col().render(), "<col>");
assertEquals(embed().render(), "<embed>");
assertEquals(hr().render(), "<hr>");
assertEquals(img().render(), "<img>");
assertEquals(input().render(), "<input>");
assertEquals(keygen().render(), "<keygen>");
assertEquals(link().render(), "<link>");
assertEquals(meta().render(), "<meta>");
assertEquals(param().render(), "<param>");
assertEquals(source().render(), "<source>");
assertEquals(track().render(), "<track>");
assertEquals(wbr().render(), "<wbr>");
assertThat(document().render(), is("<!DOCTYPE html>"));
assertThat(area().render(), is("<area>"));
assertThat(base().render(), is("<base>"));
assertThat(br().render(), is("<br>"));
assertThat(col().render(), is("<col>"));
assertThat(embed().render(), is("<embed>"));
assertThat(hr().render(), is("<hr>"));
assertThat(img().render(), is("<img>"));
assertThat(input().render(), is("<input>"));
assertThat(keygen().render(), is("<keygen>"));
assertThat(link().render(), is("<link>"));
assertThat(meta().render(), is("<meta>"));
assertThat(param().render(), is("<param>"));
assertThat(source().render(), is("<source>"));
assertThat(track().render(), is("<track>"));
assertThat(wbr().render(), is("<wbr>"));
//ContainerTags
assertEquals(a().render(), "<a></a>");
assertEquals(a("Text").render(), "<a>Text</a>");
assertEquals(abbr().render(), "<abbr></abbr>");
assertEquals(address().render(), "<address></address>");
assertEquals(article().render(), "<article></article>");
assertEquals(aside().render(), "<aside></aside>");
assertEquals(audio().render(), "<audio></audio>");
assertEquals(b().render(), "<b></b>");
assertEquals(b("Text").render(), "<b>Text</b>");
assertEquals(bdi().render(), "<bdi></bdi>");
assertEquals(bdi("Text").render(), "<bdi>Text</bdi>");
assertEquals(bdo().render(), "<bdo></bdo>");
assertEquals(bdo("Text").render(), "<bdo>Text</bdo>");
assertEquals(blockquote().render(), "<blockquote></blockquote>");
assertEquals(blockquote("Text").render(), "<blockquote>Text</blockquote>");
assertEquals(body().render(), "<body></body>");
assertEquals(button().render(), "<button></button>");
assertEquals(button("Text").render(), "<button>Text</button>");
assertEquals(canvas().render(), "<canvas></canvas>");
assertEquals(caption().render(), "<caption></caption>");
assertEquals(caption("Text").render(), "<caption>Text</caption>");
assertEquals(cite().render(), "<cite></cite>");
assertEquals(cite("Text").render(), "<cite>Text</cite>");
assertEquals(code().render(), "<code></code>");
assertEquals(colgroup().render(), "<colgroup></colgroup>");
assertEquals(datalist().render(), "<datalist></datalist>");
assertEquals(dd().render(), "<dd></dd>");
assertEquals(dd("Text").render(), "<dd>Text</dd>");
assertEquals(del().render(), "<del></del>");
assertEquals(del("Text").render(), "<del>Text</del>");
assertEquals(details().render(), "<details></details>");
assertEquals(dfn().render(), "<dfn></dfn>");
assertEquals(dfn("Text").render(), "<dfn>Text</dfn>");
assertEquals(dialog().render(), "<dialog></dialog>");
assertEquals(dialog("Text").render(), "<dialog>Text</dialog>");
assertEquals(div().render(), "<div></div>");
assertEquals(dl().render(), "<dl></dl>");
assertEquals(dt().render(), "<dt></dt>");
assertEquals(dt("Text").render(), "<dt>Text</dt>");
assertEquals(em().render(), "<em></em>");
assertEquals(em("Text").render(), "<em>Text</em>");
assertEquals(fieldset().render(), "<fieldset></fieldset>");
assertEquals(figcaption().render(), "<figcaption></figcaption>");
assertEquals(figcaption("Text").render(), "<figcaption>Text</figcaption>");
assertEquals(figure().render(), "<figure></figure>");
assertEquals(footer().render(), "<footer></footer>");
assertEquals(form().render(), "<form></form>");
assertEquals(h1().render(), "<h1></h1>");
assertEquals(h1("Text").render(), "<h1>Text</h1>");
assertEquals(h2().render(), "<h2></h2>");
assertEquals(h2("Text").render(), "<h2>Text</h2>");
assertEquals(h3().render(), "<h3></h3>");
assertEquals(h3("Text").render(), "<h3>Text</h3>");
assertEquals(h4().render(), "<h4></h4>");
assertEquals(h4("Text").render(), "<h4>Text</h4>");
assertEquals(h5().render(), "<h5></h5>");
assertEquals(h5("Text").render(), "<h5>Text</h5>");
assertEquals(h6().render(), "<h6></h6>");
assertEquals(h6("Text").render(), "<h6>Text</h6>");
assertEquals(head().render(), "<head></head>");
assertEquals(header().render(), "<header></header>");
assertEquals(html().render(), "<html></html>");
assertEquals(i().render(), "<i></i>");
assertEquals(i("Text").render(), "<i>Text</i>");
assertEquals(iframe().render(), "<iframe></iframe>");
assertEquals(ins().render(), "<ins></ins>");
assertEquals(ins("Text").render(), "<ins>Text</ins>");
assertEquals(kbd().render(), "<kbd></kbd>");
assertEquals(label().render(), "<label></label>");
assertEquals(label("Text").render(), "<label>Text</label>");
assertEquals(legend().render(), "<legend></legend>");
assertEquals(legend("Text").render(), "<legend>Text</legend>");
assertEquals(li().render(), "<li></li>");
assertEquals(li("Text").render(), "<li>Text</li>");
assertEquals(main().render(), "<main></main>");
assertEquals(map().render(), "<map></map>");
assertEquals(mark().render(), "<mark></mark>");
assertEquals(menu().render(), "<menu></menu>");
assertEquals(menuitem().render(), "<menuitem></menuitem>");
assertEquals(meter().render(), "<meter></meter>");
assertEquals(nav().render(), "<nav></nav>");
assertEquals(noscript().render(), "<noscript></noscript>");
assertEquals(object().render(), "<object></object>");
assertEquals(ol().render(), "<ol></ol>");
assertEquals(optgroup().render(), "<optgroup></optgroup>");
assertEquals(option().render(), "<option></option>");
assertEquals(option("Text").render(), "<option>Text</option>");
assertEquals(output().render(), "<output></output>");
assertEquals(p().render(), "<p></p>");
assertEquals(p("Text").render(), "<p>Text</p>");
assertEquals(pre().render(), "<pre></pre>");
assertEquals(progress().render(), "<progress></progress>");
assertEquals(q().render(), "<q></q>");
assertEquals(q("Text").render(), "<q>Text</q>");
assertEquals(rp().render(), "<rp></rp>");
assertEquals(rt().render(), "<rt></rt>");
assertEquals(ruby().render(), "<ruby></ruby>");
assertEquals(s().render(), "<s></s>");
assertEquals(samp().render(), "<samp></samp>");
assertEquals(script().render(), "<script></script>");
assertEquals(section().render(), "<section></section>");
assertEquals(select().render(), "<select></select>");
assertEquals(small().render(), "<small></small>");
assertEquals(small("Text").render(), "<small>Text</small>");
assertEquals(span().render(), "<span></span>");
assertEquals(span("Text").render(), "<span>Text</span>");
assertEquals(strong().render(), "<strong></strong>");
assertEquals(strong("Text").render(), "<strong>Text</strong>");
assertEquals(style().render(), "<style></style>");
assertEquals(sub().render(), "<sub></sub>");
assertEquals(sub("Text").render(), "<sub>Text</sub>");
assertEquals(summary().render(), "<summary></summary>");
assertEquals(summary("Text").render(), "<summary>Text</summary>");
assertEquals(sup().render(), "<sup></sup>");
assertEquals(sup("Text").render(), "<sup>Text</sup>");
assertEquals(table().render(), "<table></table>");
assertEquals(tbody().render(), "<tbody></tbody>");
assertEquals(td().render(), "<td></td>");
assertEquals(td("Text").render(), "<td>Text</td>");
assertEquals(textarea().render(), "<textarea></textarea>");
assertEquals(tfoot().render(), "<tfoot></tfoot>");
assertEquals(th().render(), "<th></th>");
assertEquals(th("Text").render(), "<th>Text</th>");
assertEquals(thead().render(), "<thead></thead>");
assertEquals(time().render(), "<time></time>");
assertEquals(title().render(), "<title></title>");
assertEquals(tr().render(), "<tr></tr>");
assertEquals(u().render(), "<u></u>");
assertEquals(u("Text").render(), "<u>Text</u>");
assertEquals(ul().render(), "<ul></ul>");
assertEquals(var().render(), "<var></var>");
assertEquals(video().render(), "<video></video>");
assertThat(a().render(), is("<a></a>"));
assertThat(a("Text").render(), is("<a>Text</a>"));
assertThat(abbr().render(), is("<abbr></abbr>"));
assertThat(address().render(), is("<address></address>"));
assertThat(article().render(), is("<article></article>"));
assertThat(aside().render(), is("<aside></aside>"));
assertThat(audio().render(), is("<audio></audio>"));
assertThat(b().render(), is("<b></b>"));
assertThat(b("Text").render(), is("<b>Text</b>"));
assertThat(bdi().render(), is("<bdi></bdi>"));
assertThat(bdi("Text").render(), is("<bdi>Text</bdi>"));
assertThat(bdo().render(), is("<bdo></bdo>"));
assertThat(bdo("Text").render(), is("<bdo>Text</bdo>"));
assertThat(blockquote().render(), is("<blockquote></blockquote>"));
assertThat(blockquote("Text").render(), is("<blockquote>Text</blockquote>"));
assertThat(body().render(), is("<body></body>"));
assertThat(button().render(), is("<button></button>"));
assertThat(button("Text").render(), is("<button>Text</button>"));
assertThat(canvas().render(), is("<canvas></canvas>"));
assertThat(caption().render(), is("<caption></caption>"));
assertThat(caption("Text").render(), is("<caption>Text</caption>"));
assertThat(cite().render(), is("<cite></cite>"));
assertThat(cite("Text").render(), is("<cite>Text</cite>"));
assertThat(code().render(), is("<code></code>"));
assertThat(colgroup().render(), is("<colgroup></colgroup>"));
assertThat(datalist().render(), is("<datalist></datalist>"));
assertThat(dd().render(), is("<dd></dd>"));
assertThat(dd("Text").render(), is("<dd>Text</dd>"));
assertThat(del().render(), is("<del></del>"));
assertThat(del("Text").render(), is("<del>Text</del>"));
assertThat(details().render(), is("<details></details>"));
assertThat(dfn().render(), is("<dfn></dfn>"));
assertThat(dfn("Text").render(), is("<dfn>Text</dfn>"));
assertThat(dialog().render(), is("<dialog></dialog>"));
assertThat(dialog("Text").render(), is("<dialog>Text</dialog>"));
assertThat(div().render(), is("<div></div>"));
assertThat(dl().render(), is("<dl></dl>"));
assertThat(dt().render(), is("<dt></dt>"));
assertThat(dt("Text").render(), is("<dt>Text</dt>"));
assertThat(em().render(), is("<em></em>"));
assertThat(em("Text").render(), is("<em>Text</em>"));
assertThat(fieldset().render(), is("<fieldset></fieldset>"));
assertThat(figcaption().render(), is("<figcaption></figcaption>"));
assertThat(figcaption("Text").render(), is("<figcaption>Text</figcaption>"));
assertThat(figure().render(), is("<figure></figure>"));
assertThat(footer().render(), is("<footer></footer>"));
assertThat(form().render(), is("<form></form>"));
assertThat(h1().render(), is("<h1></h1>"));
assertThat(h1("Text").render(), is("<h1>Text</h1>"));
assertThat(h2().render(), is("<h2></h2>"));
assertThat(h2("Text").render(), is("<h2>Text</h2>"));
assertThat(h3().render(), is("<h3></h3>"));
assertThat(h3("Text").render(), is("<h3>Text</h3>"));
assertThat(h4().render(), is("<h4></h4>"));
assertThat(h4("Text").render(), is("<h4>Text</h4>"));
assertThat(h5().render(), is("<h5></h5>"));
assertThat(h5("Text").render(), is("<h5>Text</h5>"));
assertThat(h6().render(), is("<h6></h6>"));
assertThat(h6("Text").render(), is("<h6>Text</h6>"));
assertThat(head().render(), is("<head></head>"));
assertThat(header().render(), is("<header></header>"));
assertThat(html().render(), is("<html></html>"));
assertThat(i().render(), is("<i></i>"));
assertThat(i("Text").render(), is("<i>Text</i>"));
assertThat(iframe().render(), is("<iframe></iframe>"));
assertThat(ins().render(), is("<ins></ins>"));
assertThat(ins("Text").render(), is("<ins>Text</ins>"));
assertThat(kbd().render(), is("<kbd></kbd>"));
assertThat(label().render(), is("<label></label>"));
assertThat(label("Text").render(), is("<label>Text</label>"));
assertThat(legend().render(), is("<legend></legend>"));
assertThat(legend("Text").render(), is("<legend>Text</legend>"));
assertThat(li().render(), is("<li></li>"));
assertThat(li("Text").render(), is("<li>Text</li>"));
assertThat(main().render(), is("<main></main>"));
assertThat(map().render(), is("<map></map>"));
assertThat(mark().render(), is("<mark></mark>"));
assertThat(menu().render(), is("<menu></menu>"));
assertThat(menuitem().render(), is("<menuitem></menuitem>"));
assertThat(meter().render(), is("<meter></meter>"));
assertThat(nav().render(), is("<nav></nav>"));
assertThat(noscript().render(), is("<noscript></noscript>"));
assertThat(object().render(), is("<object></object>"));
assertThat(ol().render(), is("<ol></ol>"));
assertThat(optgroup().render(), is("<optgroup></optgroup>"));
assertThat(option().render(), is("<option></option>"));
assertThat(option("Text").render(), is("<option>Text</option>"));
assertThat(output().render(), is("<output></output>"));
assertThat(p().render(), is("<p></p>"));
assertThat(p("Text").render(), is("<p>Text</p>"));
assertThat(pre().render(), is("<pre></pre>"));
assertThat(progress().render(), is("<progress></progress>"));
assertThat(q().render(), is("<q></q>"));
assertThat(q("Text").render(), is("<q>Text</q>"));
assertThat(rp().render(), is("<rp></rp>"));
assertThat(rt().render(), is("<rt></rt>"));
assertThat(ruby().render(), is("<ruby></ruby>"));
assertThat(s().render(), is("<s></s>"));
assertThat(s("Text").render(), is("<s>Text</s>"));
assertThat(samp().render(), is("<samp></samp>"));
assertThat(script().render(), is("<script></script>"));
assertThat(section().render(), is("<section></section>"));
assertThat(select().render(), is("<select></select>"));
assertThat(small().render(), is("<small></small>"));
assertThat(small("Text").render(), is("<small>Text</small>"));
assertThat(span().render(), is("<span></span>"));
assertThat(span("Text").render(), is("<span>Text</span>"));
assertThat(strong().render(), is("<strong></strong>"));
assertThat(strong("Text").render(), is("<strong>Text</strong>"));
assertThat(style().render(), is("<style></style>"));
assertThat(sub().render(), is("<sub></sub>"));
assertThat(sub("Text").render(), is("<sub>Text</sub>"));
assertThat(summary().render(), is("<summary></summary>"));
assertThat(summary("Text").render(), is("<summary>Text</summary>"));
assertThat(sup().render(), is("<sup></sup>"));
assertThat(sup("Text").render(), is("<sup>Text</sup>"));
assertThat(table().render(), is("<table></table>"));
assertThat(tbody().render(), is("<tbody></tbody>"));
assertThat(td().render(), is("<td></td>"));
assertThat(td("Text").render(), is("<td>Text</td>"));
assertThat(textarea().render(), is("<textarea></textarea>"));
assertThat(tfoot().render(), is("<tfoot></tfoot>"));
assertThat(th().render(), is("<th></th>"));
assertThat(th("Text").render(), is("<th>Text</th>"));
assertThat(thead().render(), is("<thead></thead>"));
assertThat(time().render(), is("<time></time>"));
assertThat(title().render(), is("<title></title>"));
assertThat(title("Text").render(), is("<title>Text</title>"));
assertThat(tr().render(), is("<tr></tr>"));
assertThat(u().render(), is("<u></u>"));
assertThat(u("Text").render(), is("<u>Text</u>"));
assertThat(ul().render(), is("<ul></ul>"));
assertThat(var().render(), is("<var></var>"));
assertThat(video().render(), is("<video></video>"));
}
}

View File

@@ -2,8 +2,15 @@ package j2html.tags;
import org.junit.Test;
import static j2html.TagCreator.*;
import static org.junit.Assert.assertEquals;
import static j2html.TagCreator.body;
import static j2html.TagCreator.footer;
import static j2html.TagCreator.header;
import static j2html.TagCreator.html;
import static j2html.TagCreator.main;
import static j2html.TagCreator.p;
import static j2html.TagCreator.tag;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class TagTest {
@@ -11,28 +18,35 @@ public class TagTest {
public void testRender() throws Exception {
ContainerTag testTag = new ContainerTag("a");
testTag.setAttribute("href", "http://example.com");
assertEquals(testTag.render(), "<a href=\"http://example.com\"></a>");
assertThat(testTag.render(), is("<a href=\"http://example.com\"></a>"));
ContainerTag complexTestTag = html().with(body().with(header(),main().with(p("Main stuff...")),footer().condWith(1 == 1,p("Conditional with!"))));
String expectedResult ="<html><body><header></header><main><p>Main stuff...</p></main><footer><p>Conditional with!</p></footer></body></html>";
assertEquals(complexTestTag.render(), (expectedResult));
ContainerTag complexTestTag = html().with(body().with(header(), main().with(p("Main stuff...")), footer().condWith(1 == 1, p("Conditional with!"))));
String expectedResult = "<html><body><header></header><main><p>Main stuff...</p></main><footer><p>Conditional with!</p></footer></body></html>";
assertThat(complexTestTag.render(), is((expectedResult)));
}
@Test
public void testOpenTag() throws Exception {
ContainerTag testTag = new ContainerTag("a");
assertEquals(testTag.renderOpenTag(), "<a>");
assertThat(testTag.renderOpenTag(), is("<a>"));
ContainerTag complexTestTag = new ContainerTag("input");
complexTestTag.withType("password").withId("password").withName("password").withPlaceholder("Password").isRequired();
String expectedResult = "<input type=\"password\" id=\"password\" name=\"password\" placeholder=\"Password\" required>";
assertEquals(complexTestTag.renderOpenTag(), expectedResult);
assertThat(complexTestTag.renderOpenTag(), is(expectedResult));
}
@Test
public void testCloseTag() throws Exception {
ContainerTag testTag = new ContainerTag("a");
assertEquals(testTag.renderCloseTag(), "</a>");
assertThat(testTag.renderCloseTag(), is("</a>"));
}
@Test
public void testEquals() throws Exception {
Tag tagOne = tag("p").withClass("class").withText("Test");
Tag tagTwo = p("Test").withClass("class");
assertThat(tagOne.equals(tagTwo), is(true));
}
}

View File

@@ -0,0 +1,13 @@
package j2html.tags;
class Employee {
final int id;
final String name;
final String title;
Employee(int id, String name, String title) {
this.id = id;
this.name = name;
this.title = title;
}
}