111 Commits

Author SHA1 Message Date
David
d559f05903 [maven-release-plugin] prepare release j2html-1.0.0-RC 2017-05-03 19:57:31 +02:00
David
97a8f34572 Make filereader java6 compatible, because why not 2017-05-02 22:39:59 +02:00
David
6305e364ca Experimental Java6/Java7 support 2017-05-02 03:12:17 +02:00
David
28ba518b12 Fix name collision + minor cleanup 2017-05-01 19:10:42 +02:00
David
5f04cde97c Merge pull request #56 from tipsy/id-class-shorthand
Add shorthand notation for id/class
2017-05-01 18:59:11 +02:00
David
b00ba50133 Add attrs method to tagcreator 2017-05-01 18:51:04 +02:00
David
e09918da12 Add missing test-case to attr.shortform 2017-05-01 18:06:10 +02:00
David
55b74e81aa Improve generics in Attr.addTo 2017-05-01 16:54:05 +02:00
David
75deeff13d Remove unwanted import 2017-05-01 16:29:22 +02:00
David
3aa05aa540 Merge branch 'master' into id-class-shorthand 2017-05-01 16:15:01 +02:00
David
fb24d1eabf Merge pull request #55 from chmuche/empty-attribute
Empty attribute
2017-05-01 15:50:07 +02:00
David
458f3baf98 Merge pull request #54 from chmuche/gradle-dependency
Add Gradle dependency in README.md
2017-05-01 15:48:25 +02:00
David
a661f37575 Add document() method that renders a html() child 2017-05-01 15:45:02 +02:00
David
26796cd30d Add shorthand notation for id/class 2017-05-01 15:22:48 +02:00
chmuche
75dc60c415 Add Test 2017-05-01 15:19:27 +02:00
chmuche
99b98f9b09 Create a method attr without value to create empty attribute inside the tag 2017-05-01 15:12:41 +02:00
chmuche
8d4756bab0 Add Gradle dependency in README.md 2017-05-01 15:07:50 +02:00
David
2c1f337348 Update README.md 2017-04-30 20:37:27 +02:00
David
d437e1affd Add a domcontentjoiner 2017-04-29 16:44:48 +02:00
David
4fdcc3c213 Remove need for with() 2017-04-29 12:15:51 +02:00
David
ba3261b210 Update README.md 2017-04-25 23:34:26 +02:00
David
ee0100d1a7 Set snapshot to 1.0.0 2017-04-20 23:17:07 +02:00
David
9ec3088d82 [maven-release-plugin] prepare for next development iteration 2017-04-20 23:13:36 +02:00
David
8052cdaff1 [maven-release-plugin] prepare release j2html-0.99 2017-04-20 23:13:16 +02:00
David
34b2410830 Add withClasses(String... classes) method 2017-04-20 23:08:12 +02:00
David
75d361fa20 Merge pull request #51 from tipsy/iff-else
Add generic iff-method to use in method calls
2017-04-20 21:34:07 +02:00
David
3e91da0640 Add generic iff-method to use in method calls 2017-04-17 16:20:12 +02:00
David
d1613b0570 Change Error to RuntimeException 2017-04-17 15:35:06 +02:00
David
a841271ba4 Merge pull request #50 from tipsy/inline-static-fix
Fix #14 (Unable to read files from directories other that /src/main/r…
2017-04-16 10:37:09 +02:00
David
9272438940 Simplify resource handling and throw exception 2017-04-13 21:21:01 +02:00
David
3d43eb159f Fix #14 (Unable to read files from directories other that /src/main/resources) 2017-04-13 01:25:16 +02:00
David
30bfe4ea7f Small formatting fix 2017-04-12 19:40:26 +02:00
David
7409772c20 Update README.md 2017-04-12 19:30:26 +02:00
David
29e16df057 Improve escaper performance 2017-03-28 22:23:33 +02:00
David
6903bcbe4d Update README.md 2017-01-30 00:28:58 +01:00
David
56b830782f [maven-release-plugin] prepare for next development iteration 2017-01-29 21:32:54 +01:00
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
tipsy
66b298efe4 [maven-release-plugin] prepare release j2html-0.7 2015-10-24 14:36:53 +02:00
tipsy
ed44fc79e0 Revert "Prepare for .7 release"
This reverts commit c926322fb6.
2015-10-24 13:40:12 +02:00
tipsy
c926322fb6 Prepare for .7 release 2015-10-24 13:35:05 +02:00
tipsy
d52f86dd39 Add uneeded test 2015-10-24 13:21:41 +02:00
tipsy
5692033f90 Rename inline-file-method names 2015-10-22 16:05:30 +02:00
tipsy
8667fd31d7 Methods for escaped and unescaped file as string 2015-10-22 01:39:31 +02:00
tipsy
9ef6d645d8 Add method for reading any file 2015-10-21 23:10:12 +02:00
David
4a2f502e5d Update README.md 2015-10-21 20:55:02 +02:00
tipsy
f54f0a53e4 Log using logger instead of sout 2015-10-21 19:56:28 +02:00
tipsy
04439d79de Use enum in ISR class 2015-10-21 17:41:53 +02:00
tipsy
f2d6621570 Tiny refactor 2015-10-21 09:15:10 +02:00
tipsy
4f05b26dc1 Stop using properties in POM 2015-10-20 23:47:37 +02:00
tipsy
c2691df9c5 EOF newlines 2015-10-20 23:18:45 +02:00
tipsy
91b12a6da0 Move package 2015-10-20 21:10:52 +02:00
tipsy
ccd76527bc Add filereader for inline static files 2015-10-20 19:40:54 +02:00
tipsy
ef43af72a3 Java 7 support, cleanup 2015-10-19 20:22:58 +02:00
tipsy
5ad63ad1d6 Use apache commons lang for escaping 2015-10-19 20:22:57 +02:00
tipsy
e92b7ce527 Change to non-deprecated assert 2015-10-19 20:22:57 +02:00
David
7bbb3a34da Update LICENSE
Woops x)
2015-10-05 20:19:18 +02:00
David
7e3e827af5 Update README.md 2015-05-28 20:08:56 +02:00
tipsy
0f5639660d use american english spelling of license 2015-05-27 20:09:21 +02:00
David
aa64aca294 Create LICENCE 2015-05-27 20:04:35 +02:00
tipsy
6f11845140 [maven-release-plugin] prepare for next development iteration 2015-05-26 19:38:01 +02:00
39 changed files with 3405 additions and 876 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

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2015 David Åse
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,4 +1,45 @@
![](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.
This project was inspired by [Gagawa](https://code.google.com/p/gagawa/)
The project webpage is [j2html.com](http://j2html.com).
## Getting started
### Add the maven dependency
```xml
<dependency>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>0.99</version>
</dependency>
```
### OR the gradle dependency
```
compile 'com.j2html:j2html:0.99'
```
### Import TagCreator and start building HTML
```java
import static j2html.TagCreator.*;
public class Main {
public static void main(String[] args) {
body().with(
h1("Heading!").withClass("example"),
img().withSrc("img/hello.png")
).render();
}
}
```
The above Java will result in the following HTML:
```html
<body>
<h1 class="example">Heading!</h1>
<img src="img/hello.png">
</body>
```
Find more examples at http://j2html.com/examples.html

47
pom.xml
View File

@@ -10,7 +10,7 @@
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>0.5.0</version>
<version>1.0.0-RC</version>
<name>j2html</name>
<description>Java to HTML builder with a fluent API</description>
@@ -39,16 +39,24 @@
<url>https://github.com/tipsy/j2html/issues</url>
</issueManagement>
<properties>
<jdk.version>1.8</jdk.version>
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -56,13 +64,29 @@
<build>
<plugins>
<plugin>
<groupId>net.orfjackal.retrolambda</groupId>
<artifactId>retrolambda-maven-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<goals>
<goal>process-main</goal>
<goal>process-test</goal>
</goals>
</execution>
</executions>
<configuration>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<source>1.8</source>
<target>1.8</target>
<optimize>true</optimize>
</configuration>
</plugin>
@@ -79,7 +103,7 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[${jdk.version},)</version>
<version>[1.8,)</version>
</requireJavaVersion>
</rules>
</configuration>
@@ -94,7 +118,6 @@
</configuration>
</plugin>
</plugins>
</build>
<profiles>
@@ -127,4 +150,4 @@
</profile>
</profiles>
</project>
</project>

View File

@@ -1,170 +1,842 @@
package j2html;
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.attributes.Attr;
import j2html.tags.ContainerTag;
import j2html.tags.DomContent;
import j2html.tags.DomContentJoiner;
import j2html.tags.EmptyTag;
import j2html.tags.InlineStaticResource;
import j2html.tags.Text;
import j2html.tags.UnescapedText;
public class TagCreator {
private TagCreator() {}
public static ContainerTag tag(String tagName) { return new ContainerTag(tagName); }
public static EmptyTag emptyTag(String tagName) { return new EmptyTag(tagName); }
/**
* Generic if-expression to do if'ing inside method calls
*
* @param <T> The derived generic parameter type
* @param condition the condition to if-on
* @param ifValue the value to return if condition is true
* @return value if condition is true, null otherwise
*/
public static <T> T iff(boolean condition, T ifValue) {
return condition ? ifValue : null;
}
public static Text text(String text) { return new Text(text); }
public static UnescapedText unsafeHtml(String html) { return new UnescapedText(html); }
/**
* Like {@link j2html.TagCreator#iff}, but returns else-value instead of null
*/
public static <T> T iffElse(boolean condition, T ifValue, T elseValue) {
return condition ? ifValue : elseValue;
}
//EmptyTags
public static EmptyTag area() { return new EmptyTag("area"); }
public static EmptyTag base() { return new EmptyTag("base"); }
public static EmptyTag br() { return new EmptyTag("br"); }
public static EmptyTag col() { return new EmptyTag("col"); }
public static EmptyTag document() { return new EmptyTag("!DOCTYPE html"); }
public static EmptyTag embed() { return new EmptyTag("embed"); }
public static EmptyTag hr() { return new EmptyTag("hr"); }
public static EmptyTag img() { return new EmptyTag("img"); }
public static EmptyTag input() { return new EmptyTag("input"); }
public static EmptyTag keygen() { return new EmptyTag("keygen"); }
public static EmptyTag link() { return new EmptyTag("link"); }
public static EmptyTag meta() { return new EmptyTag("meta"); }
public static EmptyTag param() { return new EmptyTag("param"); }
public static EmptyTag source() { return new EmptyTag("source"); }
public static EmptyTag track() { return new EmptyTag("track"); }
public static EmptyTag wbr() { return new EmptyTag("wbr"); }
/**
* Returns a Attr.ShortForm object with either id, classes or both,
* obtained from parsing the input string using css selector syntax
*
* @param attrs the string with shortform attributes, only id and class is supported
* @return a Attr.ShortForm object
*/
public static Attr.ShortForm attrs(String attrs) {
return Attr.shortFormFromAttrsString(attrs);
}
//ContainerTags
public static ContainerTag a() { return new ContainerTag("a"); }
public static ContainerTag a(String text) { return new ContainerTag("a").withText(text); }
public static ContainerTag abbr() { return new ContainerTag("abbr"); }
public static ContainerTag address() { return new ContainerTag("address"); }
public static ContainerTag article() { return new ContainerTag("article"); }
public static ContainerTag aside() { return new ContainerTag("aside"); }
public static ContainerTag audio() { return new ContainerTag("audio"); }
public static ContainerTag b() { return new ContainerTag("b"); }
public static ContainerTag b(String text) { return new ContainerTag("b").withText(text); }
public static ContainerTag bdi() { return new ContainerTag("bdi"); }
public static ContainerTag bdi(String text) { return new ContainerTag("bdi").withText(text); }
public static ContainerTag bdo() { return new ContainerTag("bdo"); }
public static ContainerTag bdo(String text) { return new ContainerTag("bdo").withText(text); }
public static ContainerTag blockquote() { return new ContainerTag("blockquote"); }
public static ContainerTag blockquote(String text) { return new ContainerTag("blockquote").withText(text); }
public static ContainerTag body() { return new ContainerTag("body"); }
public static ContainerTag button() { return new ContainerTag("button"); }
public static ContainerTag button(String text) { return new ContainerTag("button").withText(text); }
public static ContainerTag canvas() { return new ContainerTag("canvas"); }
public static ContainerTag caption() { return new ContainerTag("caption"); }
public static ContainerTag caption(String text) { return new ContainerTag("caption").withText(text); }
public static ContainerTag cite() { return new ContainerTag("cite"); }
public static ContainerTag cite(String text) { return new ContainerTag("cite").withText(text); }
public static ContainerTag code() { return new ContainerTag("code"); }
public static ContainerTag colgroup() { return new ContainerTag("colgroup"); }
public static ContainerTag datalist() { return new ContainerTag("datalist"); }
public static ContainerTag dd() { return new ContainerTag("dd"); }
public static ContainerTag dd(String text) { return new ContainerTag("dd").withText(text); }
public static ContainerTag del() { return new ContainerTag("del"); }
public static ContainerTag del(String text) { return new ContainerTag("del").withText(text); }
public static ContainerTag details() { return new ContainerTag("details"); }
public static ContainerTag dfn() { return new ContainerTag("dfn"); }
public static ContainerTag dfn(String text) { return new ContainerTag("dfn").withText(text); }
public static ContainerTag dialog() { return new ContainerTag("dialog"); }
public static ContainerTag dialog(String text) { return new ContainerTag("dialog").withText(text); }
public static ContainerTag div() { return new ContainerTag("div"); }
public static ContainerTag dl() { return new ContainerTag("dl"); }
public static ContainerTag dt() { return new ContainerTag("dt"); }
public static ContainerTag dt(String text) { return new ContainerTag("dt").withText(text); }
public static ContainerTag em() { return new ContainerTag("em"); }
public static ContainerTag em(String text) { return new ContainerTag("em").withText(text); }
public static ContainerTag fieldset() { return new ContainerTag("fieldset"); }
public static ContainerTag figcaption() { return new ContainerTag("figcaption"); }
public static ContainerTag figcaption(String text) { return new ContainerTag("figcaption").withText(text); }
public static ContainerTag figure() { return new ContainerTag("figure"); }
public static ContainerTag footer() { return new ContainerTag("footer"); }
public static ContainerTag form() { return new ContainerTag("form"); }
public static ContainerTag h1() { return new ContainerTag("h1"); }
public static ContainerTag h1(String text) { return new ContainerTag("h1").withText(text); }
public static ContainerTag h2() { return new ContainerTag("h2"); }
public static ContainerTag h2(String text) { return new ContainerTag("h2").withText(text); }
public static ContainerTag h3() { return new ContainerTag("h3"); }
public static ContainerTag h3(String text) { return new ContainerTag("h3").withText(text); }
public static ContainerTag h4() { return new ContainerTag("h4"); }
public static ContainerTag h4(String text) { return new ContainerTag("h4").withText(text); }
public static ContainerTag h5() { return new ContainerTag("h5"); }
public static ContainerTag h5(String text) { return new ContainerTag("h5").withText(text); }
public static ContainerTag h6() { return new ContainerTag("h6"); }
public static ContainerTag h6(String text) { return new ContainerTag("h6").withText(text); }
public static ContainerTag head() { return new ContainerTag("head"); }
public static ContainerTag header() { return new ContainerTag("header"); }
public static ContainerTag html() { return new ContainerTag("html"); }
public static ContainerTag i() { return new ContainerTag("i"); }
public static ContainerTag i(String text) { return new ContainerTag("i").withText(text); }
public static ContainerTag iframe() { return new ContainerTag("iframe"); }
public static ContainerTag ins() { return new ContainerTag("ins"); }
public static ContainerTag ins(String text) { return new ContainerTag("ins").withText(text); }
public static ContainerTag kbd() { return new ContainerTag("kbd"); }
public static ContainerTag label() { return new ContainerTag("label"); }
public static ContainerTag label(String text) { return new ContainerTag("label").withText(text); }
public static ContainerTag legend() { return new ContainerTag("legend"); }
public static ContainerTag legend(String text) { return new ContainerTag("legend").withText(text); }
public static ContainerTag li() { return new ContainerTag("li"); }
public static ContainerTag li(String text) { return new ContainerTag("li").withText(text); }
public static ContainerTag main() { return new ContainerTag("main"); }
public static ContainerTag map() { return new ContainerTag("map"); }
public static ContainerTag mark() { return new ContainerTag("mark"); }
public static ContainerTag menu() { return new ContainerTag("menu"); }
public static ContainerTag menuitem() { return new ContainerTag("menuitem"); }
public static ContainerTag meter() { return new ContainerTag("meter"); }
public static ContainerTag nav() { return new ContainerTag("nav"); }
public static ContainerTag noscript() { return new ContainerTag("noscript"); }
public static ContainerTag object() { return new ContainerTag("object"); }
public static ContainerTag ol() { return new ContainerTag("ol"); }
public static ContainerTag optgroup() { return new ContainerTag("optgroup"); }
public static ContainerTag option() { return new ContainerTag("option"); }
public static ContainerTag option(String text) { return new ContainerTag("option").withText(text); }
public static ContainerTag output() { return new ContainerTag("output"); }
public static ContainerTag p() { return new ContainerTag("p"); }
public static ContainerTag p(String text) { return new ContainerTag("p").withText(text); }
public static ContainerTag pre() { return new ContainerTag("pre"); }
public static ContainerTag progress() { return new ContainerTag("progress"); }
public static ContainerTag q() { return new ContainerTag("q"); }
public static ContainerTag q(String text) { return new ContainerTag("q").withText(text); }
public static ContainerTag rp() { return new ContainerTag("rp"); }
public static ContainerTag rt() { return new ContainerTag("rt"); }
public static ContainerTag ruby() { return new ContainerTag("ruby"); }
public static ContainerTag s() { return new ContainerTag("s"); }
public static ContainerTag s(String text) { return new ContainerTag("s").withText(text); }
public static ContainerTag samp() { return new ContainerTag("samp"); }
public static ContainerTag script() { return new ContainerTag("script"); }
public static ContainerTag section() { return new ContainerTag("section"); }
public static ContainerTag select() { return new ContainerTag("select"); }
public static ContainerTag small() { return new ContainerTag("small"); }
public static ContainerTag small(String text) { return new ContainerTag("small").withText(text); }
public static ContainerTag span() { return new ContainerTag("span"); }
public static ContainerTag span(String text) { return new ContainerTag("span").withText(text); }
public static ContainerTag strong() { return new ContainerTag("strong"); }
public static ContainerTag strong(String text) { return new ContainerTag("strong").withText(text); }
public static ContainerTag style() { return new ContainerTag("style"); }
public static ContainerTag sub() { return new ContainerTag("sub"); }
public static ContainerTag sub(String text) { return new ContainerTag("sub").withText(text); }
public static ContainerTag summary() { return new ContainerTag("summary"); }
public static ContainerTag summary(String text) { return new ContainerTag("summary").withText(text); }
public static ContainerTag sup() { return new ContainerTag("sup"); }
public static ContainerTag sup(String text) { return new ContainerTag("sup").withText(text); }
public static ContainerTag table() { return new ContainerTag("table"); }
public static ContainerTag tbody() { return new ContainerTag("tbody"); }
public static ContainerTag td() { return new ContainerTag("td"); }
public static ContainerTag td(String text) { return new ContainerTag("td").withText(text); }
public static ContainerTag textarea() { return new ContainerTag("textarea"); }
public static ContainerTag tfoot() { return new ContainerTag("tfoot"); }
public static ContainerTag th() { return new ContainerTag("th"); }
public static ContainerTag th(String text) { return new ContainerTag("th").withText(text); }
public static ContainerTag thead() { return new ContainerTag("thead"); }
public static ContainerTag time() { return new ContainerTag("time"); }
public static ContainerTag title() { return new ContainerTag("title"); }
public static ContainerTag title(String text) { return new ContainerTag("title").withText(text); }
public static ContainerTag tr() { return new ContainerTag("tr"); }
public static ContainerTag u() { return new ContainerTag("u"); }
public static ContainerTag u(String text) { return new ContainerTag("u").withText(text); }
public static ContainerTag ul() { return new ContainerTag("ul"); }
public static ContainerTag var() { return new ContainerTag("var"); }
public static ContainerTag video() { return new ContainerTag("video"); }
/**
* Returns the HTML created by concatenating the input elements,
* separated by space, in encounter order.
* Also removes spaces before periods and commas.
*
* @param stringOrDomObjects the elements to join
* @return joined elements as HTML
*/
public static UnescapedText join(Object... stringOrDomObjects) {
return DomContentJoiner.join(" ", true, stringOrDomObjects);
}
/**
* 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);
}
/**
* Return a complete html document string
*
* @param htmlTag the html content of a website
* @return document declaration and rendered html content
*/
public static String document(ContainerTag htmlTag) {
if (htmlTag.getTagName().equals("html")) {
return new EmptyTag("!DOCTYPE html").render() + htmlTag.render();
}
throw new IllegalArgumentException("Only HTML-tag can follow document declaration");
}
//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 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); }
public static EmptyTag document() { return new EmptyTag("!DOCTYPE html"); }
// EmptyTags, generated in class j2html.tags.TagCreatorCodeGenerator
public static EmptyTag area() { return new EmptyTag("area"); }
public static EmptyTag area(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("area"), shortAttr); }
public static EmptyTag base() { return new EmptyTag("base"); }
public static EmptyTag base(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("base"), shortAttr); }
public static EmptyTag br() { return new EmptyTag("br"); }
public static EmptyTag br(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("br"), shortAttr); }
public static EmptyTag col() { return new EmptyTag("col"); }
public static EmptyTag col(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("col"), shortAttr); }
public static EmptyTag embed() { return new EmptyTag("embed"); }
public static EmptyTag embed(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("embed"), shortAttr); }
public static EmptyTag hr() { return new EmptyTag("hr"); }
public static EmptyTag hr(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("hr"), shortAttr); }
public static EmptyTag img() { return new EmptyTag("img"); }
public static EmptyTag img(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("img"), shortAttr); }
public static EmptyTag input() { return new EmptyTag("input"); }
public static EmptyTag input(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("input"), shortAttr); }
public static EmptyTag keygen() { return new EmptyTag("keygen"); }
public static EmptyTag keygen(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("keygen"), shortAttr); }
public static EmptyTag link() { return new EmptyTag("link"); }
public static EmptyTag link(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("link"), shortAttr); }
public static EmptyTag meta() { return new EmptyTag("meta"); }
public static EmptyTag meta(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("meta"), shortAttr); }
public static EmptyTag param() { return new EmptyTag("param"); }
public static EmptyTag param(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("param"), shortAttr); }
public static EmptyTag source() { return new EmptyTag("source"); }
public static EmptyTag source(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("source"), shortAttr); }
public static EmptyTag track() { return new EmptyTag("track"); }
public static EmptyTag track(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("track"), shortAttr); }
public static EmptyTag wbr() { return new EmptyTag("wbr"); }
public static EmptyTag wbr(Attr.ShortForm shortAttr) { return Attr.addTo(new EmptyTag("wbr"), shortAttr); }
// ContainerTags, generated in class j2html.tags.TagCreatorCodeGenerator
public static ContainerTag a() { return new ContainerTag("a"); }
public static ContainerTag a(String text) { return new ContainerTag("a").withText(text); }
public static ContainerTag a(DomContent... dc) { return new ContainerTag("a").with(dc); }
public static ContainerTag a(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("a"), shortAttr); }
public static ContainerTag a(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("a").withText(text), shortAttr); }
public static ContainerTag a(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("a").with(dc), shortAttr); }
public static ContainerTag abbr() { return new ContainerTag("abbr"); }
public static ContainerTag abbr(String text) { return new ContainerTag("abbr").withText(text); }
public static ContainerTag abbr(DomContent... dc) { return new ContainerTag("abbr").with(dc); }
public static ContainerTag abbr(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("abbr"), shortAttr); }
public static ContainerTag abbr(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("abbr").withText(text), shortAttr); }
public static ContainerTag abbr(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("abbr").with(dc), shortAttr); }
public static ContainerTag address() { return new ContainerTag("address"); }
public static ContainerTag address(String text) { return new ContainerTag("address").withText(text); }
public static ContainerTag address(DomContent... dc) { return new ContainerTag("address").with(dc); }
public static ContainerTag address(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("address"), shortAttr); }
public static ContainerTag address(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("address").withText(text), shortAttr); }
public static ContainerTag address(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("address").with(dc), shortAttr); }
public static ContainerTag article() { return new ContainerTag("article"); }
public static ContainerTag article(String text) { return new ContainerTag("article").withText(text); }
public static ContainerTag article(DomContent... dc) { return new ContainerTag("article").with(dc); }
public static ContainerTag article(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("article"), shortAttr); }
public static ContainerTag article(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("article").withText(text), shortAttr); }
public static ContainerTag article(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("article").with(dc), shortAttr); }
public static ContainerTag aside() { return new ContainerTag("aside"); }
public static ContainerTag aside(String text) { return new ContainerTag("aside").withText(text); }
public static ContainerTag aside(DomContent... dc) { return new ContainerTag("aside").with(dc); }
public static ContainerTag aside(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("aside"), shortAttr); }
public static ContainerTag aside(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("aside").withText(text), shortAttr); }
public static ContainerTag aside(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("aside").with(dc), shortAttr); }
public static ContainerTag audio() { return new ContainerTag("audio"); }
public static ContainerTag audio(String text) { return new ContainerTag("audio").withText(text); }
public static ContainerTag audio(DomContent... dc) { return new ContainerTag("audio").with(dc); }
public static ContainerTag audio(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("audio"), shortAttr); }
public static ContainerTag audio(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("audio").withText(text), shortAttr); }
public static ContainerTag audio(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("audio").with(dc), shortAttr); }
public static ContainerTag b() { return new ContainerTag("b"); }
public static ContainerTag b(String text) { return new ContainerTag("b").withText(text); }
public static ContainerTag b(DomContent... dc) { return new ContainerTag("b").with(dc); }
public static ContainerTag b(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("b"), shortAttr); }
public static ContainerTag b(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("b").withText(text), shortAttr); }
public static ContainerTag b(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("b").with(dc), shortAttr); }
public static ContainerTag bdi() { return new ContainerTag("bdi"); }
public static ContainerTag bdi(String text) { return new ContainerTag("bdi").withText(text); }
public static ContainerTag bdi(DomContent... dc) { return new ContainerTag("bdi").with(dc); }
public static ContainerTag bdi(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("bdi"), shortAttr); }
public static ContainerTag bdi(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("bdi").withText(text), shortAttr); }
public static ContainerTag bdi(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("bdi").with(dc), shortAttr); }
public static ContainerTag bdo() { return new ContainerTag("bdo"); }
public static ContainerTag bdo(String text) { return new ContainerTag("bdo").withText(text); }
public static ContainerTag bdo(DomContent... dc) { return new ContainerTag("bdo").with(dc); }
public static ContainerTag bdo(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("bdo"), shortAttr); }
public static ContainerTag bdo(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("bdo").withText(text), shortAttr); }
public static ContainerTag bdo(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("bdo").with(dc), shortAttr); }
public static ContainerTag blockquote() { return new ContainerTag("blockquote"); }
public static ContainerTag blockquote(String text) { return new ContainerTag("blockquote").withText(text); }
public static ContainerTag blockquote(DomContent... dc) { return new ContainerTag("blockquote").with(dc); }
public static ContainerTag blockquote(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("blockquote"), shortAttr); }
public static ContainerTag blockquote(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("blockquote").withText(text), shortAttr); }
public static ContainerTag blockquote(Attr.ShortForm shortAttr, DomContent... dc){ return Attr.addTo(new ContainerTag("blockquote").with(dc), shortAttr); }
public static ContainerTag body() { return new ContainerTag("body"); }
public static ContainerTag body(String text) { return new ContainerTag("body").withText(text); }
public static ContainerTag body(DomContent... dc) { return new ContainerTag("body").with(dc); }
public static ContainerTag body(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("body"), shortAttr); }
public static ContainerTag body(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("body").withText(text), shortAttr); }
public static ContainerTag body(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("body").with(dc), shortAttr); }
public static ContainerTag button() { return new ContainerTag("button"); }
public static ContainerTag button(String text) { return new ContainerTag("button").withText(text); }
public static ContainerTag button(DomContent... dc) { return new ContainerTag("button").with(dc); }
public static ContainerTag button(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("button"), shortAttr); }
public static ContainerTag button(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("button").withText(text), shortAttr); }
public static ContainerTag button(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("button").with(dc), shortAttr); }
public static ContainerTag canvas() { return new ContainerTag("canvas"); }
public static ContainerTag canvas(String text) { return new ContainerTag("canvas").withText(text); }
public static ContainerTag canvas(DomContent... dc) { return new ContainerTag("canvas").with(dc); }
public static ContainerTag canvas(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("canvas"), shortAttr); }
public static ContainerTag canvas(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("canvas").withText(text), shortAttr); }
public static ContainerTag canvas(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("canvas").with(dc), shortAttr); }
public static ContainerTag caption() { return new ContainerTag("caption"); }
public static ContainerTag caption(String text) { return new ContainerTag("caption").withText(text); }
public static ContainerTag caption(DomContent... dc) { return new ContainerTag("caption").with(dc); }
public static ContainerTag caption(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("caption"), shortAttr); }
public static ContainerTag caption(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("caption").withText(text), shortAttr); }
public static ContainerTag caption(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("caption").with(dc), shortAttr); }
public static ContainerTag cite() { return new ContainerTag("cite"); }
public static ContainerTag cite(String text) { return new ContainerTag("cite").withText(text); }
public static ContainerTag cite(DomContent... dc) { return new ContainerTag("cite").with(dc); }
public static ContainerTag cite(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("cite"), shortAttr); }
public static ContainerTag cite(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("cite").withText(text), shortAttr); }
public static ContainerTag cite(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("cite").with(dc), shortAttr); }
public static ContainerTag code() { return new ContainerTag("code"); }
public static ContainerTag code(String text) { return new ContainerTag("code").withText(text); }
public static ContainerTag code(DomContent... dc) { return new ContainerTag("code").with(dc); }
public static ContainerTag code(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("code"), shortAttr); }
public static ContainerTag code(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("code").withText(text), shortAttr); }
public static ContainerTag code(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("code").with(dc), shortAttr); }
public static ContainerTag colgroup() { return new ContainerTag("colgroup"); }
public static ContainerTag colgroup(String text) { return new ContainerTag("colgroup").withText(text); }
public static ContainerTag colgroup(DomContent... dc) { return new ContainerTag("colgroup").with(dc); }
public static ContainerTag colgroup(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("colgroup"), shortAttr); }
public static ContainerTag colgroup(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("colgroup").withText(text), shortAttr); }
public static ContainerTag colgroup(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("colgroup").with(dc), shortAttr); }
public static ContainerTag datalist() { return new ContainerTag("datalist"); }
public static ContainerTag datalist(String text) { return new ContainerTag("datalist").withText(text); }
public static ContainerTag datalist(DomContent... dc) { return new ContainerTag("datalist").with(dc); }
public static ContainerTag datalist(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("datalist"), shortAttr); }
public static ContainerTag datalist(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("datalist").withText(text), shortAttr); }
public static ContainerTag datalist(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("datalist").with(dc), shortAttr); }
public static ContainerTag dd() { return new ContainerTag("dd"); }
public static ContainerTag dd(String text) { return new ContainerTag("dd").withText(text); }
public static ContainerTag dd(DomContent... dc) { return new ContainerTag("dd").with(dc); }
public static ContainerTag dd(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("dd"), shortAttr); }
public static ContainerTag dd(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("dd").withText(text), shortAttr); }
public static ContainerTag dd(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("dd").with(dc), shortAttr); }
public static ContainerTag del() { return new ContainerTag("del"); }
public static ContainerTag del(String text) { return new ContainerTag("del").withText(text); }
public static ContainerTag del(DomContent... dc) { return new ContainerTag("del").with(dc); }
public static ContainerTag del(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("del"), shortAttr); }
public static ContainerTag del(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("del").withText(text), shortAttr); }
public static ContainerTag del(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("del").with(dc), shortAttr); }
public static ContainerTag details() { return new ContainerTag("details"); }
public static ContainerTag details(String text) { return new ContainerTag("details").withText(text); }
public static ContainerTag details(DomContent... dc) { return new ContainerTag("details").with(dc); }
public static ContainerTag details(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("details"), shortAttr); }
public static ContainerTag details(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("details").withText(text), shortAttr); }
public static ContainerTag details(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("details").with(dc), shortAttr); }
public static ContainerTag dfn() { return new ContainerTag("dfn"); }
public static ContainerTag dfn(String text) { return new ContainerTag("dfn").withText(text); }
public static ContainerTag dfn(DomContent... dc) { return new ContainerTag("dfn").with(dc); }
public static ContainerTag dfn(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("dfn"), shortAttr); }
public static ContainerTag dfn(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("dfn").withText(text), shortAttr); }
public static ContainerTag dfn(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("dfn").with(dc), shortAttr); }
public static ContainerTag dialog() { return new ContainerTag("dialog"); }
public static ContainerTag dialog(String text) { return new ContainerTag("dialog").withText(text); }
public static ContainerTag dialog(DomContent... dc) { return new ContainerTag("dialog").with(dc); }
public static ContainerTag dialog(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("dialog"), shortAttr); }
public static ContainerTag dialog(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("dialog").withText(text), shortAttr); }
public static ContainerTag dialog(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("dialog").with(dc), shortAttr); }
public static ContainerTag div() { return new ContainerTag("div"); }
public static ContainerTag div(String text) { return new ContainerTag("div").withText(text); }
public static ContainerTag div(DomContent... dc) { return new ContainerTag("div").with(dc); }
public static ContainerTag div(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("div"), shortAttr); }
public static ContainerTag div(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("div").withText(text), shortAttr); }
public static ContainerTag div(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("div").with(dc), shortAttr); }
public static ContainerTag dl() { return new ContainerTag("dl"); }
public static ContainerTag dl(String text) { return new ContainerTag("dl").withText(text); }
public static ContainerTag dl(DomContent... dc) { return new ContainerTag("dl").with(dc); }
public static ContainerTag dl(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("dl"), shortAttr); }
public static ContainerTag dl(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("dl").withText(text), shortAttr); }
public static ContainerTag dl(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("dl").with(dc), shortAttr); }
public static ContainerTag dt() { return new ContainerTag("dt"); }
public static ContainerTag dt(String text) { return new ContainerTag("dt").withText(text); }
public static ContainerTag dt(DomContent... dc) { return new ContainerTag("dt").with(dc); }
public static ContainerTag dt(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("dt"), shortAttr); }
public static ContainerTag dt(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("dt").withText(text), shortAttr); }
public static ContainerTag dt(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("dt").with(dc), shortAttr); }
public static ContainerTag em() { return new ContainerTag("em"); }
public static ContainerTag em(String text) { return new ContainerTag("em").withText(text); }
public static ContainerTag em(DomContent... dc) { return new ContainerTag("em").with(dc); }
public static ContainerTag em(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("em"), shortAttr); }
public static ContainerTag em(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("em").withText(text), shortAttr); }
public static ContainerTag em(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("em").with(dc), shortAttr); }
public static ContainerTag fieldset() { return new ContainerTag("fieldset"); }
public static ContainerTag fieldset(String text) { return new ContainerTag("fieldset").withText(text); }
public static ContainerTag fieldset(DomContent... dc) { return new ContainerTag("fieldset").with(dc); }
public static ContainerTag fieldset(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("fieldset"), shortAttr); }
public static ContainerTag fieldset(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("fieldset").withText(text), shortAttr); }
public static ContainerTag fieldset(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("fieldset").with(dc), shortAttr); }
public static ContainerTag figcaption() { return new ContainerTag("figcaption"); }
public static ContainerTag figcaption(String text) { return new ContainerTag("figcaption").withText(text); }
public static ContainerTag figcaption(DomContent... dc) { return new ContainerTag("figcaption").with(dc); }
public static ContainerTag figcaption(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("figcaption"), shortAttr); }
public static ContainerTag figcaption(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("figcaption").withText(text), shortAttr); }
public static ContainerTag figcaption(Attr.ShortForm shortAttr, DomContent... dc){ return Attr.addTo(new ContainerTag("figcaption").with(dc), shortAttr); }
public static ContainerTag figure() { return new ContainerTag("figure"); }
public static ContainerTag figure(String text) { return new ContainerTag("figure").withText(text); }
public static ContainerTag figure(DomContent... dc) { return new ContainerTag("figure").with(dc); }
public static ContainerTag figure(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("figure"), shortAttr); }
public static ContainerTag figure(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("figure").withText(text), shortAttr); }
public static ContainerTag figure(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("figure").with(dc), shortAttr); }
public static ContainerTag footer() { return new ContainerTag("footer"); }
public static ContainerTag footer(String text) { return new ContainerTag("footer").withText(text); }
public static ContainerTag footer(DomContent... dc) { return new ContainerTag("footer").with(dc); }
public static ContainerTag footer(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("footer"), shortAttr); }
public static ContainerTag footer(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("footer").withText(text), shortAttr); }
public static ContainerTag footer(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("footer").with(dc), shortAttr); }
public static ContainerTag form() { return new ContainerTag("form"); }
public static ContainerTag form(String text) { return new ContainerTag("form").withText(text); }
public static ContainerTag form(DomContent... dc) { return new ContainerTag("form").with(dc); }
public static ContainerTag form(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("form"), shortAttr); }
public static ContainerTag form(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("form").withText(text), shortAttr); }
public static ContainerTag form(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("form").with(dc), shortAttr); }
public static ContainerTag h1() { return new ContainerTag("h1"); }
public static ContainerTag h1(String text) { return new ContainerTag("h1").withText(text); }
public static ContainerTag h1(DomContent... dc) { return new ContainerTag("h1").with(dc); }
public static ContainerTag h1(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("h1"), shortAttr); }
public static ContainerTag h1(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("h1").withText(text), shortAttr); }
public static ContainerTag h1(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("h1").with(dc), shortAttr); }
public static ContainerTag h2() { return new ContainerTag("h2"); }
public static ContainerTag h2(String text) { return new ContainerTag("h2").withText(text); }
public static ContainerTag h2(DomContent... dc) { return new ContainerTag("h2").with(dc); }
public static ContainerTag h2(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("h2"), shortAttr); }
public static ContainerTag h2(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("h2").withText(text), shortAttr); }
public static ContainerTag h2(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("h2").with(dc), shortAttr); }
public static ContainerTag h3() { return new ContainerTag("h3"); }
public static ContainerTag h3(String text) { return new ContainerTag("h3").withText(text); }
public static ContainerTag h3(DomContent... dc) { return new ContainerTag("h3").with(dc); }
public static ContainerTag h3(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("h3"), shortAttr); }
public static ContainerTag h3(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("h3").withText(text), shortAttr); }
public static ContainerTag h3(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("h3").with(dc), shortAttr); }
public static ContainerTag h4() { return new ContainerTag("h4"); }
public static ContainerTag h4(String text) { return new ContainerTag("h4").withText(text); }
public static ContainerTag h4(DomContent... dc) { return new ContainerTag("h4").with(dc); }
public static ContainerTag h4(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("h4"), shortAttr); }
public static ContainerTag h4(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("h4").withText(text), shortAttr); }
public static ContainerTag h4(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("h4").with(dc), shortAttr); }
public static ContainerTag h5() { return new ContainerTag("h5"); }
public static ContainerTag h5(String text) { return new ContainerTag("h5").withText(text); }
public static ContainerTag h5(DomContent... dc) { return new ContainerTag("h5").with(dc); }
public static ContainerTag h5(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("h5"), shortAttr); }
public static ContainerTag h5(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("h5").withText(text), shortAttr); }
public static ContainerTag h5(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("h5").with(dc), shortAttr); }
public static ContainerTag h6() { return new ContainerTag("h6"); }
public static ContainerTag h6(String text) { return new ContainerTag("h6").withText(text); }
public static ContainerTag h6(DomContent... dc) { return new ContainerTag("h6").with(dc); }
public static ContainerTag h6(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("h6"), shortAttr); }
public static ContainerTag h6(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("h6").withText(text), shortAttr); }
public static ContainerTag h6(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("h6").with(dc), shortAttr); }
public static ContainerTag head() { return new ContainerTag("head"); }
public static ContainerTag head(String text) { return new ContainerTag("head").withText(text); }
public static ContainerTag head(DomContent... dc) { return new ContainerTag("head").with(dc); }
public static ContainerTag head(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("head"), shortAttr); }
public static ContainerTag head(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("head").withText(text), shortAttr); }
public static ContainerTag head(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("head").with(dc), shortAttr); }
public static ContainerTag header() { return new ContainerTag("header"); }
public static ContainerTag header(String text) { return new ContainerTag("header").withText(text); }
public static ContainerTag header(DomContent... dc) { return new ContainerTag("header").with(dc); }
public static ContainerTag header(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("header"), shortAttr); }
public static ContainerTag header(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("header").withText(text), shortAttr); }
public static ContainerTag header(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("header").with(dc), shortAttr); }
public static ContainerTag html() { return new ContainerTag("html"); }
public static ContainerTag html(String text) { return new ContainerTag("html").withText(text); }
public static ContainerTag html(DomContent... dc) { return new ContainerTag("html").with(dc); }
public static ContainerTag html(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("html"), shortAttr); }
public static ContainerTag html(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("html").withText(text), shortAttr); }
public static ContainerTag html(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("html").with(dc), shortAttr); }
public static ContainerTag i() { return new ContainerTag("i"); }
public static ContainerTag i(String text) { return new ContainerTag("i").withText(text); }
public static ContainerTag i(DomContent... dc) { return new ContainerTag("i").with(dc); }
public static ContainerTag i(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("i"), shortAttr); }
public static ContainerTag i(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("i").withText(text), shortAttr); }
public static ContainerTag i(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("i").with(dc), shortAttr); }
public static ContainerTag iframe() { return new ContainerTag("iframe"); }
public static ContainerTag iframe(String text) { return new ContainerTag("iframe").withText(text); }
public static ContainerTag iframe(DomContent... dc) { return new ContainerTag("iframe").with(dc); }
public static ContainerTag iframe(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("iframe"), shortAttr); }
public static ContainerTag iframe(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("iframe").withText(text), shortAttr); }
public static ContainerTag iframe(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("iframe").with(dc), shortAttr); }
public static ContainerTag ins() { return new ContainerTag("ins"); }
public static ContainerTag ins(String text) { return new ContainerTag("ins").withText(text); }
public static ContainerTag ins(DomContent... dc) { return new ContainerTag("ins").with(dc); }
public static ContainerTag ins(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("ins"), shortAttr); }
public static ContainerTag ins(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("ins").withText(text), shortAttr); }
public static ContainerTag ins(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("ins").with(dc), shortAttr); }
public static ContainerTag kbd() { return new ContainerTag("kbd"); }
public static ContainerTag kbd(String text) { return new ContainerTag("kbd").withText(text); }
public static ContainerTag kbd(DomContent... dc) { return new ContainerTag("kbd").with(dc); }
public static ContainerTag kbd(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("kbd"), shortAttr); }
public static ContainerTag kbd(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("kbd").withText(text), shortAttr); }
public static ContainerTag kbd(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("kbd").with(dc), shortAttr); }
public static ContainerTag label() { return new ContainerTag("label"); }
public static ContainerTag label(String text) { return new ContainerTag("label").withText(text); }
public static ContainerTag label(DomContent... dc) { return new ContainerTag("label").with(dc); }
public static ContainerTag label(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("label"), shortAttr); }
public static ContainerTag label(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("label").withText(text), shortAttr); }
public static ContainerTag label(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("label").with(dc), shortAttr); }
public static ContainerTag legend() { return new ContainerTag("legend"); }
public static ContainerTag legend(String text) { return new ContainerTag("legend").withText(text); }
public static ContainerTag legend(DomContent... dc) { return new ContainerTag("legend").with(dc); }
public static ContainerTag legend(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("legend"), shortAttr); }
public static ContainerTag legend(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("legend").withText(text), shortAttr); }
public static ContainerTag legend(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("legend").with(dc), shortAttr); }
public static ContainerTag li() { return new ContainerTag("li"); }
public static ContainerTag li(String text) { return new ContainerTag("li").withText(text); }
public static ContainerTag li(DomContent... dc) { return new ContainerTag("li").with(dc); }
public static ContainerTag li(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("li"), shortAttr); }
public static ContainerTag li(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("li").withText(text), shortAttr); }
public static ContainerTag li(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("li").with(dc), shortAttr); }
public static ContainerTag main() { return new ContainerTag("main"); }
public static ContainerTag main(String text) { return new ContainerTag("main").withText(text); }
public static ContainerTag main(DomContent... dc) { return new ContainerTag("main").with(dc); }
public static ContainerTag main(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("main"), shortAttr); }
public static ContainerTag main(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("main").withText(text), shortAttr); }
public static ContainerTag main(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("main").with(dc), shortAttr); }
public static ContainerTag map() { return new ContainerTag("map"); }
public static ContainerTag map(String text) { return new ContainerTag("map").withText(text); }
public static ContainerTag map(DomContent... dc) { return new ContainerTag("map").with(dc); }
public static ContainerTag map(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("map"), shortAttr); }
public static ContainerTag map(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("map").withText(text), shortAttr); }
public static ContainerTag map(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("map").with(dc), shortAttr); }
public static ContainerTag mark() { return new ContainerTag("mark"); }
public static ContainerTag mark(String text) { return new ContainerTag("mark").withText(text); }
public static ContainerTag mark(DomContent... dc) { return new ContainerTag("mark").with(dc); }
public static ContainerTag mark(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("mark"), shortAttr); }
public static ContainerTag mark(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("mark").withText(text), shortAttr); }
public static ContainerTag mark(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("mark").with(dc), shortAttr); }
public static ContainerTag menu() { return new ContainerTag("menu"); }
public static ContainerTag menu(String text) { return new ContainerTag("menu").withText(text); }
public static ContainerTag menu(DomContent... dc) { return new ContainerTag("menu").with(dc); }
public static ContainerTag menu(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("menu"), shortAttr); }
public static ContainerTag menu(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("menu").withText(text), shortAttr); }
public static ContainerTag menu(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("menu").with(dc), shortAttr); }
public static ContainerTag menuitem() { return new ContainerTag("menuitem"); }
public static ContainerTag menuitem(String text) { return new ContainerTag("menuitem").withText(text); }
public static ContainerTag menuitem(DomContent... dc) { return new ContainerTag("menuitem").with(dc); }
public static ContainerTag menuitem(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("menuitem"), shortAttr); }
public static ContainerTag menuitem(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("menuitem").withText(text), shortAttr); }
public static ContainerTag menuitem(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("menuitem").with(dc), shortAttr); }
public static ContainerTag meter() { return new ContainerTag("meter"); }
public static ContainerTag meter(String text) { return new ContainerTag("meter").withText(text); }
public static ContainerTag meter(DomContent... dc) { return new ContainerTag("meter").with(dc); }
public static ContainerTag meter(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("meter"), shortAttr); }
public static ContainerTag meter(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("meter").withText(text), shortAttr); }
public static ContainerTag meter(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("meter").with(dc), shortAttr); }
public static ContainerTag nav() { return new ContainerTag("nav"); }
public static ContainerTag nav(String text) { return new ContainerTag("nav").withText(text); }
public static ContainerTag nav(DomContent... dc) { return new ContainerTag("nav").with(dc); }
public static ContainerTag nav(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("nav"), shortAttr); }
public static ContainerTag nav(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("nav").withText(text), shortAttr); }
public static ContainerTag nav(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("nav").with(dc), shortAttr); }
public static ContainerTag noscript() { return new ContainerTag("noscript"); }
public static ContainerTag noscript(String text) { return new ContainerTag("noscript").withText(text); }
public static ContainerTag noscript(DomContent... dc) { return new ContainerTag("noscript").with(dc); }
public static ContainerTag noscript(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("noscript"), shortAttr); }
public static ContainerTag noscript(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("noscript").withText(text), shortAttr); }
public static ContainerTag noscript(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("noscript").with(dc), shortAttr); }
public static ContainerTag object() { return new ContainerTag("object"); }
public static ContainerTag object(String text) { return new ContainerTag("object").withText(text); }
public static ContainerTag object(DomContent... dc) { return new ContainerTag("object").with(dc); }
public static ContainerTag object(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("object"), shortAttr); }
public static ContainerTag object(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("object").withText(text), shortAttr); }
public static ContainerTag object(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("object").with(dc), shortAttr); }
public static ContainerTag ol() { return new ContainerTag("ol"); }
public static ContainerTag ol(String text) { return new ContainerTag("ol").withText(text); }
public static ContainerTag ol(DomContent... dc) { return new ContainerTag("ol").with(dc); }
public static ContainerTag ol(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("ol"), shortAttr); }
public static ContainerTag ol(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("ol").withText(text), shortAttr); }
public static ContainerTag ol(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("ol").with(dc), shortAttr); }
public static ContainerTag optgroup() { return new ContainerTag("optgroup"); }
public static ContainerTag optgroup(String text) { return new ContainerTag("optgroup").withText(text); }
public static ContainerTag optgroup(DomContent... dc) { return new ContainerTag("optgroup").with(dc); }
public static ContainerTag optgroup(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("optgroup"), shortAttr); }
public static ContainerTag optgroup(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("optgroup").withText(text), shortAttr); }
public static ContainerTag optgroup(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("optgroup").with(dc), shortAttr); }
public static ContainerTag option() { return new ContainerTag("option"); }
public static ContainerTag option(String text) { return new ContainerTag("option").withText(text); }
public static ContainerTag option(DomContent... dc) { return new ContainerTag("option").with(dc); }
public static ContainerTag option(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("option"), shortAttr); }
public static ContainerTag option(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("option").withText(text), shortAttr); }
public static ContainerTag option(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("option").with(dc), shortAttr); }
public static ContainerTag output() { return new ContainerTag("output"); }
public static ContainerTag output(String text) { return new ContainerTag("output").withText(text); }
public static ContainerTag output(DomContent... dc) { return new ContainerTag("output").with(dc); }
public static ContainerTag output(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("output"), shortAttr); }
public static ContainerTag output(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("output").withText(text), shortAttr); }
public static ContainerTag output(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("output").with(dc), shortAttr); }
public static ContainerTag p() { return new ContainerTag("p"); }
public static ContainerTag p(String text) { return new ContainerTag("p").withText(text); }
public static ContainerTag p(DomContent... dc) { return new ContainerTag("p").with(dc); }
public static ContainerTag p(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("p"), shortAttr); }
public static ContainerTag p(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("p").withText(text), shortAttr); }
public static ContainerTag p(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("p").with(dc), shortAttr); }
public static ContainerTag pre() { return new ContainerTag("pre"); }
public static ContainerTag pre(String text) { return new ContainerTag("pre").withText(text); }
public static ContainerTag pre(DomContent... dc) { return new ContainerTag("pre").with(dc); }
public static ContainerTag pre(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("pre"), shortAttr); }
public static ContainerTag pre(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("pre").withText(text), shortAttr); }
public static ContainerTag pre(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("pre").with(dc), shortAttr); }
public static ContainerTag progress() { return new ContainerTag("progress"); }
public static ContainerTag progress(String text) { return new ContainerTag("progress").withText(text); }
public static ContainerTag progress(DomContent... dc) { return new ContainerTag("progress").with(dc); }
public static ContainerTag progress(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("progress"), shortAttr); }
public static ContainerTag progress(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("progress").withText(text), shortAttr); }
public static ContainerTag progress(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("progress").with(dc), shortAttr); }
public static ContainerTag q() { return new ContainerTag("q"); }
public static ContainerTag q(String text) { return new ContainerTag("q").withText(text); }
public static ContainerTag q(DomContent... dc) { return new ContainerTag("q").with(dc); }
public static ContainerTag q(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("q"), shortAttr); }
public static ContainerTag q(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("q").withText(text), shortAttr); }
public static ContainerTag q(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("q").with(dc), shortAttr); }
public static ContainerTag rp() { return new ContainerTag("rp"); }
public static ContainerTag rp(String text) { return new ContainerTag("rp").withText(text); }
public static ContainerTag rp(DomContent... dc) { return new ContainerTag("rp").with(dc); }
public static ContainerTag rp(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("rp"), shortAttr); }
public static ContainerTag rp(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("rp").withText(text), shortAttr); }
public static ContainerTag rp(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("rp").with(dc), shortAttr); }
public static ContainerTag rt() { return new ContainerTag("rt"); }
public static ContainerTag rt(String text) { return new ContainerTag("rt").withText(text); }
public static ContainerTag rt(DomContent... dc) { return new ContainerTag("rt").with(dc); }
public static ContainerTag rt(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("rt"), shortAttr); }
public static ContainerTag rt(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("rt").withText(text), shortAttr); }
public static ContainerTag rt(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("rt").with(dc), shortAttr); }
public static ContainerTag ruby() { return new ContainerTag("ruby"); }
public static ContainerTag ruby(String text) { return new ContainerTag("ruby").withText(text); }
public static ContainerTag ruby(DomContent... dc) { return new ContainerTag("ruby").with(dc); }
public static ContainerTag ruby(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("ruby"), shortAttr); }
public static ContainerTag ruby(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("ruby").withText(text), shortAttr); }
public static ContainerTag ruby(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("ruby").with(dc), shortAttr); }
public static ContainerTag s() { return new ContainerTag("s"); }
public static ContainerTag s(String text) { return new ContainerTag("s").withText(text); }
public static ContainerTag s(DomContent... dc) { return new ContainerTag("s").with(dc); }
public static ContainerTag s(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("s"), shortAttr); }
public static ContainerTag s(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("s").withText(text), shortAttr); }
public static ContainerTag s(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("s").with(dc), shortAttr); }
public static ContainerTag samp() { return new ContainerTag("samp"); }
public static ContainerTag samp(String text) { return new ContainerTag("samp").withText(text); }
public static ContainerTag samp(DomContent... dc) { return new ContainerTag("samp").with(dc); }
public static ContainerTag samp(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("samp"), shortAttr); }
public static ContainerTag samp(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("samp").withText(text), shortAttr); }
public static ContainerTag samp(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("samp").with(dc), shortAttr); }
public static ContainerTag script() { return new ContainerTag("script"); }
public static ContainerTag script(String text) { return new ContainerTag("script").withText(text); }
public static ContainerTag script(DomContent... dc) { return new ContainerTag("script").with(dc); }
public static ContainerTag script(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("script"), shortAttr); }
public static ContainerTag script(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("script").withText(text), shortAttr); }
public static ContainerTag script(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("script").with(dc), shortAttr); }
public static ContainerTag section() { return new ContainerTag("section"); }
public static ContainerTag section(String text) { return new ContainerTag("section").withText(text); }
public static ContainerTag section(DomContent... dc) { return new ContainerTag("section").with(dc); }
public static ContainerTag section(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("section"), shortAttr); }
public static ContainerTag section(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("section").withText(text), shortAttr); }
public static ContainerTag section(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("section").with(dc), shortAttr); }
public static ContainerTag select() { return new ContainerTag("select"); }
public static ContainerTag select(String text) { return new ContainerTag("select").withText(text); }
public static ContainerTag select(DomContent... dc) { return new ContainerTag("select").with(dc); }
public static ContainerTag select(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("select"), shortAttr); }
public static ContainerTag select(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("select").withText(text), shortAttr); }
public static ContainerTag select(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("select").with(dc), shortAttr); }
public static ContainerTag small() { return new ContainerTag("small"); }
public static ContainerTag small(String text) { return new ContainerTag("small").withText(text); }
public static ContainerTag small(DomContent... dc) { return new ContainerTag("small").with(dc); }
public static ContainerTag small(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("small"), shortAttr); }
public static ContainerTag small(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("small").withText(text), shortAttr); }
public static ContainerTag small(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("small").with(dc), shortAttr); }
public static ContainerTag span() { return new ContainerTag("span"); }
public static ContainerTag span(String text) { return new ContainerTag("span").withText(text); }
public static ContainerTag span(DomContent... dc) { return new ContainerTag("span").with(dc); }
public static ContainerTag span(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("span"), shortAttr); }
public static ContainerTag span(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("span").withText(text), shortAttr); }
public static ContainerTag span(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("span").with(dc), shortAttr); }
public static ContainerTag strong() { return new ContainerTag("strong"); }
public static ContainerTag strong(String text) { return new ContainerTag("strong").withText(text); }
public static ContainerTag strong(DomContent... dc) { return new ContainerTag("strong").with(dc); }
public static ContainerTag strong(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("strong"), shortAttr); }
public static ContainerTag strong(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("strong").withText(text), shortAttr); }
public static ContainerTag strong(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("strong").with(dc), shortAttr); }
public static ContainerTag style() { return new ContainerTag("style"); }
public static ContainerTag style(String text) { return new ContainerTag("style").withText(text); }
public static ContainerTag style(DomContent... dc) { return new ContainerTag("style").with(dc); }
public static ContainerTag style(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("style"), shortAttr); }
public static ContainerTag style(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("style").withText(text), shortAttr); }
public static ContainerTag style(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("style").with(dc), shortAttr); }
public static ContainerTag sub() { return new ContainerTag("sub"); }
public static ContainerTag sub(String text) { return new ContainerTag("sub").withText(text); }
public static ContainerTag sub(DomContent... dc) { return new ContainerTag("sub").with(dc); }
public static ContainerTag sub(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("sub"), shortAttr); }
public static ContainerTag sub(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("sub").withText(text), shortAttr); }
public static ContainerTag sub(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("sub").with(dc), shortAttr); }
public static ContainerTag summary() { return new ContainerTag("summary"); }
public static ContainerTag summary(String text) { return new ContainerTag("summary").withText(text); }
public static ContainerTag summary(DomContent... dc) { return new ContainerTag("summary").with(dc); }
public static ContainerTag summary(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("summary"), shortAttr); }
public static ContainerTag summary(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("summary").withText(text), shortAttr); }
public static ContainerTag summary(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("summary").with(dc), shortAttr); }
public static ContainerTag sup() { return new ContainerTag("sup"); }
public static ContainerTag sup(String text) { return new ContainerTag("sup").withText(text); }
public static ContainerTag sup(DomContent... dc) { return new ContainerTag("sup").with(dc); }
public static ContainerTag sup(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("sup"), shortAttr); }
public static ContainerTag sup(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("sup").withText(text), shortAttr); }
public static ContainerTag sup(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("sup").with(dc), shortAttr); }
public static ContainerTag table() { return new ContainerTag("table"); }
public static ContainerTag table(String text) { return new ContainerTag("table").withText(text); }
public static ContainerTag table(DomContent... dc) { return new ContainerTag("table").with(dc); }
public static ContainerTag table(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("table"), shortAttr); }
public static ContainerTag table(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("table").withText(text), shortAttr); }
public static ContainerTag table(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("table").with(dc), shortAttr); }
public static ContainerTag tbody() { return new ContainerTag("tbody"); }
public static ContainerTag tbody(String text) { return new ContainerTag("tbody").withText(text); }
public static ContainerTag tbody(DomContent... dc) { return new ContainerTag("tbody").with(dc); }
public static ContainerTag tbody(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("tbody"), shortAttr); }
public static ContainerTag tbody(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("tbody").withText(text), shortAttr); }
public static ContainerTag tbody(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("tbody").with(dc), shortAttr); }
public static ContainerTag td() { return new ContainerTag("td"); }
public static ContainerTag td(String text) { return new ContainerTag("td").withText(text); }
public static ContainerTag td(DomContent... dc) { return new ContainerTag("td").with(dc); }
public static ContainerTag td(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("td"), shortAttr); }
public static ContainerTag td(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("td").withText(text), shortAttr); }
public static ContainerTag td(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("td").with(dc), shortAttr); }
public static ContainerTag textarea() { return new ContainerTag("textarea"); }
public static ContainerTag textarea(String text) { return new ContainerTag("textarea").withText(text); }
public static ContainerTag textarea(DomContent... dc) { return new ContainerTag("textarea").with(dc); }
public static ContainerTag textarea(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("textarea"), shortAttr); }
public static ContainerTag textarea(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("textarea").withText(text), shortAttr); }
public static ContainerTag textarea(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("textarea").with(dc), shortAttr); }
public static ContainerTag tfoot() { return new ContainerTag("tfoot"); }
public static ContainerTag tfoot(String text) { return new ContainerTag("tfoot").withText(text); }
public static ContainerTag tfoot(DomContent... dc) { return new ContainerTag("tfoot").with(dc); }
public static ContainerTag tfoot(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("tfoot"), shortAttr); }
public static ContainerTag tfoot(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("tfoot").withText(text), shortAttr); }
public static ContainerTag tfoot(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("tfoot").with(dc), shortAttr); }
public static ContainerTag th() { return new ContainerTag("th"); }
public static ContainerTag th(String text) { return new ContainerTag("th").withText(text); }
public static ContainerTag th(DomContent... dc) { return new ContainerTag("th").with(dc); }
public static ContainerTag th(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("th"), shortAttr); }
public static ContainerTag th(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("th").withText(text), shortAttr); }
public static ContainerTag th(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("th").with(dc), shortAttr); }
public static ContainerTag thead() { return new ContainerTag("thead"); }
public static ContainerTag thead(String text) { return new ContainerTag("thead").withText(text); }
public static ContainerTag thead(DomContent... dc) { return new ContainerTag("thead").with(dc); }
public static ContainerTag thead(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("thead"), shortAttr); }
public static ContainerTag thead(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("thead").withText(text), shortAttr); }
public static ContainerTag thead(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("thead").with(dc), shortAttr); }
public static ContainerTag time() { return new ContainerTag("time"); }
public static ContainerTag time(String text) { return new ContainerTag("time").withText(text); }
public static ContainerTag time(DomContent... dc) { return new ContainerTag("time").with(dc); }
public static ContainerTag time(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("time"), shortAttr); }
public static ContainerTag time(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("time").withText(text), shortAttr); }
public static ContainerTag time(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("time").with(dc), shortAttr); }
public static ContainerTag title() { return new ContainerTag("title"); }
public static ContainerTag title(String text) { return new ContainerTag("title").withText(text); }
public static ContainerTag title(DomContent... dc) { return new ContainerTag("title").with(dc); }
public static ContainerTag title(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("title"), shortAttr); }
public static ContainerTag title(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("title").withText(text), shortAttr); }
public static ContainerTag title(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("title").with(dc), shortAttr); }
public static ContainerTag tr() { return new ContainerTag("tr"); }
public static ContainerTag tr(String text) { return new ContainerTag("tr").withText(text); }
public static ContainerTag tr(DomContent... dc) { return new ContainerTag("tr").with(dc); }
public static ContainerTag tr(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("tr"), shortAttr); }
public static ContainerTag tr(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("tr").withText(text), shortAttr); }
public static ContainerTag tr(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("tr").with(dc), shortAttr); }
public static ContainerTag u() { return new ContainerTag("u"); }
public static ContainerTag u(String text) { return new ContainerTag("u").withText(text); }
public static ContainerTag u(DomContent... dc) { return new ContainerTag("u").with(dc); }
public static ContainerTag u(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("u"), shortAttr); }
public static ContainerTag u(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("u").withText(text), shortAttr); }
public static ContainerTag u(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("u").with(dc), shortAttr); }
public static ContainerTag ul() { return new ContainerTag("ul"); }
public static ContainerTag ul(String text) { return new ContainerTag("ul").withText(text); }
public static ContainerTag ul(DomContent... dc) { return new ContainerTag("ul").with(dc); }
public static ContainerTag ul(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("ul"), shortAttr); }
public static ContainerTag ul(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("ul").withText(text), shortAttr); }
public static ContainerTag ul(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("ul").with(dc), shortAttr); }
public static ContainerTag var() { return new ContainerTag("var"); }
public static ContainerTag var(String text) { return new ContainerTag("var").withText(text); }
public static ContainerTag var(DomContent... dc) { return new ContainerTag("var").with(dc); }
public static ContainerTag var(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("var"), shortAttr); }
public static ContainerTag var(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("var").withText(text), shortAttr); }
public static ContainerTag var(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("var").with(dc), shortAttr); }
public static ContainerTag video() { return new ContainerTag("video"); }
public static ContainerTag video(String text) { return new ContainerTag("video").withText(text); }
public static ContainerTag video(DomContent... dc) { return new ContainerTag("video").with(dc); }
public static ContainerTag video(Attr.ShortForm shortAttr) { return Attr.addTo(new ContainerTag("video"), shortAttr); }
public static ContainerTag video(Attr.ShortForm shortAttr, String text) { return Attr.addTo(new ContainerTag("video").withText(text), shortAttr); }
public static ContainerTag video(Attr.ShortForm shortAttr, DomContent... dc) { return Attr.addTo(new ContainerTag("video").with(dc), shortAttr); }
}

View File

@@ -1,114 +1,174 @@
package j2html.attributes;
import j2html.tags.Tag;
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";
public static class ShortForm {
String id;
String classes;
private ShortForm(String id, String classes) {
this.id = id;
this.classes = classes;
}
boolean hasId() {
return id != null && !"".equals(id);
}
boolean hasClasses() {
return classes != null && !"".equals(classes);
}
}
public static ShortForm shortFormFromAttrsString(String attrs) {
if (!attrs.contains(".") && !attrs.contains(("#"))) {
throw new IllegalArgumentException("String must contain either id (#) or class (.)");
}
if (attrs.split("#").length > 2) {
throw new IllegalArgumentException("Only one id (#) allowed");
}
String id = "";
StringBuilder classes = new StringBuilder();
for (String attr : attrs.split("\\.")) {
if (attr.contains("#")) {
if (!attr.startsWith("#")) {
throw new IllegalArgumentException("# cannot be in the middle of string");
}
id = attr.replace("#", "");
} else {
classes.append(attr).append(" ");
}
}
return new ShortForm(id.trim(), classes.toString().trim());
}
public static <T extends Tag<T>> T addTo(T tag, ShortForm shortForm) {
if (shortForm.hasId() && shortForm.hasClasses()) {
return tag.withId(shortForm.id).withClass(shortForm.classes);
}
if (shortForm.hasId()) {
return tag.withId(shortForm.id);
}
if (shortForm.hasClasses()) {
return tag.withClass(shortForm.classes);
}
return tag;
}
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 j2html.utils.SimpleHtmlEscaper.escape;
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 = escape(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,86 +1,108 @@
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);
this.children = new ArrayList<>();
public ContainerTag(String tagName) {
super(tagName);
this.children = new ArrayList<DomContent>();
}
/**
* 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.");
throw new RuntimeException("Cannot append a tag to itself.");
}
if (child == null) {
return this; // in some cases, like when using iff(), we ignore null children
}
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) {
children.forEach(this::with);
for (DomContent child : children) {
this.with(child);
}
}
return this;
}
/**
* Call with-method based on condition
* {@link #with(List children)}
*/
public ContainerTag condWith(boolean condition, List<Tag> children) {
return condition ? this.with(children) : this;
}
/**
* Appends the tags to the end of this element
* Call with-method based on condition
* {@link #with(java.lang.Iterable)}
*
* @param children tags to be appended
* @param condition the condition to use
* @param children DomContent-objects to be appended if condition met
* @return itself for easy chaining
*/
public ContainerTag with(Tag... children) {
for (Tag aChildren : children) {
with(aChildren);
public ContainerTag condWith(boolean condition, Iterable<? extends DomContent> children) {
return condition ? this.with(children) : this;
}
/**
* Appends the DomContent-objects to the end of this element
*
* @param children DomContent-objects to be appended
* @return itself for easy chaining
*/
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
@@ -89,45 +111,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() {
//very slow
// return renderOpenTag() + children.stream().map(Tag::render).collect(Collectors.joining()) + renderCloseTag();
//pretty fast
// StringBuilder rendered = new StringBuilder(renderOpenTag());
// children.forEach(rendered::append);
// rendered.append(renderCloseTag());
// return rendered.toString();
//fastest
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());
}
}
@@ -136,56 +130,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

@@ -0,0 +1,24 @@
package j2html.tags;
public class DomContentJoiner {
public static UnescapedText join(CharSequence delimiter, boolean fixPeriodAndCommaSpacing, Object... stringOrDomObjects) {
StringBuilder sb = new StringBuilder();
for (Object o : stringOrDomObjects) {
if (o instanceof String) {
sb.append(((String) o).trim()).append(" ");
} else if (o instanceof DomContent) {
sb.append(((DomContent) o).render().trim()).append(" ");
} else {
throw new RuntimeException("You can only join DomContent and String objects");
}
}
String joined = sb.toString().trim();
if (fixPeriodAndCommaSpacing) {
joined = joined.replaceAll("\\s\\.", ".");
joined = joined.replaceAll("\\s\\,", ",");
}
return new UnescapedText(joined);
}
}

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

@@ -0,0 +1,53 @@
package j2html.tags;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import j2html.utils.CSSMin;
import j2html.utils.JSMin;
import static j2html.TagCreator.*;
public class InlineStaticResource {
public enum TargetFormat {CSS_MIN, CSS, JS_MIN, JS}
public static ContainerTag get(String path, TargetFormat format) {
String fileString = getFileAsString(path);
switch (format) {
case CSS_MIN : return style().with(rawHtml(CSSMin.compress(fileString)));
case JS_MIN : return script().with(rawHtml(JSMin.compressJs(fileString)));
case CSS : return style().with(rawHtml(fileString));
case JS : return script().with(rawHtml(fileString));
default : throw new RuntimeException("Invalid target format");
}
}
public static String getFileAsString(String path) {
try {
return readFileAsString(InlineStaticResource.class.getResource(path).getPath());
} catch (Exception e1) {
try {
return readFileAsString(path);
} catch (Exception e2) {
throw new RuntimeException("Couldn't find file with path='" + path + "'");
}
}
}
/**
* @author kjheimark <3
*/
private static String readFileAsString(String path) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
StringBuilder sb = new StringBuilder();
int c;
while ((c = bufferedReader.read()) >= 0 && c >= 0) {
sb.append((char) c);
}
return sb.toString();
}
}

View File

@@ -1,31 +1,48 @@
package j2html.tags;
import java.util.ArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import j2html.attributes.Attr;
import j2html.attributes.Attribute;
import java.util.ArrayList;
public abstract class Tag<T extends Tag<T>> extends DomContent {
public abstract class Tag {
protected String tagName;
private ArrayList<Attribute> attributes;
protected String tag;
protected ArrayList<Attribute> attributes;
protected Tag parent;
protected Tag(String tagType) {
this.tag = tagType;
this.attributes = new ArrayList<>();
protected Tag(String tagName) {
this.tagName = tagName;
this.attributes = new ArrayList<Attribute>();
}
public void setParent(Tag parent) {
this.parent = parent;
public String getTagName() {
return this.tagName;
}
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,27 +55,110 @@ 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;
}
/**
* Sets a custom attribute without value
*
* @param attribute the attribute name
* @return itself for easy chaining
* @see Tag#attr(String, String)
*/
public T attr(String attribute) {
return attr(attribute, null);
}
/**
* 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() {
// final String tagAttributes = attributes.stream().map(Attribute::render).collect(Collectors.joining());
// return "<" + tag + tagAttributes + ">"; //too slow
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 withClasses(String... classes) {
StringBuilder sb = new StringBuilder();
for (String s : classes) {
sb.append(s != null ? s : "").append(" ");
}
return attr(Attr.CLASS, sb.toString().trim());
}
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

@@ -0,0 +1,167 @@
package j2html.tags;
import java.util.Arrays;
import java.util.List;
class TagCreatorCodeGenerator {
public static void main(String[] args) {
System.out.println("// EmptyTags, generated in " + TagCreatorCodeGenerator.class);
for (String tag : emptyTags()) {
String emptyA1 = "public static EmptyTag " + tag + "()";
String emptyA2 = "{ return new EmptyTag(\"" + tag + "\"); }";
// Attr shorthands
String emptyB1 = "public static EmptyTag " + tag + "(Attr.ShortForm shortAttr)";
String emptyB2 = "{ return Attr.addTo(new EmptyTag(\"" + tag + "\"), shortAttr); }";
// Print
System.out.println(String.format("%-80s%1s", emptyA1, emptyA2));
System.out.println(String.format("%-80s%1s", emptyB1, emptyB2));
System.out.println("");
}
System.out.println("// ContainerTags, generated in " + TagCreatorCodeGenerator.class);
for (String tag : containerTags()) {
String containerA1 = "public static ContainerTag " + tag + "()";
String containerA2 = "{ return new ContainerTag(\"" + tag + "\"); }";
String containerB1 = "public static ContainerTag " + tag + "(String text)";
String containerB2 = "{ return new ContainerTag(\"" + tag + "\").withText(text); }";
String containerC1 = "public static ContainerTag " + tag + "(DomContent... dc)";
String containerC2 = "{ return new ContainerTag(\"" + tag + "\").with(dc); }";
// Attr shorthands
String containerD1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr)";
String containerD2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\"), shortAttr); }";
String containerE1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr, String text)";
String containerE2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\").withText(text), shortAttr); }";
String containerF1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr, DomContent... dc)";
String containerF2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\").with(dc), shortAttr); }";
// Print
System.out.println(String.format("%-80s%1s", containerA1, containerA2));
System.out.println(String.format("%-80s%1s", containerB1, containerB2));
System.out.println(String.format("%-80s%1s", containerC1, containerC2));
System.out.println(String.format("%-80s%1s", containerD1, containerD2));
System.out.println(String.format("%-80s%1s", containerE1, containerE2));
System.out.println(String.format("%-80s%1s", containerF1, containerF2));
System.out.println("");
}
}
// This is a method that contains all ContainerTags, there is nothing below it
private static List<String> emptyTags() {
return Arrays.asList(
"area",
"base",
"br",
"col",
//"!DOCTYPE html",
"embed",
"hr",
"img",
"input",
"keygen",
"link",
"meta",
"param",
"source",
"track",
"wbr"
);
}
private static List<String> containerTags() {
return Arrays.asList(
"a",
"abbr",
"address",
"article",
"aside",
"audio",
"b",
"bdi",
"bdo",
"blockquote",
"body",
"button",
"canvas",
"caption",
"cite",
"code",
"colgroup",
"datalist",
"dd",
"del",
"details",
"dfn",
"dialog",
"div",
"dl",
"dt",
"em",
"fieldset",
"figcaption",
"figure",
"footer",
"form",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"head",
"header",
"html",
"i",
"iframe",
"ins",
"kbd",
"label",
"legend",
"li",
"main",
"map",
"mark",
"menu",
"menuitem",
"meter",
"nav",
"noscript",
"object",
"ol",
"optgroup",
"option",
"output",
"p",
"pre",
"progress",
"q",
"rp",
"rt",
"ruby",
"s",
"samp",
"script",
"section",
"select",
"small",
"span",
"strong",
"style",
"sub",
"summary",
"sup",
"table",
"tbody",
"td",
"textarea",
"tfoot",
"th",
"thead",
"time",
"title",
"tr",
"u",
"ul",
"var",
"video"
);
}
}

View File

@@ -1,22 +1,18 @@
package j2html.tags;
import j2html.utils.SimpleEscaper;
import static j2html.utils.SimpleHtmlEscaper.escape;
public class Text extends DomContent {
public class Text extends Tag {
private String text;
public Text(String text) {
super(text);
this.text = text;
}
@Override
public String render() {
return escape(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

@@ -0,0 +1,695 @@
/**
* * 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* 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>
* </ul>
* Some code is based on the YUI CssCompressor code, by Julien Lecomte.
*
* @author Barry van Oudtshoorn
* Repo: https://github.com/barryvan/CSSMin
*/
package j2html.utils;
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());
static boolean debugLogging = false;
/**
* Minify supplied CSS.
*
* @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
char curr;
BufferedReader br = new BufferedReader(new StringReader(input));
StringBuilder sb = new StringBuilder();
if (debugLogging) {
LOG.info("Reading file into StringBuffer...");
}
String s;
while ((s = br.readLine()) != null) {
if (s.trim().equals("")) {
continue;
}
sb.append(s);
}
if (debugLogging) {
LOG.info("Removing comments...");
}
// Find the start of the comment
n = 0;
while ((n = sb.indexOf("/*", n)) != -1) {
if (sb.charAt(n + 2) == '*') { // Retain special comments
n += 2;
continue;
}
k = sb.indexOf("*/", n + 2);
if (k == -1) {
throw new UnterminatedCommentException();
}
sb.delete(n, k + 2);
}
if (debugLogging) {
LOG.info(sb.toString());
LOG.info("\n\n");
}
if (debugLogging) {
LOG.info("Parsing and processing selectors...");
}
Vector<Selector> selectors = new Vector<Selector>();
n = 0;
j = 0;
for (int i = 0; i < sb.length(); i++) {
curr = sb.charAt(i);
if (j < 0) {
throw new UnbalancedBracesException();
}
if (curr == '{') {
j++;
} else if (curr == '}') {
j--;
if (j == 0) {
try {
selectors.addElement(new Selector(sb.substring(n, i + 1)));
} catch (UnterminatedSelectorException usex) {
LOG.warning("Unterminated selector: " + usex.getMessage());
} catch (EmptySelectorBodyException ebex) {
if (debugLogging) {
LOG.warning("Empty selector body: " + ebex.getMessage());
}
}
n = i + 1;
}
}
}
StringBuilder result = new StringBuilder();
for (Selector selector : selectors) {
result.append(selector);
}
if (debugLogging) {
LOG.info("Process completed successfully.");
}
return result.toString();
} catch (UnterminatedCommentException ucex) {
LOG.warning("Unterminated comment.");
} catch (UnbalancedBracesException ubex) {
LOG.warning("Unbalanced braces.");
} catch (Exception ex) {
LOG.warning(ex.getMessage());
}
return null;
}
}
class Selector {
private static final Logger LOG = Logger.getLogger(Selector.class.getName());
private Property[] properties = null;
private Vector<Selector> subSelectors = null;
private String selector;
/**
* Creates a new Selector using the supplied strings.
*
* @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.
*/
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);
}
this.selector = parts[0].trim();
// 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<Selector>();
parts = selector.split("(\\s*\\{\\s*)|(\\s*\\}\\s*)");
for (int i = 1; i < parts.length; i += 2) {
parts[i] = parts[i].trim();
parts[i + 1] = parts[i + 1].trim();
if (!(parts[i].equals("") || (parts[i + 1].equals("")))) {
this.subSelectors.addElement(new Selector(parts[i] + "{" + parts[i + 1] + "}"));
}
}
} else {
String contents = parts[parts.length - 1].trim();
if (CSSMin.debugLogging) {
LOG.info("Parsing selector: " + this.selector);
LOG.info("\t" + contents);
}
if (contents.charAt(contents.length() - 1) != '}') { // Ensure that we have a leading and trailing brace.
throw new UnterminatedSelectorException(selector);
}
if (contents.length() == 1) {
throw new EmptySelectorBodyException(selector);
}
contents = contents.substring(0, contents.length() - 2);
this.properties = new Property[0];
this.properties = parseProperties(contents).toArray(this.properties);
sortProperties(this.properties);
}
}
/**
* Prints out this selector and its contents nicely, with the contents sorted alphabetically.
*
* @return A string representing this selector, minified.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.selector).append("{");
if (this.subSelectors != null) {
for (Selector s : this.subSelectors) {
sb.append(s.toString());
}
}
if (this.properties != null) {
for (Property p : this.properties) {
sb.append(p.toString());
}
}
if (sb.charAt(sb.length() - 1) == ';') {
sb.deleteCharAt(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
/**
* Parses out the properties of a selector's body.
*
* @param contents The body; for example, "border: solid 1px red; color: blue;"
* @return An array of properties parsed from this selector.
*/
private ArrayList<Property> parseProperties(String contents) {
ArrayList<String> parts = new ArrayList<String>();
boolean bInsideString = false,
bInsideURL = false;
int j = 0;
String substr;
for (int i = 0; i < contents.length(); i++) {
if (bInsideString) { // If we're inside a string
bInsideString = !(contents.charAt(i) == '"');
} else if (bInsideURL) { // If we're inside a URL
bInsideURL = !(contents.charAt(i) == ')');
} 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;
}
} else if (contents.charAt(i) == ';') {
substr = contents.substring(j, i);
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
j = i + 1;
}
}
substr = contents.substring(j, contents.length());
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
ArrayList<Property> results = new ArrayList<Property>();
for (String part : parts) {
try {
results.add(new Property(part));
} catch (IncompletePropertyException ipex) {
LOG.warning("Incomplete property in selector \"" + this.selector + "\": \"" + ipex.getMessage() + "\"");
}
}
return results;
}
/**
* Sorts the properties array to enhance gzipping.
*
* @param properties The array to be sorted.
*/
private void sortProperties(Property[] properties) {
Arrays.sort(properties);
}
}
class Property implements Comparable<Property> {
private static final Logger LOG = Logger.getLogger(Property.class.getName());
private String property;
private Part[] parts;
/**
* Creates a new Property using the supplied strings. Parses out the values of the property selector.
*
* @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.
*/
Property(String property) throws IncompletePropertyException {
try {
// Parse the property.
ArrayList<String> parts = new ArrayList<String>();
boolean bCanSplit = true;
int j = 0;
String substr;
if (CSSMin.debugLogging) {
LOG.info("\t\tExamining property: " + property);
}
for (int i = 0; i < property.length(); i++) {
if (!bCanSplit) { // If we're inside a string
bCanSplit = (property.charAt(i) == '"');
} else if (property.charAt(i) == '"') {
bCanSplit = false;
} else if (property.charAt(i) == ':' && parts.isEmpty()) {
substr = property.substring(j, i);
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
j = i + 1;
}
}
substr = property.substring(j, property.length());
if (!(substr.trim().equals(""))) {
parts.add(substr);
}
if (parts.size() < 2) {
throw new IncompletePropertyException(property);
}
String prop = parts.get(0).trim();
if (!(prop.length() > 2 && prop.substring(0, 2).equals("--"))) {
prop = prop.toLowerCase();
}
this.property = prop;
this.parts = parseValues(simplifyColours(parts.get(1).trim().replaceAll(", ", ",")));
} catch (PatternSyntaxException e) {
// Invalid regular expression used.
}
}
/**
* Prints out this property nicely.
*
* @return A string representing this property, minified.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.property).append(":");
for (Part p : this.parts) {
sb.append(p.toString()).append(",");
}
sb.deleteCharAt(sb.length() - 1); // Delete the trailing comma.
sb.append(";");
if (CSSMin.debugLogging) {
LOG.info(sb.toString());
}
return sb.toString();
}
/**
* Compare this property with another.
*/
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.
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);
}
return thisProp;
}
/**
* Parse the values out of a property.
*
* @param contents The property to parse
* @return An array of Parts
*/
private Part[] parseValues(String contents) {
String[] parts = contents.split(",");
Part[] results = new Part[parts.length];
for (int i = 0; i < parts.length; i++) {
try {
results[i] = new Part(parts[i], property);
} catch (Exception e) {
LOG.warning(e.getMessage());
results[i] = null;
}
}
return results;
}
private String simplifyColours(String contents) {
// This replacement, although it results in a smaller uncompressed file,
// actually makes the gzipped file bigger -- people tend to use rgba(0,0,0,0.x)
// quite a lot, which means that rgba(0,0,0,0) has its first eight or so characters
// compressed really efficiently; much more so than "transparent".
//contents = contents.replaceAll("rgba\\(0,0,0,0\\)", "transparent");
return simplifyRGBColours(contents);
}
// Convert rgb(51,102,153) to #336699 (this code largely based on YUI code)
private String simplifyRGBColours(String contents) {
StringBuffer newContents = new StringBuffer();
StringBuffer hexColour;
String[] rgbColours;
int colourValue;
Pattern pattern = Pattern.compile("rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)");
Matcher matcher = pattern.matcher(contents);
while (matcher.find()) {
hexColour = new StringBuffer("#");
rgbColours = matcher.group(1).split(",");
for (String rgbColour : rgbColours) {
colourValue = Integer.parseInt(rgbColour);
if (colourValue < 16) {
hexColour.append("0");
}
hexColour.append(Integer.toHexString(colourValue));
}
matcher.appendReplacement(newContents, hexColour.toString());
}
matcher.appendTail(newContents);
return newContents.toString();
}
}
class Part {
private String contents;
private String property;
/**
* Create a new property by parsing the given string.
*
* @param contents The string to parse.
* @throws Exception If the part cannot be parsed.
*/
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.
this.contents = " " + contents;
this.property = property;
simplify();
}
private void simplify() {
// !important doesn't need to be spaced
this.contents = this.contents.replaceAll(" !important", "!important");
// Replace 0in, 0cm, etc. with just 0
this.contents = this.contents.replaceAll("(\\s)(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2");
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";
}
// Simplify multiple-parameter properties
simplifyParameters();
// Simplify font weights
simplifyFontWeights();
// Strip unnecessary quotes from url() and single-word parts, and make as much lowercase as possible.
simplifyQuotesAndCaps();
// Simplify colours
simplifyColourNames();
simplifyHexColours();
}
private void simplifyParameters() {
if (this.property.equals("background-size")) {
return;
}
StringBuilder newContents = new StringBuilder();
String[] params = this.contents.split(" ");
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
params = Arrays.copyOf(params, 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
params = Arrays.copyOf(params, 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
params = Arrays.copyOf(params, 1);
}
for (String param : params) {
newContents.append(param).append(" ");
}
newContents.deleteCharAt(newContents.length() - 1); // Delete the trailing space
this.contents = newContents.toString();
}
private void simplifyFontWeights() {
if (!this.property.equals("font-weight")) {
return;
}
String lcContents = this.contents.toLowerCase();
for (int i = 0; i < Constants.fontWeightNames.length; i++) {
if (lcContents.equals(Constants.fontWeightNames[i])) {
this.contents = Constants.fontWeightValues[i];
break;
}
}
}
private void simplifyQuotesAndCaps() {
// Strip quotes from URLs
if ((this.contents.length() > 4) && (this.contents.substring(0, 4).equalsIgnoreCase("url("))) {
this.contents = this.contents.replaceAll("(?i)url\\(('|\")?(.*?)\\1\\)", "url($2)");
} else if ((this.contents.length() > 4) && (this.contents.substring(0, 4).equalsIgnoreCase("var("))) {
this.contents = this.contents.replaceAll("\\s", "");
} else {
String[] words = this.contents.split("\\s");
if (words.length == 1) {
if (!this.property.equalsIgnoreCase("animation-name")) {
this.contents = this.contents.toLowerCase();
}
this.contents = this.contents.replaceAll("('|\")?(.*?)\1", "$2");
}
}
}
private void simplifyColourNames() {
String lcContents = this.contents.toLowerCase();
for (int i = 0; i < Constants.htmlColourNames.length; i++) {
if (lcContents.equals(Constants.htmlColourNames[i])) {
if (Constants.htmlColourValues[i].length() < Constants.htmlColourNames[i].length()) {
this.contents = Constants.htmlColourValues[i];
}
break;
} else if (lcContents.equals(Constants.htmlColourValues[i])) {
if (Constants.htmlColourNames[i].length() < Constants.htmlColourValues[i].length()) {
this.contents = Constants.htmlColourNames[i];
}
}
}
}
private void simplifyHexColours() {
StringBuffer newContents = new StringBuffer();
Pattern pattern = Pattern.compile("#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])");
Matcher matcher = pattern.matcher(this.contents);
while (matcher.find()) {
if (matcher.group(1).equalsIgnoreCase(matcher.group(2)) && matcher.group(3).equalsIgnoreCase(matcher.group(4)) && matcher.group(5).equalsIgnoreCase(matcher.group(6))) {
matcher.appendReplacement(newContents, "#" + matcher.group(1).toLowerCase() + matcher.group(3).toLowerCase() + matcher.group(5).toLowerCase());
} else {
matcher.appendReplacement(newContents, matcher.group().toLowerCase());
}
}
matcher.appendTail(newContents);
this.contents = newContents.toString();
}
/**
* Returns itself.
*
* @return this part's string representation.
*/
public String toString() {
return this.contents;
}
}
class UnterminatedCommentException extends Exception {
}
class UnbalancedBracesException extends Exception {
}
class IncompletePropertyException extends Exception {
private final String message;
IncompletePropertyException(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
class EmptySelectorBodyException extends Exception {
private final String message;
EmptySelectorBodyException(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
class UnterminatedSelectorException extends Exception {
private final String message;
UnterminatedSelectorException(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
class IncompleteSelectorException extends Exception {
private final String message;
IncompleteSelectorException(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
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"};
}

View File

@@ -0,0 +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;
public class JSMin {
/**
* 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 (Exception 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,36 @@
package j2html.utils;
public class SimpleEscaper {
public static String escape(String s) {
if (s == null) {
return null;
}
StringBuilder escapedText = new StringBuilder();
char currentChar;
for (int i = 0; i < s.length(); i++) {
currentChar = s.charAt(i);
switch (currentChar) {
case '<':
escapedText.append("&lt;");
break;
case '>':
escapedText.append("&gt;");
break;
case '&':
escapedText.append("&amp;");
break;
case '"':
escapedText.append("&quot;");
break;
case '\'':
escapedText.append("&#x27;");
break;
default:
escapedText.append(currentChar);
}
}
return escapedText.toString();
}
}

View File

@@ -1,28 +0,0 @@
package j2html.utils;
public class SimpleHtmlEscaper {
/**
* Simple approach from http://stackoverflow.com/a/25228492/4893160 ... good enough ?
* Apache StringEscapeUtils is extremely slow compared (probably because it's a lot safer!)
* @param s the string to be escaped
* @return the escaped string
*/
public static String escape(String s) {
if("".equals(s)){ return ""; }
if(s == null) { return null; }
StringBuilder out = new StringBuilder(Math.max(16, s.length()));
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
out.append("&#");
out.append((int) c);
out.append(';');
} else {
out.append(c);
}
}
return out.toString();
}
}

View File

@@ -0,0 +1 @@
public class AnyContent{}

7
src/test/files/test.css Normal file
View File

@@ -0,0 +1,7 @@
body {
background: goldenrod;
margin-top: 10px;
margin-right: 10px;
margin-bottom: 10px;
margin-left: 10px;
}

3
src/test/files/test.html Normal file
View File

@@ -0,0 +1,3 @@
<body>
Any content
</body>

6
src/test/files/test.js Normal file
View File

@@ -0,0 +1,6 @@
(function () {
var test = 5;
var tast = 10;
var testTast = test + tast;
console.log(testTast);
})();

View File

@@ -0,0 +1,49 @@
package j2html;
import java.util.concurrent.Callable;
import org.apache.commons.lang3.StringEscapeUtils;
import org.junit.Test;
import j2html.utils.SimpleEscaper;
public class PerformanceTest {
private String shortTestString = "<body>\n"
+ " <h1 class=\"example\">Heading!</h1>\n"
+ " <img src=\"img/hello.png\">\n"
+ "</body>";
// syntax-highlighted getting started example from j2html.com:
private String longTestString =
"<pre class=\" language-java\"><code class=\" language-java\"><span class=\"token keyword\">import</span> <span class=\"token keyword\">static</span> j2html<span class=\"token punctuation\">.</span>TagCreator<span class=\"token punctuation\">.</span>*<span class=\"token punctuation\">;</span>\n"
+ "\n"
+ "<span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Main</span> <span class=\"token punctuation\">{</span>\n"
+ " <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">void</span> <span class=\"token function\">main<span class=\"token punctuation\">(</span></span>String<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span> args<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n"
+ " <span class=\"token function\">body<span class=\"token punctuation\">(</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">with<span class=\"token punctuation\">(</span></span>\n"
+ " <span class=\"token function\">h1<span class=\"token punctuation\">(</span></span><span class=\"token string\">\"Heading!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">withClass<span class=\"token punctuation\">(</span></span><span class=\"token string\">\"example\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n"
+ " <span class=\"token function\">img<span class=\"token punctuation\">(</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">withSrc<span class=\"token punctuation\">(</span></span><span class=\"token string\">\"img/hello.png\"</span><span class=\"token punctuation\">)</span>\n"
+ " <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">render<span class=\"token punctuation\">(</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n"
+ " <span class=\"token punctuation\">}</span>\n"
+ "<span class=\"token punctuation\">}</span>\n"
+ "</code></pre>";
@Test
public void test_escaper_performnce() throws Exception {
timeEscaper("SimpleEscaper#short", () -> SimpleEscaper.escape(shortTestString));
timeEscaper("SimpleEscaper#long", () -> SimpleEscaper.escape(longTestString));
timeEscaper("ApacheEscaper#short", () -> StringEscapeUtils.escapeHtml4(shortTestString));
timeEscaper("ApacheEscaper#long", () -> StringEscapeUtils.escapeHtml4(longTestString));
}
private void timeEscaper(String name, Callable escaper) throws Exception {
long startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
escaper.call();
}
long endTime = System.nanoTime();
long durationMs = (endTime - startTime) / 1000000;
System.out.println(String.format("%-21s%s", name + ":", +durationMs + "ms"));
}
}

View File

@@ -0,0 +1,61 @@
package j2html.attributes;
import org.junit.Test;
import static j2html.TagCreator.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class AttrShortFormTest {
@Test
public void addTo_emptyTag() throws Exception {
String expected = "<input id=\"some-id\" class=\"some-class\">";
String actual = input(attrs("#some-id.some-class")).render();
assertThat(actual, is(expected));
}
@Test
public void addTo_containerTag() throws Exception {
String expected = "<div id=\"some-id\" class=\"some-class\"></div>";
String actual = div(attrs("#some-id.some-class")).render();
assertThat(actual, is(expected));
}
@Test
public void addTo_justId() throws Exception {
String expected = "<div id=\"some-id\"></div>";
String actual = div(attrs("#some-id")).render();
assertThat(actual, is(expected));
}
@Test
public void addTo_justClass() throws Exception {
String expected = "<div class=\"some-class\"></div>";
String actual = div(attrs(".some-class")).render();
assertThat(actual, is(expected));
}
@Test
public void addTo_addTwoClasses() throws Exception {
String expected = "<div class=\"some-class some-other-class\"></div>";
String actual = div(attrs(".some-class.some-other-class")).render();
assertThat(actual, is(expected));
}
@Test(expected = IllegalArgumentException.class)
public void addTo_stringWithoutIdOrClass() throws Exception {
div(attrs("some-class")).render();
}
@Test(expected = IllegalArgumentException.class)
public void addTo_stringWithTwoIds() throws Exception {
div(attrs("#id1#id2")).render();
}
@Test(expected = IllegalArgumentException.class)
public void addTo_stringWithStupidlyPlacedId() throws Exception {
div(attrs("id1#id2")).render();
}
}

View File

@@ -1,30 +1,32 @@
package j2html.attributes;
import j2html.tags.ContainerTag;
import org.junit.Test;
import static junit.framework.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,27 @@ package j2html.tags;
import org.junit.Test;
import static j2html.TagCreator.*;
import static junit.framework.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.iff;
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 {
@@ -11,34 +30,67 @@ public class ComplexRenderTest {
boolean USER_SHOULD_LOG_IN = true;
boolean USER_SHOULD_SIGN_UP = false;
return document().render() +
html().with(
head().with(
title().withText("Test")
),
body().with(
header().with(
h1("Test Header")
),
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")
)
),
footer().withText("Test Footer"),
script().withSrc("/testScript.js")
html().with(
head().with(
title().withText("Test")
),
body().with(
header().with(
h1().with(
text("Test Header "),
a("with link").withHref("http://example.com"),
text(".")
)
).render();
),
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"))
),
footer().attr(Attr.CLASS, "footer").condAttr(1 == 1, Attr.ID, "id").withText("Test Footer"),
script().withSrc("/testScript.js")
)
).render();
}
private String renderTest2() {
boolean USER_SHOULD_LOG_IN = true;
boolean USER_SHOULD_SIGN_UP = false;
return document().render() +
html(
head(
title("Test")
),
body(
header(
h1(
text("Test Header "),
a("with link").withHref("http://example.com"),
text(".")
)
),
main(
h2("Test Form"),
div(
input().withType("email").withName("email").withPlaceholder("Email"),
input().withType("password").withName("password").withPlaceholder("Password"),
iff(USER_SHOULD_LOG_IN, button().withType("submit").withText("Login")),
iff(USER_SHOULD_SIGN_UP, button().withType("submit").withText("Signup"))
)
),
footer("Test Footer").attr(Attr.CLASS, "footer").condAttr(1 == 1, Attr.ID, "id"),
script().withSrc("/testScript.js")
)
).render();
}
@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));
assertThat(renderTest2(), is(expectedResult));
}
}

View File

@@ -2,32 +2,41 @@ package j2html.tags;
import org.junit.Test;
import static j2html.TagCreator.*;
import static junit.framework.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

@@ -0,0 +1,45 @@
package j2html.tags;
import org.junit.Test;
import static j2html.TagCreator.fileAsEscapedString;
import static j2html.TagCreator.fileAsString;
import static j2html.TagCreator.scriptWithInlineFile_min;
import static j2html.TagCreator.styleWithInlineFile_min;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class InlineStaticResourceTest {
private static final String EOL = System.getProperty("line.separator"); // System independent End Of Line
@Test
public void testAllTags() throws Exception {
String expectedCss = "<style>body{background:#daa520;margin-bottom:10px;margin-left:10px;margin-right:10px;margin-top:10px}</style>";
String expectedJs = "<script>(function(){var test=5;var tast=10;var testTast=test+tast;console.log(testTast);})();</script>";
String expectedHtml = "<body>" + EOL + " Any content" + EOL + "</body>" + EOL;
String expectedEscapedHtml = "&lt;body&gt;" + EOL + " Any content" + EOL + "&lt;/body&gt;" + EOL;
String expectedAnyContent = "public class AnyContent{}" + EOL;
// classpath files
assertThat(styleWithInlineFile_min("/test.css").render(), is(expectedCss));
assertThat(scriptWithInlineFile_min("/test.js").render(), is(expectedJs));
assertThat(fileAsString("/test.html").render(), is(expectedHtml));
assertThat(fileAsEscapedString("/test.html").render(), is(expectedEscapedHtml));
assertThat(fileAsString("/AnyContent.java").render(), is(expectedAnyContent));
// files outside classpath
assertThat(styleWithInlineFile_min("src/test/files/test.css").render(), is(expectedCss));
assertThat(scriptWithInlineFile_min("src/test/files/test.js").render(), is(expectedJs));
assertThat(fileAsString("src/test/files/test.html").render(), is(expectedHtml));
assertThat(fileAsEscapedString("src/test/files/test.html").render(), is(expectedEscapedHtml));
assertThat(fileAsString("src/test/files/AnyContent.java").render(), is(expectedAnyContent));
}
@Test(expected=RuntimeException.class)
public void testExceptionForBadPath() throws Exception {
styleWithInlineFile_min("NOT A FILE");
}
}

View File

@@ -1,173 +1,251 @@
package j2html.tags;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.*;
import static j2html.TagCreator.*;
import static junit.framework.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 testIff() throws Exception {
String expected = "<div><p>Test</p><a href=\"#\">Test</a></div>";
String actual = div(
p("Test"),
iff(1 == 1, a("Test").withHref("#")),
iff(1 == 2, a("Tast").withHref("#"))
).render();
assertThat(actual, is(expected));
}
@Test
public void testIffElse() throws Exception {
String expected = "<div><p>Tast</p></div>";
String actual = div(iffElse(1 == 2, p("Test"), p("Tast"))).render();
assertThat(actual, is(expected));
}
@Test
public void testJoin() throws Exception {
String expected = "This is my joined string. It has a <a href=\"#\">link in the middle</a> and <code>code at the end</code>.";
String actual = join("This is my joined string. It has a", a("link in the middle").withHref("#"), "and", code("code at the end"), ".").render();
assertThat(actual, is(expected));
}
@Test
@Ignore // Having some trouble with RetroLambda setup
public void testEach() throws Exception {
String j2htmlMap = ul().with(
li("Begin list"),
each(employees, employee -> li(
h2(employee.name),
p(employee.title)
))
).render();
String javaMap = ul().with(
li("Begin list"),
rawHtml(employees.stream().map(employee -> li(
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
@Ignore // Having some trouble with RetroLambda setup
public void testFilter() throws Exception {
String j2htmlFilter = ul().with(
li("Begin list"),
each(filter(employees, e -> e.id % 2 == 1), employee -> li(
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(
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>").render(), "&#60;script&#62;");
assertEquals(unsafeHtml("<script>").render(), "<script>");
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>"));
//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,17 @@ 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.div;
import static j2html.TagCreator.footer;
import static j2html.TagCreator.header;
import static j2html.TagCreator.html;
import static j2html.TagCreator.iff;
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 +20,52 @@ 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));
}
@Test
public void testWithClasses() throws Exception {
String expected = "<div class=\"c1 c2\"></div>";
String actual = div().withClasses("c1", iff(1 == 1, "c2"), iff(1 == 2, "c3")).render();
assertThat(actual, is(expected));
}
@Test
public void testEmptyAttribute() throws Exception {
ContainerTag testTagWithAttrValueNull = new ContainerTag("a").attr("attribute", null);
assertThat(testTagWithAttrValueNull.render(), is("<a attribute></a>"));
ContainerTag testTagAttrWithoutAttr = new ContainerTag("a").attr("attribute");
assertThat(testTagAttrWithoutAttr.render(), is("<a attribute></a>"));
}
}

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;
}
}

View File

@@ -1,97 +0,0 @@
package performancetester;
import j2html.tags.ContainerTag;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
import java.util.function.IntConsumer;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import static j2html.TagCreator.*;
import static org.junit.Assert.assertEquals;
public class RenderSpeed {
/**
* This test class is only used during development of j2html, to see if changes to data-types and rendering
* techniques have a positive or negative impact
*/
public int iterations = 100000;
public int precision = 10;
@Test
public void testFullPageRenderSpeed() {
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));
String methodName = new Object(){}.getClass().getEnclosingMethod().getName();
measureAvgMethodTime(this::fullPageRenderTest, iterations, precision, methodName);
}
@Test
public void testAttributeRenderSpeed() {
String methodName = new Object(){}.getClass().getEnclosingMethod().getName();
measureAvgMethodTime(this::attributeRenderTest, iterations, precision, methodName);
}
public void attributeRenderTest(int i) {
tag("div " + i)
.attr("just", "adding")
.attr("some", "pretty")
.attr("random", "attributes")
.attr("to", "this")
.attr("div", "here").render();
}
public String fullPageRenderTest(int i) {
return html().with(
head().with(
title().withText("Test " + i)
),
body().with(
header().with(
h1("Test Header")
),
main().with(
h2("Test Form"),
div().with(
input().withType("email").withName("email").withPlaceholder("Email"),
input().withType("password").withName("password").withPlaceholder("Password"),
input().withType("password").withName("repeatPassword").withPlaceholder("Repeat password"),
input().withType("password").withName("repeatPasswordAgain").withPlaceholder("Repeat password again"),
button().withType("submit").withText("Login")
),
div().withText(
"<script>alert(1)</script>"
)
),
footer().withText("Test Footer"),
script().withSrc("/testScript.js")
)
).render();
}
/**
* Please tell me if there is a proper way to do this :D
*
* @param method the method to measure
* @param iterations the number of times to run the method
* @param precision the number of times to run the timer
* @param methodName the name of the method (only used for output)
*/
private void measureAvgMethodTime(IntConsumer method, int iterations, int precision, String methodName) {
double averageTime = LongStream.range(0, precision).map(l -> measureMethodTime(method, iterations)).average().getAsDouble();
System.out.println("\n" + methodName + ": " + averageTime + "ms was avg runtime per " + String.format("%,d", iterations) + " iterations (ran " + precision + " times) \n");
}
private long measureMethodTime(IntConsumer method, int iterations) {
long startTime = System.nanoTime();
IntStream.range(0, iterations).parallel().forEach(method);
long endTime = System.nanoTime();
System.out.print(TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + " ");
return TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
}
}

View File

@@ -0,0 +1 @@
public class AnyContent{}

View File

@@ -0,0 +1,7 @@
body {
background: goldenrod;
margin-top: 10px;
margin-right: 10px;
margin-bottom: 10px;
margin-left: 10px;
}

View File

@@ -0,0 +1,3 @@
<body>
Any content
</body>

View File

@@ -0,0 +1,6 @@
(function () {
var test = 5;
var tast = 10;
var testTast = test + tast;
console.log(testTast);
})();