Compare commits
14 Commits
j2html-1.5
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b99683147 | ||
|
|
38c08d4724 | ||
|
|
1c164a0773 | ||
|
|
dcc7258c8e | ||
|
|
930ade9354 | ||
|
|
d1c404d5db | ||
|
|
c2177d0584 | ||
|
|
5eb202b0a9 | ||
|
|
4bda3635ab | ||
|
|
f083b2cc9c | ||
|
|
9ad0e428c1 | ||
|
|
83866be83f | ||
|
|
5135cffc3f | ||
|
|
09e08f3465 |
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -23,6 +23,6 @@ jobs:
|
|||||||
if: contains(matrix.os, 'win') == false
|
if: contains(matrix.os, 'win') == false
|
||||||
run: chmod +x ./mvnw
|
run: chmod +x ./mvnw
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: ./mvnw package --file library/pom.xml --batch-mode
|
run: ./mvnw verify --file library/pom.xml --batch-mode
|
||||||
env:
|
env:
|
||||||
MAVEN_OPTS: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
MAVEN_OPTS: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ The project webpage is [j2html.com](http://j2html.com).
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.j2html</groupId>
|
<groupId>com.j2html</groupId>
|
||||||
<artifactId>j2html</artifactId>
|
<artifactId>j2html</artifactId>
|
||||||
<version>1.4.0</version>
|
<version>1.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
### Or the gradle dependency
|
### Or the gradle dependency
|
||||||
```
|
```
|
||||||
compile 'com.j2html:j2html:1.4.0'
|
compile 'com.j2html:j2html:1.6.0'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Import TagCreator and start building HTML
|
### Import TagCreator and start building HTML
|
||||||
|
|||||||
141
code_gen/pom.xml
141
code_gen/pom.xml
@@ -1,74 +1,85 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.j2html</groupId>
|
<groupId>com.j2html</groupId>
|
||||||
<artifactId>j2htmlcodegen</artifactId>
|
<artifactId>j2htmlcodegen</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<name>j2htmlcodegen</name>
|
<name>j2htmlcodegen</name>
|
||||||
<url>https://j2html.com/</url>
|
<url>https://j2html.com/</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>jsoup</artifactId>
|
||||||
<version>4.13.1</version>
|
<version>1.15.3</version>
|
||||||
<scope>test</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
<dependency>
|
||||||
|
<groupId>com.squareup</groupId>
|
||||||
|
<artifactId>javapoet</artifactId>
|
||||||
|
<version>1.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
<plugins>
|
<plugins>
|
||||||
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-clean-plugin</artifactId>
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.2.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.2.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.0</version>
|
<version>3.10.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>2.22.1</version>
|
<version>2.22.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.2.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-install-plugin</artifactId>
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
<version>2.5.2</version>
|
<version>2.5.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-deploy-plugin</artifactId>
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
<version>2.8.2</version>
|
<version>2.8.2</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-site-plugin</artifactId>
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
<version>3.7.1</version>
|
<version>3.7.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.0.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public final class TagCreatorCodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is a method that contains all ContainerTags, there is nothing below it
|
// This is a method that contains all ContainerTags, there is nothing below it
|
||||||
static List<String> emptyTags() {
|
public static List<String> emptyTags() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
"area",
|
"area",
|
||||||
"base",
|
"base",
|
||||||
@@ -84,7 +84,7 @@ public final class TagCreatorCodeGenerator {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<String> containerTags() {
|
public static List<String> containerTags() {
|
||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
"a",
|
"a",
|
||||||
"abbr",
|
"abbr",
|
||||||
@@ -103,6 +103,7 @@ public final class TagCreatorCodeGenerator {
|
|||||||
"cite",
|
"cite",
|
||||||
"code",
|
"code",
|
||||||
"colgroup",
|
"colgroup",
|
||||||
|
"data",
|
||||||
"datalist",
|
"datalist",
|
||||||
"dd",
|
"dd",
|
||||||
"del",
|
"del",
|
||||||
@@ -134,7 +135,6 @@ public final class TagCreatorCodeGenerator {
|
|||||||
"label",
|
"label",
|
||||||
"legend",
|
"legend",
|
||||||
"li",
|
"li",
|
||||||
"generate",
|
|
||||||
"main",
|
"main",
|
||||||
"map",
|
"map",
|
||||||
"mark",
|
"mark",
|
||||||
@@ -149,6 +149,7 @@ public final class TagCreatorCodeGenerator {
|
|||||||
"option",
|
"option",
|
||||||
"output",
|
"output",
|
||||||
"p",
|
"p",
|
||||||
|
"picture",
|
||||||
"pre",
|
"pre",
|
||||||
"progress",
|
"progress",
|
||||||
"q",
|
"q",
|
||||||
@@ -160,6 +161,7 @@ public final class TagCreatorCodeGenerator {
|
|||||||
"script",
|
"script",
|
||||||
"section",
|
"section",
|
||||||
"select",
|
"select",
|
||||||
|
"slot",
|
||||||
"small",
|
"small",
|
||||||
"span",
|
"span",
|
||||||
"strong",
|
"strong",
|
||||||
@@ -170,6 +172,7 @@ public final class TagCreatorCodeGenerator {
|
|||||||
"table",
|
"table",
|
||||||
"tbody",
|
"tbody",
|
||||||
"td",
|
"td",
|
||||||
|
"template",
|
||||||
"textarea",
|
"textarea",
|
||||||
"tfoot",
|
"tfoot",
|
||||||
"th",
|
"th",
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package j2html_codegen.generators;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import j2html_codegen.wattsi.AttributeDefinition;
|
||||||
|
import j2html_codegen.wattsi.ElementDefinition;
|
||||||
|
import j2html_codegen.wattsi.WattsiSource;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class WattsiGenerator {
|
||||||
|
|
||||||
|
public static void main(String... args) throws IOException {
|
||||||
|
Path source = Paths.get(args[0]);
|
||||||
|
Document doc = Jsoup.parse(source.toFile(), "UTF-8", "https://html.spec.whatwg.org/");
|
||||||
|
WattsiSource wattsi = new WattsiSource(doc);
|
||||||
|
|
||||||
|
List<ElementDefinition> elements = wattsi.elementDefinitions();
|
||||||
|
List<AttributeDefinition> attributes = wattsi.attributeDefinitions();
|
||||||
|
|
||||||
|
// for (ElementDefinition element : elements) {
|
||||||
|
// System.out.println((element.isObsolete() ? "!" : "") + element.name());
|
||||||
|
// for (AttributeDefinition attribute : attributes) {
|
||||||
|
// if (attribute.appliesTo(element)) {
|
||||||
|
// System.out.println(" " + (attribute.isObsolete() ? "!" : "") + attribute.name());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// System.out.println();
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (ElementDefinition element : elements) {
|
||||||
|
ClassName className = ClassName.get(
|
||||||
|
"com.j2html",
|
||||||
|
capitalize(element.name()) + "Tag"
|
||||||
|
);
|
||||||
|
|
||||||
|
TypeSpec.Builder type = TypeSpec.classBuilder(className)
|
||||||
|
.addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
|
if (element.isObsolete()) {
|
||||||
|
type.addAnnotation(Deprecated.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AttributeDefinition attribute : attributes) {
|
||||||
|
if (attribute.appliesTo(element)) {
|
||||||
|
String name = methodName("with", attribute.name().split("-"));
|
||||||
|
MethodSpec.Builder setter = MethodSpec.methodBuilder(name)
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.returns(className)
|
||||||
|
.addStatement("return this");
|
||||||
|
|
||||||
|
if(attribute.isObsolete()){
|
||||||
|
setter.addAnnotation(Deprecated.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
type.addMethod(setter.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println(type.build().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(doc.select("dfn"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String methodName(String prefix, String... words){
|
||||||
|
String[] tmp = new String[words.length + 1];
|
||||||
|
tmp[0] = prefix;
|
||||||
|
for(int i = 0; i < words.length; i++){
|
||||||
|
tmp[i+1] = words[i];
|
||||||
|
}
|
||||||
|
return methodName(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String methodName(String... words){
|
||||||
|
String[] camelCase = new String[words.length];
|
||||||
|
camelCase[0] = words[0];
|
||||||
|
for(int i = 1; i < words.length; i++){
|
||||||
|
camelCase[i] = capitalize(words[i]);
|
||||||
|
}
|
||||||
|
return String.join("", camelCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String capitalize(String word){
|
||||||
|
return word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,7 +80,7 @@ public final class AttributesList {
|
|||||||
new AttrD("min", true, "input","meter"),
|
new AttrD("min", true, "input","meter"),
|
||||||
new AttrD("multiple", false, "input","select"),
|
new AttrD("multiple", false, "input","select"),
|
||||||
new AttrD("muted", false, "video","audio"),
|
new AttrD("muted", false, "video","audio"),
|
||||||
new AttrD("name", true, "button","fieldset","form","iframe","input","map","meta","object","output","param","select","textarea"),
|
new AttrD("name", true, "button","fieldset","form","iframe","input","map","meta","object","output","param","select","slot","textarea"),
|
||||||
new AttrD("novalidate", false, "form"),
|
new AttrD("novalidate", false, "form"),
|
||||||
new AttrD("onabort", true, "audio","embed","img","object","video"),
|
new AttrD("onabort", true, "audio","embed","img","object","video"),
|
||||||
new AttrD("onafterprint", true, "body"),
|
new AttrD("onafterprint", true, "body"),
|
||||||
@@ -174,7 +174,7 @@ public final class AttributesList {
|
|||||||
//new AttrD("translate"),// global attribute
|
//new AttrD("translate"),// global attribute
|
||||||
new AttrD("type", true, "a","button","embed","input","link","menu","object","script","source","style"),
|
new AttrD("type", true, "a","button","embed","input","link","menu","object","script","source","style"),
|
||||||
new AttrD("usemap", true, "img","object"),
|
new AttrD("usemap", true, "img","object"),
|
||||||
new AttrD("value", true, "button","input","li","option","meter","progress","param"),
|
new AttrD("value", true, "button","data","input","li","option","meter","progress","param"),
|
||||||
new AttrD("width", true, "canvas","embed","iframe","img","input","object","video"),
|
new AttrD("width", true, "canvas","embed","iframe","img","input","object","video"),
|
||||||
new AttrD("wrap", true, "textarea")
|
new AttrD("wrap", true, "textarea")
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package j2html_codegen.wattsi;
|
||||||
|
|
||||||
|
public interface AttributeDefinition {
|
||||||
|
|
||||||
|
String name();
|
||||||
|
|
||||||
|
boolean appliesTo(ElementDefinition element);
|
||||||
|
|
||||||
|
boolean isObsolete();
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package j2html_codegen.wattsi;
|
||||||
|
|
||||||
|
public interface ElementDefinition {
|
||||||
|
|
||||||
|
String name();
|
||||||
|
|
||||||
|
boolean isObsolete();
|
||||||
|
|
||||||
|
}
|
||||||
204
code_gen/src/main/java/j2html_codegen/wattsi/WattsiSource.java
Normal file
204
code_gen/src/main/java/j2html_codegen/wattsi/WattsiSource.java
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package j2html_codegen.wattsi;
|
||||||
|
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.nodes.Node;
|
||||||
|
import org.jsoup.nodes.TextNode;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
|
public class WattsiSource {
|
||||||
|
|
||||||
|
private final Document doc;
|
||||||
|
|
||||||
|
private final Set<Reference> obsolete = new HashSet<>();
|
||||||
|
|
||||||
|
public WattsiSource(Document doc) {
|
||||||
|
this.doc = doc;
|
||||||
|
|
||||||
|
// Find where obsolete elements are defined or referenced.
|
||||||
|
Elements obsoleteElements = doc.select("p:contains(Elements in the following list are entirely obsolete) + dl");
|
||||||
|
|
||||||
|
// Convert definitions into references to record obsolete elements.
|
||||||
|
obsoleteElements.select("dt > dfn[element]")
|
||||||
|
.stream()
|
||||||
|
.map(WattsiElement::new)
|
||||||
|
.map(WattsiElement::reference)
|
||||||
|
.forEach(obsolete::add);
|
||||||
|
|
||||||
|
// Extract references to record obsolete elements.
|
||||||
|
obsoleteElements.select("dt > code")
|
||||||
|
.stream()
|
||||||
|
.map(Element::childNodes)
|
||||||
|
.map(Reference::from)
|
||||||
|
.forEach(obsolete::add);
|
||||||
|
|
||||||
|
// Find where obsolete attributes are defined or referenced.
|
||||||
|
Elements obsoleteAttributes = doc.select("p:contains(The following attributes are obsolete) + dl");
|
||||||
|
|
||||||
|
// Convert definitions into references to record obsolete attributes.
|
||||||
|
obsoleteAttributes.select("dt > dfn[element-attr]").stream()
|
||||||
|
.map(WattsiAttribute::new)
|
||||||
|
.map(WattsiAttribute::reference)
|
||||||
|
.forEach(obsolete::add);
|
||||||
|
|
||||||
|
// System.out.println(obsoleteAttributes.select("dt"));
|
||||||
|
|
||||||
|
// obsoleteAttributes.select("dt > code").stream()
|
||||||
|
// .map(Element::childNodes)
|
||||||
|
// .map(Reference::from)
|
||||||
|
// .forEach(System.err::println);
|
||||||
|
|
||||||
|
// System.out.println(
|
||||||
|
// doc.select("dfn[obsolete]")
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ElementDefinition> elementDefinitions() {
|
||||||
|
return doc.select("dfn[element]").stream()
|
||||||
|
.map(WattsiElement::new)
|
||||||
|
.collect(toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AttributeDefinition> attributeDefinitions() {
|
||||||
|
return doc.select("dfn[element-attr]").stream()
|
||||||
|
.map(WattsiAttribute::new)
|
||||||
|
.collect(toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WattsiElement implements ElementDefinition {
|
||||||
|
private final Element dfn;
|
||||||
|
|
||||||
|
WattsiElement(Element dfn) {
|
||||||
|
if (!"dfn".equals(dfn.tagName())) {
|
||||||
|
throw new IllegalArgumentException("Element cannot be defined from: " + dfn);
|
||||||
|
}
|
||||||
|
if (!dfn.hasAttr("element")) {
|
||||||
|
throw new IllegalArgumentException("Does not define an element: " + dfn);
|
||||||
|
}
|
||||||
|
if (dfn.childrenSize() != 1) {
|
||||||
|
throw new IllegalArgumentException("Element cannot have multiple definitions: " + dfn);
|
||||||
|
}
|
||||||
|
this.dfn = dfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Reference reference() {
|
||||||
|
return Reference.from(dfn.childNodes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
if (dfn.hasAttr("data-x")) {
|
||||||
|
return dfn.attr("data-x");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Reference.from(dfn.childNodes()).key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isObsolete() {
|
||||||
|
return obsolete.contains(reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WattsiAttribute implements AttributeDefinition {
|
||||||
|
private final Element dfn;
|
||||||
|
|
||||||
|
WattsiAttribute(Element dfn) {
|
||||||
|
if (!"dfn".equals(dfn.tagName())) {
|
||||||
|
throw new IllegalArgumentException("Attribute cannot be defined from: " + dfn);
|
||||||
|
}
|
||||||
|
if (!dfn.hasAttr("element-attr")) {
|
||||||
|
throw new IllegalArgumentException("Does not define an attribute: " + dfn);
|
||||||
|
}
|
||||||
|
if (dfn.childrenSize() != 1) {
|
||||||
|
throw new IllegalArgumentException("Attribute cannot have multiple definitions: " + dfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dfn = dfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Reference reference() {
|
||||||
|
return Reference.from(dfn.childNodes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return reference().text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> targets() {
|
||||||
|
if (dfn.hasAttr("for")) {
|
||||||
|
return Arrays.asList(dfn.attr("for").trim().split(","));
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean appliesTo(ElementDefinition element) {
|
||||||
|
return targets().contains(element.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isObsolete() {
|
||||||
|
return obsolete.contains(reference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Reference {
|
||||||
|
private final String key;
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
Reference(String key, String text) {
|
||||||
|
this.key = key;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return key + "[" + text + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Reference reference = (Reference) o;
|
||||||
|
return key.equals(reference.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Reference from(List<Node> nodes) {
|
||||||
|
if (nodes.stream().allMatch(n -> n instanceof TextNode)) {
|
||||||
|
String txt = nodes.stream()
|
||||||
|
.map(n -> (TextNode) n)
|
||||||
|
.map(TextNode::text)
|
||||||
|
.collect(Collectors.joining(" "));
|
||||||
|
return new Reference(txt, txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Node node : nodes) {
|
||||||
|
if (node instanceof Element) {
|
||||||
|
Element element = (Element) node;
|
||||||
|
if (element.is("code") || element.is("span")) {
|
||||||
|
if (element.hasAttr("data-x")) {
|
||||||
|
return new Reference(element.attr("data-x").toLowerCase(), element.text());
|
||||||
|
} else {
|
||||||
|
return new Reference(element.text().toLowerCase(), element.text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package j2html_codegen;
|
||||||
|
|
||||||
|
import j2html_codegen.generators.TagCreatorCodeGenerator;
|
||||||
|
import j2html_codegen.wattsi.ElementDefinition;
|
||||||
|
import j2html_codegen.wattsi.WattsiSource;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class CodeGeneratorComplianceTests {
|
||||||
|
|
||||||
|
private WattsiSource specification;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
Path source = Paths.get("src","test","resources","2022-01.wattsi");
|
||||||
|
Document doc = Jsoup.parse(source.toFile(), "UTF-8", "https://html.spec.whatwg.org/");
|
||||||
|
specification = new WattsiSource(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> generatedElements(){
|
||||||
|
Set<String> elements = new HashSet<>();
|
||||||
|
elements.addAll(TagCreatorCodeGenerator.emptyTags());
|
||||||
|
elements.addAll(TagCreatorCodeGenerator.containerTags());
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> specifiedElements(WattsiSource source){
|
||||||
|
Set<String> elements = new HashSet<>();
|
||||||
|
for(ElementDefinition element : source.elementDefinitions()){
|
||||||
|
elements.add(element.name());
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
// TODO restore this test once a policy has been determined for obsolete elements.
|
||||||
|
public void all_wattsi_elements_are_defined_in_the_code_generator() {
|
||||||
|
Set<String> generated = generatedElements();
|
||||||
|
|
||||||
|
List<String> undefined = specification.elementDefinitions().stream()
|
||||||
|
.filter(element -> !element.isObsolete())
|
||||||
|
.filter(element -> !generated.contains(element.name()))
|
||||||
|
.map(ElementDefinition::name)
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertEquals("HTML elements are missing", emptyList(), undefined);
|
||||||
|
// Currently missing (and mostly deprecated):
|
||||||
|
// hgroup
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void only_wattsi_elements_are_defined_in_the_code_generator(){
|
||||||
|
Set<String> specified = specifiedElements(specification);
|
||||||
|
|
||||||
|
List<String> invalid = generatedElements().stream()
|
||||||
|
.filter(element -> !specified.contains(element))
|
||||||
|
.collect(toList());
|
||||||
|
|
||||||
|
assertEquals("HTML elements are invalid", emptyList(), invalid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
128553
code_gen/src/test/resources/2022-01.wattsi
Normal file
128553
code_gen/src/test/resources/2022-01.wattsi
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,9 +11,9 @@
|
|||||||
<header class="top-header"><nav class="width-limit"><a id="logo" href="/"><span><img src="/img/logo.svg" alt="j2html logo"></span></a><ul><li><a href="/">Home</a></li><li><a href="/download.html">Download</a></li><li><a href="/examples.html">Examples</a></li><li><a href="/news.html">News</a></li></ul></nav></header><header class="banner"><h1 class="width-limit">Maven and GitHub</h1></header><main class="width-limit"><section id="download"><h2>Maven dependency</h2><p>To experience the joy of generating HTML with a Java HTML builder, add the j2html dependency to your POM:</p><pre><code class="language-markup"><dependency>
|
<header class="top-header"><nav class="width-limit"><a id="logo" href="/"><span><img src="/img/logo.svg" alt="j2html logo"></span></a><ul><li><a href="/">Home</a></li><li><a href="/download.html">Download</a></li><li><a href="/examples.html">Examples</a></li><li><a href="/news.html">News</a></li></ul></nav></header><header class="banner"><h1 class="width-limit">Maven and GitHub</h1></header><main class="width-limit"><section id="download"><h2>Maven dependency</h2><p>To experience the joy of generating HTML with a Java HTML builder, add the j2html dependency to your POM:</p><pre><code class="language-markup"><dependency>
|
||||||
<groupId>com.j2html</groupId>
|
<groupId>com.j2html</groupId>
|
||||||
<artifactId>j2html</artifactId>
|
<artifactId>j2html</artifactId>
|
||||||
<version>1.4.0</version>
|
<version>1.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</code></pre><h2>Clone the repo on GitHub</h2><p>Please clone and/or fork the repo on <a href="https://github.com/tipsy/j2html" target="_blank">GitHub</a>, make changes, and create pull requests! We will go through pull requests every sunday, so don't be shy.</p></section></main><div id="javalin-suggestion"><span class="close">✖</span> Want a simple and modern web framework? <br> Try our other project: <a href="https://javalin.io?from=j2html">https://javalin.io</a></div><footer>This page was created using <a href="https://github.com/tipsy/j2html" target="_blank">j2html</a> and <a href="https://javalin.io/" target="_blank">Javalin</a>. Webpage source on <a href="https://github.com/j2html/j2html-webpage" target="_blank">Github</a>. <br> <p class="lols">A static page generator or a template engine would be better suited than a HTML builder for creating this page, but we had to do it.</p></footer><script>/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+java */
|
</code></pre><a id="upgrade"></a><h2>Steps for upgrading</h2><p>From 1.4.0 to 1.5.0</p><ul><li>Change return types from <code>Tag</code>, <code>ContainerTag</code> or <code>EmptyTag</code> to the specific tag being returned.</li><li>Change missing method calls on tags, such as <code>withRole("value")</code> to <code>.attr("role", "value")</code>.</li><li>Method parameters of <code>Tag</code>, <code>ContainerTag</code> or <code>EmptyTag</code> should have a wildcard (<?>) added, or be changed to a specific tag.</li><li>Replace ambiguous method references like <code>each(list, TagCreator::li)</code> with lambdas such as <code>each(list, str -> li(str))</code>.</li></ul><h2>Clone the repo on GitHub</h2><p>Please clone and/or fork the repo on <a href="https://github.com/tipsy/j2html" target="_blank">GitHub</a>, make changes, and create pull requests! We will go through pull requests every sunday, so don't be shy.</p></section></main><div id="javalin-suggestion"><span class="close">✖</span> Want a simple and modern web framework? <br> Try our other project: <a href="https://javalin.io?from=j2html">https://javalin.io</a></div><footer>This page was created using <a href="https://github.com/tipsy/j2html" target="_blank">j2html</a> and <a href="https://javalin.io/" target="_blank">Javalin</a>. Webpage source on <a href="https://github.com/j2html/j2html-webpage" target="_blank">Github</a>. <br> <p class="lols">A static page generator or a template engine would be better suited than a HTML builder for creating this page, but we had to do it.</p></footer><script>/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+java */
|
||||||
self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=t.util.clone(e[r]));return a;case"Array":return e.map(function(e){return t.util.clone(e)})}return e}},languages:{extend:function(e,n){var a=t.util.clone(t.languages[e]);for(var r in n)a[r]=n[r];return a},insertBefore:function(e,n,a,r){r=r||t.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var s={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var l in a)a.hasOwnProperty(l)&&(s[l]=a[l]);s[o]=i[o]}return t.languages.DFS(t.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=s)}),r[e]=s},DFS:function(e,n,a){for(var r in e)e.hasOwnProperty(r)&&(n.call(e,r,e[r],a||r),"Object"===t.util.type(e[r])?t.languages.DFS(e[r],n):"Array"===t.util.type(e[r])&&t.languages.DFS(e[r],n,r))}},highlightAll:function(e,n){for(var a,r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'),i=0;a=r[i++];)t.highlightElement(a,e===!0,n)},highlightElement:function(a,r,i){for(var l,s,o=a;o&&!e.test(o.className);)o=o.parentNode;if(o&&(l=(o.className.match(e)||[,""])[1],s=t.languages[l]),s){a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,o=a.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l);var u=a.textContent;if(u){u=u.replace(/^(?:\r?\n|\r)/,"");var g={element:a,language:l,grammar:s,code:u};if(t.hooks.run("before-highlight",g),r&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){g.highlightedCode=n.stringify(JSON.parse(e.data),l),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(g.element),t.hooks.run("after-highlight",g)},c.postMessage(JSON.stringify({language:g.language,code:g.code}))}else g.highlightedCode=t.highlight(g.code,g.grammar,g.language),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(a),t.hooks.run("after-highlight",g)}}},highlight:function(e,a,r){var i=t.tokenize(e,a);return n.stringify(t.util.encode(i),r)},tokenize:function(e,n){var a=t.Token,r=[e],i=n.rest;if(i){for(var l in i)n[l]=i[l];delete n.rest}e:for(var l in n)if(n.hasOwnProperty(l)&&n[l]){var s=n[l];s="Array"===t.util.type(s)?s:[s];for(var o=0;o<s.length;++o){var u=s[o],g=u.inside,c=!!u.lookbehind,f=0,h=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var d=r[p];if(r.length>e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+"</"+i.tag+">"},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);;
|
self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=t.util.clone(e[r]));return a;case"Array":return e.map(function(e){return t.util.clone(e)})}return e}},languages:{extend:function(e,n){var a=t.util.clone(t.languages[e]);for(var r in n)a[r]=n[r];return a},insertBefore:function(e,n,a,r){r=r||t.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var s={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var l in a)a.hasOwnProperty(l)&&(s[l]=a[l]);s[o]=i[o]}return t.languages.DFS(t.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=s)}),r[e]=s},DFS:function(e,n,a){for(var r in e)e.hasOwnProperty(r)&&(n.call(e,r,e[r],a||r),"Object"===t.util.type(e[r])?t.languages.DFS(e[r],n):"Array"===t.util.type(e[r])&&t.languages.DFS(e[r],n,r))}},highlightAll:function(e,n){for(var a,r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'),i=0;a=r[i++];)t.highlightElement(a,e===!0,n)},highlightElement:function(a,r,i){for(var l,s,o=a;o&&!e.test(o.className);)o=o.parentNode;if(o&&(l=(o.className.match(e)||[,""])[1],s=t.languages[l]),s){a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,o=a.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l);var u=a.textContent;if(u){u=u.replace(/^(?:\r?\n|\r)/,"");var g={element:a,language:l,grammar:s,code:u};if(t.hooks.run("before-highlight",g),r&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){g.highlightedCode=n.stringify(JSON.parse(e.data),l),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(g.element),t.hooks.run("after-highlight",g)},c.postMessage(JSON.stringify({language:g.language,code:g.code}))}else g.highlightedCode=t.highlight(g.code,g.grammar,g.language),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(a),t.hooks.run("after-highlight",g)}}},highlight:function(e,a,r){var i=t.tokenize(e,a);return n.stringify(t.util.encode(i),r)},tokenize:function(e,n){var a=t.Token,r=[e],i=n.rest;if(i){for(var l in i)n[l]=i[l];delete n.rest}e:for(var l in n)if(n.hasOwnProperty(l)&&n[l]){var s=n[l];s="Array"===t.util.type(s)?s:[s];for(var o=0;o<s.length;++o){var u=s[o],g=u.inside,c=!!u.lookbehind,f=0,h=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var d=r[p];if(r.length>e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+"</"+i.tag+">"},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);;
|
||||||
Prism.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});;
|
Prism.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});;
|
||||||
Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/<style[\w\W]*?>[\w\W]*?<\/style>/i,inside:{tag:{pattern:/<style[\w\W]*?>|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));;
|
Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/<style[\w\W]*?>[\w\W]*?<\/style>/i,inside:{tag:{pattern:/<style[\w\W]*?>|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));;
|
||||||
|
|||||||
@@ -45,8 +45,12 @@
|
|||||||
import static j2html.TagCreator.*; // Use static star import
|
import static j2html.TagCreator.*; // Use static star import
|
||||||
|
|
||||||
|
|
||||||
Config.class // Static config class which holds all configuration
|
Config.class // Holds all configuration. Offers global configuration or customizable instances
|
||||||
Config.closeEmptyTags = true // all options are public and static, assign using '=' operator
|
Config.closeEmptyTags = true // Global options are public, static and mutable.
|
||||||
|
Config.global() // Copy all static Config fields into an instance. Instances are immutable
|
||||||
|
Config.defaults() // A Config with defaults that are independent of global options
|
||||||
|
Config.global().withEmptyTagsClosed(true) // A Config that is different from the global options
|
||||||
|
Config.defaults().withEmptyTagsClosed(true) // A Config that is different from the default options
|
||||||
|
|
||||||
|
|
||||||
TagCreator.join() // Method for joining small snippets, like:
|
TagCreator.join() // Method for joining small snippets, like:
|
||||||
@@ -64,6 +68,17 @@ div().withClasses("menu-element", iffElse(isActive, "active"
|
|||||||
Tag.class // Is extended by ContainerTag (ex <div></div> and EmptyTag (ex <br>)
|
Tag.class // Is extended by ContainerTag (ex <div></div> and EmptyTag (ex <br>)
|
||||||
Tag.attr(String attribute, Object value) // Set an attribute on the tag
|
Tag.attr(String attribute, Object value) // Set an attribute on the tag
|
||||||
Tag.withXyz(String value) // Calls attr with predefined attribute (ex .withId, .withClass, etc.)
|
Tag.withXyz(String value) // Calls attr with predefined attribute (ex .withId, .withClass, etc.)
|
||||||
|
Tag.render(HtmlBuilder builder) // Render HTML using the given builder.
|
||||||
|
Tag.render() // Shortcut for rendering flat HTML into a string using global Config.
|
||||||
|
ContainerTag.renderFormatted() // Shortcut for rendering indented HTML into a string using global Config.
|
||||||
|
|
||||||
|
HtmlBuilder.class // Interface for composing HTML. Implemented by FlatHtml and IndentedHtml
|
||||||
|
FlatHtml.into(Appendable) // Render into a stream, file, etc. without indentation or line breaks
|
||||||
|
FlatHtml.into(Appendable appendable, Config config) // Customize rendering of flat html
|
||||||
|
IndentedHtml.into(Appendable) // Render human-readable HTML into an stream, file, etc.
|
||||||
|
IndentedHtml.into(Appendable appendable, Config config) // Customize rendering of intended html
|
||||||
|
ul(li("one"), li("two")).render(IndentedHtml.inMemory()).toString() // Similar to renderFormatted()
|
||||||
|
ul(li("one"), li("two")).render(IndentedHtml.into(filewriter)) // Write HTML into a file
|
||||||
</code></pre><h2 id="loops">Loops, each() and filter()</h2><p>Using Java 8's lambda syntax, you can write loops (via streams) inside your HTML-builder:</p><div class="code-compare nowith"><ul><li class="nowith-switch active">version 1.0.0 +</li><li class="with-switch">earlier versions</li></ul><pre class="nowith-pre"><code class="language-java">body(
|
</code></pre><h2 id="loops">Loops, each() and filter()</h2><p>Using Java 8's lambda syntax, you can write loops (via streams) inside your HTML-builder:</p><div class="code-compare nowith"><ul><li class="nowith-switch active">version 1.0.0 +</li><li class="with-switch">earlier versions</li></ul><pre class="nowith-pre"><code class="language-java">body(
|
||||||
div(attrs("#employees"),
|
div(attrs("#employees"),
|
||||||
employees.stream().map(employee ->
|
employees.stream().map(employee ->
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<groupId>com.j2html</groupId>
|
<groupId>com.j2html</groupId>
|
||||||
<artifactId>j2html</artifactId>
|
<artifactId>j2html</artifactId>
|
||||||
<version>1.5.0</version>
|
<version>1.6.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<name>j2html</name>
|
<name>j2html</name>
|
||||||
<description>Java to HTML builder with a fluent API</description>
|
<description>Java to HTML builder with a fluent API</description>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<connection>scm:git:git@github.com:tipsy/j2html.git</connection>
|
<connection>scm:git:git@github.com:tipsy/j2html.git</connection>
|
||||||
<developerConnection>scm:git:git@github.com:tipsy/j2html.git</developerConnection>
|
<developerConnection>scm:git:git@github.com:tipsy/j2html.git</developerConnection>
|
||||||
<url>https://github.com/tipsy/j2html.git</url>
|
<url>https://github.com/tipsy/j2html.git</url>
|
||||||
<tag>j2html-1.5.0</tag>
|
<tag>HEAD</tag>
|
||||||
</scm>
|
</scm>
|
||||||
<developers>
|
<developers>
|
||||||
<developer>
|
<developer>
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.3</version>
|
<version>3.10.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source>
|
||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
<version>1.4</version>
|
<version>3.1.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>enforce-java</id>
|
<id>enforce-java</id>
|
||||||
@@ -131,14 +131,14 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>2.10.3</version>
|
<version>3.4.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>2.4</version>
|
<version>3.2.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
<version>2.5.0</version>
|
<version>5.1.6</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>bundle-manifest</id>
|
<id>bundle-manifest</id>
|
||||||
@@ -165,6 +165,44 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.revapi</groupId>
|
||||||
|
<artifactId>revapi-maven-plugin</artifactId>
|
||||||
|
<version>0.14.6</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.revapi</groupId>
|
||||||
|
<artifactId>revapi-java</artifactId>
|
||||||
|
<version>0.26.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<configuration>
|
||||||
|
<oldArtifacts>
|
||||||
|
<artifact>com.j2html:j2html:1.6.0</artifact>
|
||||||
|
</oldArtifacts>
|
||||||
|
<analysisConfiguration>
|
||||||
|
<revapi.differences>
|
||||||
|
<differences>
|
||||||
|
<item>
|
||||||
|
<ignore>true</ignore>
|
||||||
|
<code>java.class.removed</code>
|
||||||
|
<old>class j2html.tags.specialized.GenerateTag</old>
|
||||||
|
<justification>
|
||||||
|
This class should never have been used. It was introduced
|
||||||
|
accidentally by find+replace in the code generator class.
|
||||||
|
</justification>
|
||||||
|
</item>
|
||||||
|
</differences>
|
||||||
|
</revapi.differences>
|
||||||
|
</analysisConfiguration>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>check</id>
|
||||||
|
<goals><goal>check</goal></goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@@ -182,7 +220,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
<version>1.6</version>
|
<version>3.0.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>sign-artifacts</id>
|
<id>sign-artifacts</id>
|
||||||
|
|||||||
@@ -461,6 +461,13 @@ public class TagCreator {
|
|||||||
public static ColgroupTag colgroup (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new ColgroupTag().withText(text), shortAttr); }
|
public static ColgroupTag colgroup (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new ColgroupTag().withText(text), shortAttr); }
|
||||||
public static ColgroupTag colgroup (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new ColgroupTag().with(dc), shortAttr); }
|
public static ColgroupTag colgroup (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new ColgroupTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
|
public static DataTag data () { return new DataTag(); }
|
||||||
|
public static DataTag data (String text) { return new DataTag().withText(text); }
|
||||||
|
public static DataTag data (DomContent... dc) { return new DataTag().with(dc); }
|
||||||
|
public static DataTag data (Attr.ShortForm shortAttr) { return Attr.addTo( new DataTag(), shortAttr); }
|
||||||
|
public static DataTag data (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new DataTag().withText(text), shortAttr); }
|
||||||
|
public static DataTag data (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new DataTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
public static DatalistTag datalist () { return new DatalistTag(); }
|
public static DatalistTag datalist () { return new DatalistTag(); }
|
||||||
public static DatalistTag datalist (String text) { return new DatalistTag().withText(text); }
|
public static DatalistTag datalist (String text) { return new DatalistTag().withText(text); }
|
||||||
public static DatalistTag datalist (DomContent... dc) { return new DatalistTag().with(dc); }
|
public static DatalistTag datalist (DomContent... dc) { return new DatalistTag().with(dc); }
|
||||||
@@ -762,6 +769,13 @@ public class TagCreator {
|
|||||||
public static PTag p (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new PTag().withText(text), shortAttr); }
|
public static PTag p (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new PTag().withText(text), shortAttr); }
|
||||||
public static PTag p (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new PTag().with(dc), shortAttr); }
|
public static PTag p (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new PTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
|
public static PictureTag picture () { return new PictureTag(); }
|
||||||
|
public static PictureTag picture (String text) { return new PictureTag().withText(text); }
|
||||||
|
public static PictureTag picture (DomContent... dc) { return new PictureTag().with(dc); }
|
||||||
|
public static PictureTag picture (Attr.ShortForm shortAttr) { return Attr.addTo( new PictureTag(), shortAttr); }
|
||||||
|
public static PictureTag picture (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new PictureTag().withText(text), shortAttr); }
|
||||||
|
public static PictureTag picture (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new PictureTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
public static PreTag pre () { return new PreTag(); }
|
public static PreTag pre () { return new PreTag(); }
|
||||||
public static PreTag pre (String text) { return new PreTag().withText(text); }
|
public static PreTag pre (String text) { return new PreTag().withText(text); }
|
||||||
public static PreTag pre (DomContent... dc) { return new PreTag().with(dc); }
|
public static PreTag pre (DomContent... dc) { return new PreTag().with(dc); }
|
||||||
@@ -839,6 +853,13 @@ public class TagCreator {
|
|||||||
public static SelectTag select (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new SelectTag().withText(text), shortAttr); }
|
public static SelectTag select (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new SelectTag().withText(text), shortAttr); }
|
||||||
public static SelectTag select (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new SelectTag().with(dc), shortAttr); }
|
public static SelectTag select (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new SelectTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
|
public static SlotTag slot () { return new SlotTag(); }
|
||||||
|
public static SlotTag slot (String text) { return new SlotTag().withText(text); }
|
||||||
|
public static SlotTag slot (DomContent... dc) { return new SlotTag().with(dc); }
|
||||||
|
public static SlotTag slot (Attr.ShortForm shortAttr) { return Attr.addTo( new SlotTag(), shortAttr); }
|
||||||
|
public static SlotTag slot (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new SlotTag().withText(text), shortAttr); }
|
||||||
|
public static SlotTag slot (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new SlotTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
public static SmallTag small () { return new SmallTag(); }
|
public static SmallTag small () { return new SmallTag(); }
|
||||||
public static SmallTag small (String text) { return new SmallTag().withText(text); }
|
public static SmallTag small (String text) { return new SmallTag().withText(text); }
|
||||||
public static SmallTag small (DomContent... dc) { return new SmallTag().with(dc); }
|
public static SmallTag small (DomContent... dc) { return new SmallTag().with(dc); }
|
||||||
@@ -909,6 +930,13 @@ public class TagCreator {
|
|||||||
public static TdTag td (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new TdTag().withText(text), shortAttr); }
|
public static TdTag td (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new TdTag().withText(text), shortAttr); }
|
||||||
public static TdTag td (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new TdTag().with(dc), shortAttr); }
|
public static TdTag td (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new TdTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
|
public static TemplateTag template () { return new TemplateTag(); }
|
||||||
|
public static TemplateTag template (String text) { return new TemplateTag().withText(text); }
|
||||||
|
public static TemplateTag template (DomContent... dc) { return new TemplateTag().with(dc); }
|
||||||
|
public static TemplateTag template (Attr.ShortForm shortAttr) { return Attr.addTo( new TemplateTag(), shortAttr); }
|
||||||
|
public static TemplateTag template (Attr.ShortForm shortAttr, String text) { return Attr.addTo( new TemplateTag().withText(text), shortAttr); }
|
||||||
|
public static TemplateTag template (Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo( new TemplateTag().with(dc), shortAttr); }
|
||||||
|
|
||||||
public static TextareaTag textarea () { return new TextareaTag(); }
|
public static TextareaTag textarea () { return new TextareaTag(); }
|
||||||
public static TextareaTag textarea (String text) { return new TextareaTag().withText(text); }
|
public static TextareaTag textarea (String text) { return new TextareaTag().withText(text); }
|
||||||
public static TextareaTag textarea (DomContent... dc) { return new TextareaTag().with(dc); }
|
public static TextareaTag textarea (DomContent... dc) { return new TextareaTag().with(dc); }
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public abstract class Attr {
|
|||||||
public static final String HTTP_EQUIV = "http-equiv";
|
public static final String HTTP_EQUIV = "http-equiv";
|
||||||
public static final String ICON = "icon";
|
public static final String ICON = "icon";
|
||||||
public static final String ID = "id";
|
public static final String ID = "id";
|
||||||
|
public static final String IS = "is";
|
||||||
public static final String ISMAP = "ismap";
|
public static final String ISMAP = "ismap";
|
||||||
public static final String ITEMPROP = "itemprop";
|
public static final String ITEMPROP = "itemprop";
|
||||||
public static final String KEYTYPE = "keytype";
|
public static final String KEYTYPE = "keytype";
|
||||||
@@ -96,6 +97,7 @@ public abstract class Attr {
|
|||||||
public static final String SHAPE = "shape";
|
public static final String SHAPE = "shape";
|
||||||
public static final String SIZE = "size";
|
public static final String SIZE = "size";
|
||||||
public static final String SIZES = "sizes";
|
public static final String SIZES = "sizes";
|
||||||
|
public static final String SLOT = "slot";
|
||||||
public static final String SPAN = "span";
|
public static final String SPAN = "span";
|
||||||
public static final String SPELLCHECK = "spellcheck";
|
public static final String SPELLCHECK = "spellcheck";
|
||||||
public static final String SRC = "src";
|
public static final String SRC = "src";
|
||||||
|
|||||||
@@ -162,8 +162,12 @@ public abstract class Tag<T extends Tag<T>> extends DomContent implements IInsta
|
|||||||
|
|
||||||
public T withId(String id) { return attr(Attr.ID, id); }
|
public T withId(String id) { return attr(Attr.ID, id); }
|
||||||
|
|
||||||
|
public T withIs(String element){ return attr(Attr.IS, element); }
|
||||||
|
|
||||||
public T withLang(String lang) { return attr(Attr.LANG, lang); }
|
public T withLang(String lang) { return attr(Attr.LANG, lang); }
|
||||||
|
|
||||||
|
public T withSlot(String name){ return attr(Attr.SLOT, name); }
|
||||||
|
|
||||||
public T isSpellcheck(){ return attr(Attr.SPELLCHECK, "true"); }
|
public T isSpellcheck(){ return attr(Attr.SPELLCHECK, "true"); }
|
||||||
|
|
||||||
public T withStyle(String style) { return attr(Attr.STYLE, style); }
|
public T withStyle(String style) { return attr(Attr.STYLE, style); }
|
||||||
@@ -191,8 +195,12 @@ public abstract class Tag<T extends Tag<T>> extends DomContent implements IInsta
|
|||||||
|
|
||||||
public T withCondId(boolean condition, String id) { return condAttr(condition, Attr.ID, id); }
|
public T withCondId(boolean condition, String id) { return condAttr(condition, Attr.ID, id); }
|
||||||
|
|
||||||
|
public T withCondIs(boolean condition, String element){ return condAttr(condition, Attr.IS, element); }
|
||||||
|
|
||||||
public T withCondLang(boolean condition, String lang) { return condAttr(condition, Attr.LANG, lang); }
|
public T withCondLang(boolean condition, String lang) { return condAttr(condition, Attr.LANG, lang); }
|
||||||
|
|
||||||
|
public T withCondSlot(boolean condition, String name){ return condAttr(condition, Attr.SLOT, name); }
|
||||||
|
|
||||||
public T withCondSpellcheck(boolean condition){ return attr(Attr.SPELLCHECK, (condition)?"true":"false"); }
|
public T withCondSpellcheck(boolean condition){ return attr(Attr.SPELLCHECK, (condition)?"true":"false"); }
|
||||||
|
|
||||||
public T withCondStyle(boolean condition, String style) { return condAttr(condition, Attr.STYLE, style); }
|
public T withCondStyle(boolean condition, String style) { return condAttr(condition, Attr.STYLE, style); }
|
||||||
|
|||||||
11
library/src/main/java/j2html/tags/specialized/DataTag.java
Normal file
11
library/src/main/java/j2html/tags/specialized/DataTag.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package j2html.tags.specialized;
|
||||||
|
|
||||||
|
import j2html.tags.ContainerTag;
|
||||||
|
import j2html.tags.attributes.IValue;
|
||||||
|
|
||||||
|
public final class DataTag extends ContainerTag<DataTag>
|
||||||
|
implements IValue<DataTag> {
|
||||||
|
public DataTag() {
|
||||||
|
super("data");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package j2html.tags.specialized;
|
|
||||||
|
|
||||||
import j2html.tags.ContainerTag;
|
|
||||||
|
|
||||||
public final class GenerateTag extends ContainerTag<GenerateTag> {
|
|
||||||
public GenerateTag() {
|
|
||||||
super("generate");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package j2html.tags.specialized;
|
||||||
|
|
||||||
|
import j2html.tags.ContainerTag;
|
||||||
|
|
||||||
|
public final class PictureTag extends ContainerTag<PictureTag> {
|
||||||
|
public PictureTag() {
|
||||||
|
super("picture");
|
||||||
|
}
|
||||||
|
}
|
||||||
11
library/src/main/java/j2html/tags/specialized/SlotTag.java
Normal file
11
library/src/main/java/j2html/tags/specialized/SlotTag.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package j2html.tags.specialized;
|
||||||
|
|
||||||
|
import j2html.tags.ContainerTag;
|
||||||
|
import j2html.tags.attributes.IName;
|
||||||
|
|
||||||
|
public final class SlotTag extends ContainerTag<SlotTag>
|
||||||
|
implements IName<SlotTag> {
|
||||||
|
public SlotTag() {
|
||||||
|
super("slot");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package j2html.tags.specialized;
|
||||||
|
|
||||||
|
import j2html.tags.ContainerTag;
|
||||||
|
|
||||||
|
public final class TemplateTag extends ContainerTag<TemplateTag> {
|
||||||
|
public TemplateTag() {
|
||||||
|
super("template");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -288,13 +288,13 @@ public class JSMin {
|
|||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UnterminatedCommentException extends Exception {
|
public class UnterminatedCommentException extends Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UnterminatedStringLiteralException extends Exception {
|
public class UnterminatedStringLiteralException extends Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UnterminatedRegExpLiteralException extends Exception {
|
public class UnterminatedRegExpLiteralException extends Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ public class TagCreatorTest {
|
|||||||
assertThat(cite("Text").render(), is("<cite>Text</cite>"));
|
assertThat(cite("Text").render(), is("<cite>Text</cite>"));
|
||||||
assertThat(code().render(), is("<code></code>"));
|
assertThat(code().render(), is("<code></code>"));
|
||||||
assertThat(colgroup().render(), is("<colgroup></colgroup>"));
|
assertThat(colgroup().render(), is("<colgroup></colgroup>"));
|
||||||
|
assertThat(data().render(), is("<data></data>"));
|
||||||
assertThat(datalist().render(), is("<datalist></datalist>"));
|
assertThat(datalist().render(), is("<datalist></datalist>"));
|
||||||
assertThat(dd().render(), is("<dd></dd>"));
|
assertThat(dd().render(), is("<dd></dd>"));
|
||||||
assertThat(dd("Text").render(), is("<dd>Text</dd>"));
|
assertThat(dd("Text").render(), is("<dd>Text</dd>"));
|
||||||
@@ -287,6 +288,7 @@ public class TagCreatorTest {
|
|||||||
assertThat(output().render(), is("<output></output>"));
|
assertThat(output().render(), is("<output></output>"));
|
||||||
assertThat(p().render(), is("<p></p>"));
|
assertThat(p().render(), is("<p></p>"));
|
||||||
assertThat(p("Text").render(), is("<p>Text</p>"));
|
assertThat(p("Text").render(), is("<p>Text</p>"));
|
||||||
|
assertThat(picture().render(), is("<picture></picture>"));
|
||||||
assertThat(pre().render(), is("<pre></pre>"));
|
assertThat(pre().render(), is("<pre></pre>"));
|
||||||
assertThat(progress().render(), is("<progress></progress>"));
|
assertThat(progress().render(), is("<progress></progress>"));
|
||||||
assertThat(q().render(), is("<q></q>"));
|
assertThat(q().render(), is("<q></q>"));
|
||||||
@@ -300,6 +302,8 @@ public class TagCreatorTest {
|
|||||||
assertThat(script().render(), is("<script></script>"));
|
assertThat(script().render(), is("<script></script>"));
|
||||||
assertThat(section().render(), is("<section></section>"));
|
assertThat(section().render(), is("<section></section>"));
|
||||||
assertThat(select().render(), is("<select></select>"));
|
assertThat(select().render(), is("<select></select>"));
|
||||||
|
assertThat(slot().render(), is("<slot></slot>"));
|
||||||
|
assertThat(slot("Text").render(), is("<slot>Text</slot>"));
|
||||||
assertThat(small().render(), is("<small></small>"));
|
assertThat(small().render(), is("<small></small>"));
|
||||||
assertThat(small("Text").render(), is("<small>Text</small>"));
|
assertThat(small("Text").render(), is("<small>Text</small>"));
|
||||||
assertThat(span().render(), is("<span></span>"));
|
assertThat(span().render(), is("<span></span>"));
|
||||||
@@ -317,6 +321,7 @@ public class TagCreatorTest {
|
|||||||
assertThat(tbody().render(), is("<tbody></tbody>"));
|
assertThat(tbody().render(), is("<tbody></tbody>"));
|
||||||
assertThat(td().render(), is("<td></td>"));
|
assertThat(td().render(), is("<td></td>"));
|
||||||
assertThat(td("Text").render(), is("<td>Text</td>"));
|
assertThat(td("Text").render(), is("<td>Text</td>"));
|
||||||
|
assertThat(template("Text").render(), is("<template>Text</template>"));
|
||||||
assertThat(textarea().render(), is("<textarea></textarea>"));
|
assertThat(textarea().render(), is("<textarea></textarea>"));
|
||||||
assertThat(tfoot().render(), is("<tfoot></tfoot>"));
|
assertThat(tfoot().render(), is("<tfoot></tfoot>"));
|
||||||
assertThat(th().render(), is("<th></th>"));
|
assertThat(th().render(), is("<th></th>"));
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Website is available on http://localhost:8888/.
|
|||||||
In order to "deploy" the website, the static files in the `j2html/docs` must be updated.
|
In order to "deploy" the website, the static files in the `j2html/docs` must be updated.
|
||||||
You can either download the files manually from your browser, or use curl:
|
You can either download the files manually from your browser, or use curl:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl "http://localhost:8888/" > index.html
|
curl "http://localhost:8888/" > index.html
|
||||||
curl "http://localhost:8888/download.html" > download.html
|
curl "http://localhost:8888/download.html" > download.html
|
||||||
curl "http://localhost:8888/examples.html" > examples.html
|
curl "http://localhost:8888/examples.html" > examples.html
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.j2html</groupId>
|
<groupId>com.j2html</groupId>
|
||||||
<artifactId>j2html</artifactId>
|
<artifactId>j2html</artifactId>
|
||||||
<version>1.4.0</version>
|
<version>1.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.1</version>
|
<version>3.10.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source>
|
||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ import io.javalin.http.staticfiles.Location;
|
|||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
Javalin app = Javalin.create(config ->
|
Javalin app = Javalin.create(config ->
|
||||||
config.addStaticFiles("src/main/resources/public", Location.EXTERNAL)
|
config.addStaticFiles("website/src/main/resources/public", Location.EXTERNAL)
|
||||||
).start(8888);
|
).start(8888);
|
||||||
|
|
||||||
app.get("/", PageController::serveIndex);
|
app.get("/", PageController::serveIndex);
|
||||||
|
|||||||
@@ -2,13 +2,7 @@ package app.views.pages;
|
|||||||
|
|
||||||
import app.views.MainView;
|
import app.views.MainView;
|
||||||
import static app.views.Partials.codeSnippet;
|
import static app.views.Partials.codeSnippet;
|
||||||
import static j2html.TagCreator.a;
|
import static j2html.TagCreator.*;
|
||||||
import static j2html.TagCreator.attrs;
|
|
||||||
import static j2html.TagCreator.fileAsEscapedString;
|
|
||||||
import static j2html.TagCreator.h2;
|
|
||||||
import static j2html.TagCreator.join;
|
|
||||||
import static j2html.TagCreator.p;
|
|
||||||
import static j2html.TagCreator.section;
|
|
||||||
|
|
||||||
public class DownloadView {
|
public class DownloadView {
|
||||||
public static String render() {
|
public static String render() {
|
||||||
@@ -19,6 +13,23 @@ public class DownloadView {
|
|||||||
h2("Maven dependency"),
|
h2("Maven dependency"),
|
||||||
p("To experience the joy of generating HTML with a Java HTML builder, add the j2html dependency to your POM:"),
|
p("To experience the joy of generating HTML with a Java HTML builder, add the j2html dependency to your POM:"),
|
||||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/mavenDep.xml")),
|
codeSnippet("markup", fileAsEscapedString("/codeExamples/mavenDep.xml")),
|
||||||
|
a().withId("upgrade"),
|
||||||
|
h2("Steps for upgrading"),
|
||||||
|
p("From 1.4.0 to 1.5.0"),
|
||||||
|
ul(
|
||||||
|
li(
|
||||||
|
join("Change return types from", code("Tag"), ",", code("ContainerTag"), "or", code("EmptyTag"), "to the specific tag being returned.")
|
||||||
|
),
|
||||||
|
li(
|
||||||
|
join("Change missing method calls on tags, such as", code("withRole(\"value\")"), "to", code(".attr(\"role\", \"value\")"), ".")
|
||||||
|
),
|
||||||
|
li(
|
||||||
|
join("Method parameters of", code("Tag"), ",", code("ContainerTag"), "or", code("EmptyTag"), "should have a wildcard (<?>) added, or be changed to a specific tag.")
|
||||||
|
),
|
||||||
|
li(
|
||||||
|
join("Replace ambiguous method references like ", code("each(list, TagCreator::li)"), " with lambdas such as", code("each(list, str -> li(str))"), ".")
|
||||||
|
)
|
||||||
|
),
|
||||||
h2("Clone the repo on GitHub"),
|
h2("Clone the repo on GitHub"),
|
||||||
p(join(
|
p(join(
|
||||||
"Please clone and/or fork the repo on",
|
"Please clone and/or fork the repo on",
|
||||||
|
|||||||
@@ -2,39 +2,35 @@ package app.views.pages;
|
|||||||
|
|
||||||
import app.views.MainView;
|
import app.views.MainView;
|
||||||
import j2html.TagCreator;
|
import j2html.TagCreator;
|
||||||
import j2html.tags.ContainerTag;
|
|
||||||
import j2html.tags.DomContent;
|
import j2html.tags.DomContent;
|
||||||
|
import j2html.tags.specialized.ArticleTag;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static app.views.Partials.mavenLink;
|
import static app.views.Partials.mavenLink;
|
||||||
import static j2html.TagCreator.a;
|
import static j2html.TagCreator.*;
|
||||||
import static j2html.TagCreator.article;
|
|
||||||
import static j2html.TagCreator.attrs;
|
|
||||||
import static j2html.TagCreator.br;
|
|
||||||
import static j2html.TagCreator.code;
|
|
||||||
import static j2html.TagCreator.dd;
|
|
||||||
import static j2html.TagCreator.dl;
|
|
||||||
import static j2html.TagCreator.dt;
|
|
||||||
import static j2html.TagCreator.each;
|
|
||||||
import static j2html.TagCreator.em;
|
|
||||||
import static j2html.TagCreator.h2;
|
|
||||||
import static j2html.TagCreator.join;
|
|
||||||
import static j2html.TagCreator.li;
|
|
||||||
import static j2html.TagCreator.p;
|
|
||||||
import static j2html.TagCreator.section;
|
|
||||||
import static j2html.TagCreator.text;
|
|
||||||
import static j2html.TagCreator.ul;
|
|
||||||
|
|
||||||
public class NewsView {
|
public class NewsView {
|
||||||
|
|
||||||
private static ContainerTag newsPost(String title, String version, DomContent... listItems) {
|
private static ArticleTag newsPost(
|
||||||
|
String title,
|
||||||
|
String version,
|
||||||
|
boolean breaking,
|
||||||
|
DomContent... listItems
|
||||||
|
) {
|
||||||
List<DomContent> list = Arrays.asList(listItems);
|
List<DomContent> list = Arrays.asList(listItems);
|
||||||
return article(
|
return article(
|
||||||
h2(title).withId("j2html-" + version + "-released"),
|
h2(title).withId("j2html-" + version + "-released"),
|
||||||
mavenLink(version),
|
mavenLink(version),
|
||||||
|
iff(breaking,
|
||||||
|
p(
|
||||||
|
a("This version contains breaking changes. Please view the upgrade guide.").withHref("download.html#upgrade")
|
||||||
|
)
|
||||||
|
),
|
||||||
p("Changes:"),
|
p("Changes:"),
|
||||||
ul(
|
ul(
|
||||||
each(list, TagCreator::li)
|
each(list, el -> TagCreator.li(el))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,13 +41,45 @@ public class NewsView {
|
|||||||
section(attrs("#news"),
|
section(attrs("#news"),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.4.0 adds a couple of convenient methods (Jan 2019)", "1.4.0",
|
"j2html 1.6.0 adds support for web components and newer HTML elements. (Jun 2022)",
|
||||||
|
"1.6.0",
|
||||||
|
false,
|
||||||
|
join("Added", code("TagCreator::data"), "to provide machine-readable translations."),
|
||||||
|
join("Added", code("TagCreator::picture"), "to provide alternative versions of an image for different display/device scenarios."),
|
||||||
|
join("Added", code("TagCreator::slot"), "to provide placeholders for web components."),
|
||||||
|
join("Added", code("TagCreator::template"), "to provide templating of content fragments for web components."),
|
||||||
|
join("Added global attributes used for web components.")
|
||||||
|
),
|
||||||
|
|
||||||
|
newsPost(
|
||||||
|
"j2html 1.5.0 enhances factory methods and class types, overhauls HTML rendering, introduces support for Java modules and fixes several bugs (Jun 2021)",
|
||||||
|
"1.5.0",
|
||||||
|
true,
|
||||||
|
join("Added", code("Automatic-Module-Name"), "to manifest to support JDK 9+"),
|
||||||
|
join("Added", code("TagCreator::each(DomContent...)")),
|
||||||
|
join("Added", code("TagCreator::each(Collection, BiFunction)")),
|
||||||
|
join("Added", code("HtmlBuilder"), "interface, with implementations for ", code("FlatHtml"), "and", code("IndentedHtml")),
|
||||||
|
join("Added", code("Config.defaults()"), "for customizable configuration instances and", code("Config.global()"), "for (backwards-compatible) static global configuration"),
|
||||||
|
join("Deprecated old rendering methods. Libraries that use custom Tag implementations should switch to using ", code("HtmlBuilder")),
|
||||||
|
join("Fixed the use of", code("rawHtml()"), "when constructing the Tag tree"),
|
||||||
|
join("Fixed text escaping for", code("style()"), "and", code("script()")),
|
||||||
|
join("Fixed formatting of children for", code("textarea()"), "and", code("pre()")),
|
||||||
|
join("Fixed appending an unnecessary delimiter to the end of text with", code("join()")),
|
||||||
|
join("Thanks to", a("Oliver Becker").withHref("https://github.com/obecker"), "for many code improvements")
|
||||||
|
),
|
||||||
|
|
||||||
|
newsPost(
|
||||||
|
"j2html 1.4.0 adds a couple of convenient methods (Jan 2019)",
|
||||||
|
"1.4.0",
|
||||||
|
false,
|
||||||
join("Added", code("TagCreator::each(Map, BiFunction)")),
|
join("Added", code("TagCreator::each(Map, BiFunction)")),
|
||||||
join("Added", code("Stream<DomContent>"), "variants of", code("each"), "and", code("with"))
|
join("Added", code("Stream<DomContent>"), "variants of", code("each"), "and", code("with"))
|
||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.3.0 has a couple of features and fixes (May 2018)", "1.3.0",
|
"j2html 1.3.0 has a couple of features and fixes (May 2018)",
|
||||||
|
"1.3.0",
|
||||||
|
false,
|
||||||
join("Added support for", code("Map"), "in", code("each()")),
|
join("Added support for", code("Map"), "in", code("each()")),
|
||||||
join("Added osgi metadata"),
|
join("Added osgi metadata"),
|
||||||
join("Added support for", code("Optional"), "in", code("iff()")),
|
join("Added support for", code("Optional"), "in", code("iff()")),
|
||||||
@@ -59,19 +87,25 @@ public class NewsView {
|
|||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.2.2 has performance improvements (Dec 2017)", "1.2.2",
|
"j2html 1.2.2 has performance improvements (Dec 2017)",
|
||||||
|
"1.2.2",
|
||||||
|
false,
|
||||||
join("There have been some massive performance improvements. Big thanks to", a("kicktipp").withHref("https://github.com/kicktipp"), ".")
|
join("There have been some massive performance improvements. Big thanks to", a("kicktipp").withHref("https://github.com/kicktipp"), ".")
|
||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.2.1 fixes some bugs (Nov 2017)", "1.2.1",
|
"j2html 1.2.1 fixes some bugs (Nov 2017)",
|
||||||
|
"1.2.1",
|
||||||
|
false,
|
||||||
join("Fix", em("\"bad closing tag (<!DOCTYPE html/>) when closeEmptyTags is true\""), "bug"),
|
join("Fix", em("\"bad closing tag (<!DOCTYPE html/>) when closeEmptyTags is true\""), "bug"),
|
||||||
join("Fix", em("\"can't load static resources from jar\""), "bug"),
|
join("Fix", em("\"can't load static resources from jar\""), "bug"),
|
||||||
join("Fix", em("\"CSSMin stripping last character of CSS rule if rule doesn't end in semi-colon\""), "bug")
|
join("Fix", em("\"CSSMin stripping last character of CSS rule if rule doesn't end in semi-colon\""), "bug")
|
||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.2.0 already? (Sep 2017)", "1.2.0",
|
"j2html 1.2.0 already? (Sep 2017)",
|
||||||
|
"1.2.0",
|
||||||
|
false,
|
||||||
join("Added option to render formatted HTML, ex", code("body(...).renderFormatted()")),
|
join("Added option to render formatted HTML, ex", code("body(...).renderFormatted()")),
|
||||||
join("Added option to configure HTML-formatting-indent via", code("Config.indenter = (int, string) -> {...}")),
|
join("Added option to configure HTML-formatting-indent via", code("Config.indenter = (int, string) -> {...}")),
|
||||||
join("Added option to configure CSS-minification via", code("Config.cssMinifier = string -> {...}")),
|
join("Added option to configure CSS-minification via", code("Config.cssMinifier = string -> {...}")),
|
||||||
@@ -81,12 +115,16 @@ public class NewsView {
|
|||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.1.0 is out! (Aug 2017)", "1.1.0",
|
"j2html 1.1.0 is out! (Aug 2017)",
|
||||||
|
"1.1.0",
|
||||||
|
false,
|
||||||
join("Added a option to customize TextEscaper via", code("Config.textEscaper = text -> {}"))
|
join("Added a option to customize TextEscaper via", code("Config.textEscaper = text -> {}"))
|
||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 1.0.0 is here! (May 2017)", "1.0.0",
|
"j2html 1.0.0 is here! (May 2017)",
|
||||||
|
"1.0.0",
|
||||||
|
false,
|
||||||
join("v1 is officially done. We will be doing", a("semantic versioning").withHref("http://semver.org/").withTarget("_blank"), "from now on."),
|
join("v1 is officially done. We will be doing", a("semantic versioning").withHref("http://semver.org/").withTarget("_blank"), "from now on."),
|
||||||
join("All tag methods (", code("div()"), ",", code("p()"), "etc ) can now accept an arbitrary number of", code("DomContent"), "as arguments, eliminating the need for", code("with()"), "in most cases."),
|
join("All tag methods (", code("div()"), ",", code("p()"), "etc ) can now accept an arbitrary number of", code("DomContent"), "as arguments, eliminating the need for", code("with()"), "in most cases."),
|
||||||
join("Added a shorthand-attribute overloads to all TagCreator methods:", br(), code("div(attrs(\"#id.class\")"), "becomes", code("<div id=\"id\" class=\"class\"></div>")),
|
join("Added a shorthand-attribute overloads to all TagCreator methods:", br(), code("div(attrs(\"#id.class\")"), "becomes", code("<div id=\"id\" class=\"class\"></div>")),
|
||||||
@@ -96,7 +134,9 @@ public class NewsView {
|
|||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 0.99 released! (Apr 2017)", "0.99",
|
"j2html 0.99 released! (Apr 2017)",
|
||||||
|
"0.99",
|
||||||
|
false,
|
||||||
join("Added generic", code("iff()"), "/", code("iffElse()"), "methods for performing if's in method calls."),
|
join("Added generic", code("iff()"), "/", code("iffElse()"), "methods for performing if's in method calls."),
|
||||||
join("Added", code("withClasses()"), "to add multiple classes to element. Works well with", code("iff()"), "."),
|
join("Added", code("withClasses()"), "to add multiple classes to element. Works well with", code("iff()"), "."),
|
||||||
join("HTML-escaping is now a lot faster (and a lot faster than StringUtils)"),
|
join("HTML-escaping is now a lot faster (and a lot faster than StringUtils)"),
|
||||||
@@ -104,7 +144,9 @@ public class NewsView {
|
|||||||
),
|
),
|
||||||
|
|
||||||
newsPost(
|
newsPost(
|
||||||
"j2html 0.88 released! (Jan 2017)", "0.88",
|
"j2html 0.88 released! (Jan 2017)",
|
||||||
|
"0.88",
|
||||||
|
false,
|
||||||
text("Closure and StringUtils dependencies removed in favor of custom implementations. Most users seem interested in a very lightweight library."),
|
text("Closure and StringUtils dependencies removed in favor of custom implementations. Most users seem interested in a very lightweight library."),
|
||||||
code("unsafeHtml()"), text(" is now "), code("rawHtml()"),
|
code("unsafeHtml()"), text(" is now "), code("rawHtml()"),
|
||||||
text("Added "), code(".equals()"), text(" to Tag-class. Two Tags are equal if they render the same HTML")
|
text("Added "), code(".equals()"), text(" to Tag-class. Two Tags are equal if they render the same HTML")
|
||||||
|
|||||||
@@ -2,8 +2,12 @@ TagCreator.class // Static utility class for creating all tags
|
|||||||
import static j2html.TagCreator.*; // Use static star import
|
import static j2html.TagCreator.*; // Use static star import
|
||||||
|
|
||||||
|
|
||||||
Config.class // Static config class which holds all configuration
|
Config.class // Holds all configuration. Offers global configuration or customizable instances
|
||||||
Config.closeEmptyTags = true // all options are public and static, assign using '=' operator
|
Config.closeEmptyTags = true // Global options are public, static and mutable.
|
||||||
|
Config.global() // Copy all static Config fields into an instance. Instances are immutable
|
||||||
|
Config.defaults() // A Config with defaults that are independent of global options
|
||||||
|
Config.global().withEmptyTagsClosed(true) // A Config that is different from the global options
|
||||||
|
Config.defaults().withEmptyTagsClosed(true) // A Config that is different from the default options
|
||||||
|
|
||||||
|
|
||||||
TagCreator.join() // Method for joining small snippets, like:
|
TagCreator.join() // Method for joining small snippets, like:
|
||||||
@@ -21,3 +25,14 @@ div().withClasses("menu-element", iffElse(isActive, "active", "not-active"))
|
|||||||
Tag.class // Is extended by ContainerTag (ex <div></div> and EmptyTag (ex <br>)
|
Tag.class // Is extended by ContainerTag (ex <div></div> and EmptyTag (ex <br>)
|
||||||
Tag.attr(String attribute, Object value) // Set an attribute on the tag
|
Tag.attr(String attribute, Object value) // Set an attribute on the tag
|
||||||
Tag.withXyz(String value) // Calls attr with predefined attribute (ex .withId, .withClass, etc.)
|
Tag.withXyz(String value) // Calls attr with predefined attribute (ex .withId, .withClass, etc.)
|
||||||
|
Tag.render(HtmlBuilder builder) // Render HTML using the given builder.
|
||||||
|
Tag.render() // Shortcut for rendering flat HTML into a string using global Config.
|
||||||
|
ContainerTag.renderFormatted() // Shortcut for rendering indented HTML into a string using global Config.
|
||||||
|
|
||||||
|
HtmlBuilder.class // Interface for composing HTML. Implemented by FlatHtml and IndentedHtml
|
||||||
|
FlatHtml.into(Appendable) // Render into a stream, file, etc. without indentation or line breaks
|
||||||
|
FlatHtml.into(Appendable appendable, Config config) // Customize rendering of flat html
|
||||||
|
IndentedHtml.into(Appendable) // Render human-readable HTML into an stream, file, etc.
|
||||||
|
IndentedHtml.into(Appendable appendable, Config config) // Customize rendering of intended html
|
||||||
|
ul(li("one"), li("two")).render(IndentedHtml.inMemory()).toString() // Similar to renderFormatted()
|
||||||
|
ul(li("one"), li("two")).render(IndentedHtml.into(filewriter)) // Write HTML into a file
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.j2html</groupId>
|
<groupId>com.j2html</groupId>
|
||||||
<artifactId>j2html</artifactId>
|
<artifactId>j2html</artifactId>
|
||||||
<version>1.4.0</version>
|
<version>1.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
Reference in New Issue
Block a user