我正在处理旧的jsp项目,我需要为IE5-IE8实现一些flexbox并将其打包到标签lib。
这是我的代码:
layout.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>2.5</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>layout</short-name>
<description>Vertical and horisontal box layout</description>
<tag>
<name>vbox</name>
<tag-class>com.company.tag.layout.VBox</tag-class>
<body-content>JSP</body-content>
<description>
Vertical box layout
</description>
<attribute>
<name>class</name>
</attribute>
<attribute>
<name>style</name>
</attribute>
</tag>
<tag>
<name>hbox</name>
<tag-class>com.company.tag.layout.HBox</tag-class>
<body-content>JSP</body-content>
<description>
Horizontal box layout
</description>
<attribute>
<name>class</name>
</attribute>
<attribute>
<name>style</name>
</attribute>
</tag>
<tag>
<name>box</name>
<tag-class>com.company.tag.layout.Box</tag-class>
<body-content>JSP</body-content>
<description>
The box with static or dynamic width or height derived from weight attribute
</description>
<attribute>
<name>weight</name>
<required>true</required>
</attribute>
<attribute>
<name>class</name>
</attribute>
<attribute>
<name>style</name>
</attribute>
</tag>
</taglib>
AbstractBoxLayout.java
package com.company.tag.layout;
import static com.google.common.base.Preconditions.checkState;
import static java.lang.Float.parseFloat;
import static java.lang.Math.round;
import static java.lang.String.format;
import static org.apache.commons.lang3.ObjectUtils.firstNonNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.join;
import static org.apache.commons.lang3.StringUtils.trim;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.company.tag.layout.Box.BoxData;
public abstract class AbstractBoxLayout extends BodyTagSupport {
private static final long serialVersionUID = -1556868158755870941L;
protected ArrayList<BoxData> boxes = new ArrayList<>();
protected String attrClass;
protected String attrStyle;
private void resetState() {
boxes = new ArrayList<>();
attrClass = null;
attrStyle = null;
}
@Override
public int doEndTag() throws JspException {
try {
String content = bodyContent.getString();
checkState(isBlank(content), "Unexpected content in vbox: %s", trim(content));
checkState(!boxes.isEmpty(), getClass().getSimpleName().toLowerCase() + " is empty");
pageContext.getOut().write(format("<table cellspacing=\"0\" cellpadding=\"0\" %s%s>",
formatClass(attrClass),
formatStyle("table-layout: fixed; width: 100%; height: 100%; border: none", attrStyle)));
writeBoxes(calculateTotalWeight());
pageContext.getOut().write("</table>\n");
resetState();
return super.doEndTag();
} catch (IOException e) {
throw new JspException(e);
}
}
private float calculateTotalWeight() {
float totalWeight = 0;
for (BoxData box : boxes) {
totalWeight += parseFloat(box.weight);
}
return totalWeight;
}
abstract void writeBoxes(float totalWeight) throws IOException;
public void addBox(BoxData data) {
boxes.add(data);
}
protected String formatClass(String clazz) {
return clazz == null ? "" : format("class=\"%s\" ", clazz);
}
protected String formatStyle(String... styles) {
if (firstNonNull(styles) == null)
return "";
return format("style=\"%s\"", join(styles, ";"));
}
protected String deriveWeight(float totalWeight, float weight) {
return weight == 0 ? "0px" : format("%s%%", round((weight / totalWeight * 100)));
}
public void setClass(String attrClass) {
this.attrClass = attrClass;
}
public void setStyle(String attrStyle) {
this.attrStyle = attrStyle;
}
}
VBox.java
package com.company.tag.layout;
import static java.lang.Float.parseFloat;
import static java.lang.String.format;
import java.io.IOException;
import com.company.tag.layout.Box.BoxData;
public class VBox extends AbstractBoxLayout {
private static final long serialVersionUID = -1556868158755870941L;
@Override
protected void writeBoxes(float totalWeight) throws IOException {
for (BoxData box : boxes) {
float weight = parseFloat(box.weight);
pageContext.getOut().write(format("<tr %s>", formatStyle("height: " + deriveWeight(totalWeight, weight))));
pageContext.getOut().write(format("<td %s>\n", formatStyle("overflow: hidden", box.style)));
pageContext.getOut().write(box.content);
pageContext.getOut().write("\n</td>");
pageContext.getOut().write("</tr>");
}
}
}
HBox.java 包com.company.tag.layout;
import static java.lang.Float.parseFloat;
import static java.lang.String.format;
import java.io.IOException;
import com.company.tag.layout.Box.BoxData;
public class HBox extends AbstractBoxLayout {
private static final long serialVersionUID = -1556868158755870941L;
@Override
void writeBoxes(float totalWeight) throws IOException {
pageContext.getOut().write("<tr>");
for (BoxData box : boxes) {
float weight = parseFloat(box.weight);
pageContext.getOut().write(format("<td %s>\n",
formatStyle(format("width: %s; overflow: hidden", deriveWeight(totalWeight, weight)), box.style)));
pageContext.getOut().write(box.content);
pageContext.getOut().write("\n</td>");
}
pageContext.getOut().write("</tr>");
}
}
Box.java
package com.company.tag.layout;
import static com.google.common.base.Preconditions.checkState;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
public class Box extends BodyTagSupport {
public static final class BoxData {
String weight;
String clazz;
String style;
String content;
}
private static final long serialVersionUID = -6446830382322868121L;
private BoxData data = new BoxData();
@Override
public int doEndTag() throws JspException {
Tag parent = this.getParent();
checkState(parent instanceof AbstractBoxLayout, "Not enclosed with vbox or hbox");
AbstractBoxLayout abl = (AbstractBoxLayout) parent;
data.content = bodyContent.getString();
abl.addBox(data);
data = new BoxData();
return EVAL_BODY_BUFFERED;
}
@Override
public void setBodyContent(BodyContent b) {
super.setBodyContent(b);
}
public void setWeight(String attrWeight) {
data.weight = attrWeight;
}
public void setClass(String attrClass) {
data.clazz = attrClass;
}
public void setStyle(String attrStyle) {
data.style = attrStyle;
}
}
boxLayoutTest.jsp
<%@ taglib prefix="layout" uri="/WEB-INF/tld/layout.tld"%>
<!DOCTYPE html>
<html style="height: 100%;">
<body style="height: 100%; margin: 0">
<layout:vbox>
<layout:box weight="1" style="background: orange">
Eve
</layout:box>
<layout:box weight="0" style="background: red">
Jill<br><br><br><br>
</layout:box>
<layout:box weight="2" style="background: yellow;">
<div style="width: 100%; height: 100%; background: green">John</div>
</layout:box>
</layout:vbox>
<layout:hbox>
<layout:box weight="1" style="background: orange; vertical-align: bottom; text-align: center">
<span style="vertical-align: bottom;">Eve</span>
</layout:box>
<layout:box weight="0" style="width: 50px; background: red">
This is some long text written
</layout:box>
<layout:box weight="2" style="background: yellow">
<div style="width: 100%; height: 100%; background: green">John</div>
</layout:box>
</layout:hbox>
</body>
</html>
这被翻译成类似
的东西<%@ taglib prefix="layout" uri="/WEB-INF/tld/layout.tld"%>
<!DOCTYPE html>
<html style="height: 100%;">
<body style="height: 100%; margin: 0">
<table cellspacing="0" cellpadding="0" style="table-layout: fixed; width: 100%; height: 100%; border-collapse: collapse;">
<tr style="height: 30%;">
<td style="background: orange">Eve</td>
</tr>
<tr style="height: 0;">
<td style="background: red">Jill<br> <br> <br> <br> <br> <br>
</td>
</tr>
<tr style="height: 70%;">
<td style="background: yellow">
<div style="width: 100%; height: 100%; background: green">John</div>
</td>
</tr>
</table>
<table cellspacing="0" cellpadding="0" style="table-layout: fixed; width: 100%; height: 100%; border-collapse: collapse">
<tr>
<td style="width: 30%; background: orange">Eve</td>
<td style="width: 50px; background: red">This is some long text written</td>
<td style="width: 70%; background: yellow">
<div style="width: 100%; height: 100%; background: green">John</div>
</td>
</tr>
</table>
</body>
</html>
最后一击失败:不能让绿色约翰&#39;填充表数据空间。我已经读过很多关于这不是一项非常重要的任务,但也许有人会遇到一些好主意?