de.tsl2.nano.h5.HtmlUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tsl2.nano.h5 Show documentation
Show all versions of tsl2.nano.h5 Show documentation
TSL2 Framework Html5 Extensions (WebServer, Html5Presentation, RuleCover, BeanConfigurator, LogicTable-Sheet, Expression-Descriptors for Actions, Rules, URLs, Queries)
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Thomas Schneider, Thomas Schneider
* created on: Sep 29, 2012
*
* Copyright: (c) Thomas Schneider 2012, all rights reserved
*/
package de.tsl2.nano.h5;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.core.util.CollectionUtil;
import de.tsl2.nano.core.util.FileUtil;
import de.tsl2.nano.core.util.NetUtil;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.h5.plugin.INanoPlugin;
import de.tsl2.nano.plugin.Plugins;
/**
* defines html tag- and attribute-names und helper methods. android doesn't support the full w3c implementation like
* HtmlElement etc.
*
* @author Thomas Schneider, Thomas Schneider
* @version $Revision$
*/
public class HtmlUtil {
private static final Log LOG = LogFactory.getLog(HtmlUtil.class);
public static final String HTML_FORWARD = "";
public static final String TAG_HTML = "html";
public static final String TAG_HEAD = "head";
public static final String TAG_BODY = "body";
public static final String TAG_H1 = "h1";
public static final String TAG_H2 = "h2";
public static final String TAG_H3 = "h3";
public static final String TAG_H4 = "h4";
public static final String TAG_H5 = "h5";
public static final String TAG_H6 = "h6";
public static final String TAG_FORM = "form";
public static final String ATTR_ACTION = "action";
public static final String ATTR_METHOD = "method";
public static final String TAG_DIV = "div";
public static final String TAG_STYLE = "style";
public static final String TAG_INPUT = "input";
public static final String ATTR_TYPE = "type";
public static final String ATTR_ID = "id";
public static final String ATTR_CLASS = "class";
public static final String ATTR_NAME = "name";
public static final String ATTR_VALUE = "value";
public static final String ATTR_PATTERN = "pattern";
public static final String ATTR_DISABLED = "disabled";
public static final String ATTR_READONLY = "readonly";
public static final String ATTR_HIDDEN = "hidden";
public static final String ATTR_ACCESSKEY = "accesskey";
public static final String ATTR_STYLE = "style";
public static final String ATTR_TITLE = "title";
public static final String ATTR_REQUIRED = "required";
public static final String ATTR_LIST = "list";
public static final String ATTR_MAXLENGTH = "maxlength";
public static final String ATTR_CHECKED = "checked";
public static final String ATTR_MIN = "min";
public static final String ATTR_MAX = "max";
public static final String ATTR_TEXT_ALIGN = "text-align";
public static final String ATTR_FORMNOVALIDATE = "formnovalidate";
public static final String ATTR_FORMTARGET = "formtarget";
public static final String ATTR_AUTOFOCUS = "autofocus";
public static final String ATTR_TYPE_INPUT = "input";
public static final String ATTR_TYPE_TEXT = "text";
public static final String ATTR_TYPE_DATE = "date";
public static final String ATTR_TYPE_TIME = "time";
public static final String ATTR_TYPE_CHECKBOX = "checkbox";
public static final String ATTR_TYPE_RADIO = "radio";
public static final String ATTR_TYPE_NUMBER = "number";
public static final String ATTR_TYPE_TEL = "tel";
public static final String ATTR_TYPE_EMAIL = "email";
public static final String ATTR_TYPE_URL = "url";
public static final String ATTR_TYPE_PASSWORD = "password";
public static final String ATTR_TYPE_SEARCH = "search";
public static final String TAG_TEXTAREA = "textarea";
public static final String ATTR_ROWS = "rows";
public static final String ATTR_COLS = "cols";
public static final String ATTR_WRAP = "wrap";
public static final String TAG_SELECT = "select";
public static final String TAG_DATALIST = "datalist";
public static final String TAG_OPTGROUP = "optgroup";
public static final String TAG_OPTION = "option";
public static final String ATTR_SIZE = "size";
public static final String ATTR_SELECTED = "selected";
public static final String ATTR_MULTIPLE = "multiple";
public static final String TAG_LINK = "a";
public static final String ATTR_HREF = "href";
public static final String TAG_IMAGE = "img";
public static final String ATTR_SRC = "src";
public static final String ATTR_ALT = "alt";
public static final String ATTR_DATA = "data";
public static final String ATTR_SRCDOC = "srcdoc"; //--> iframe
public static final String TAG_AUDIO = "audio";
public static final String TAG_VIDEO = "video";
public static final String TAG_EMBED = "embed";
public static final String TAG_OBJECT = "object";
public static final String TAG_CANVAS = "canvas";
public static final String TAG_DEVICE = "device";
public static final String TAG_FRAME = "iframe";
public static final String TAG_SVG = "svg";
public static final String TAG_BUTTON = "button";
public static final String TAG_SCRIPT = "script";
public static final String ATTR_TYPE_JS = "text/javascript";
/*
* Layout
*/
public static final String TAG_BREAK = "br";
public static final String TAG_PARAGRAPH = "p";
public static final String ATTR_ALIGN = "align";
public static final String ALIGN_CENTER = "center";
public static final String ALIGN_RIGHT = "end";
public static final String ALIGN_LEFT = "left";
public static final String TAG_PRE = "pre";
public static final String TAG_EXP_DETAILS = "details";
public static final String TAG_EXP_SUMMARY = "summary";
public static final String ATTR_EXP_OPEN = "open";
public static final String TAG_SPAN = "span";
//the font tag is not supported in html5
// public static final String TAG_FONT = "font";
static final String ATTR_COLOR = "color";
public static final String TAG_TABLE = "table";
public static final String TAG_CAPTION = "caption";
public static final String TAG_THEAD = "thead";
public static final String TAG_TBODY = "tbody";
public static final String TAG_COLGROUP = "colgroup";
public static final String TAG_COL = "col";
public static final String TAG_ROW = "tr";
public static final String TAG_HEADERCELL = "th";
public static final String TAG_CELL = "td";
public static final String ATTR_FRAME = "frame";
public static final String ATTR_BORDER = "border";
public static final String ATTR_WIDTH = "width";
public static final String ATTR_HEIGHT = "height";
public static final String ATTR_BGCOLOR = "bgcolor";
public static final String ATTR_SPAN = "span";
public static final String ATTR_SPANCOL = "colspan";
public static final String ATTR_SPANROW = "rowspan";
public static final String ATTR_HEADERS = "header";
public static final String ATTR_TABINDEX = "tabindex";
public static final String COLOR_WHITE = "#FFFFFF";
public static final String COLOR_BLACK = "#000000";
public static final String COLOR_RED = "#FF0000";
public static final String COLOR_GREEN = "#00FF00";
public static final String COLOR_BLUE = "#0000FF";
public static final String COLOR_GRAY = "#999999";
public static final String COLOR_LIGHT_RED = "#FFCCCC";
public static final String COLOR_LIGHT_GREEN = "#CCFFCC";
public static final String COLOR_LIGHT_BLUE = "#CCCCFF";
public static final String COLOR_LIGHTER_BLUE = "#DDDDFF";
public static final String COLOR_LIGHT_GRAY = "#CCCCCC";
public static final String COLOR_YELLOW = "#CCCC00";
/** static styles */
public static final String STYLE_BACKGROUND_COLOR = "background-color";
public static final String STYLE_BACKGROUND_TRANSPARENT = "background: transparent;";
public static final String STYLE_BACKGROUND_RADIAL_GRADIENT =
"background: var(--bg-color);";
public static final String STYLE_BACKGROUND_FADING_TRANSITION =
"-webkit-transition: background 2.5s ease-in-out; -moz-transition: background 2.5s ease-in-out; -ms-transition: background 2.5s ease-in-out; -o-transition: background 2.5s ease-in-out; transition: background 2.5s ease-in-out;";
public static final String STYLE_BACKGROUND_FADING_KEYFRAMES =
"-webkit-animation: fade 2s; -webkit-animation-fill-mode: both; -moz-animation: fade 2s; -moz-animation-fill-mode: both; -o-animation: fade 2s; -o-animation-fill-mode: both; animation: fade 2s; animation-fill-mode: both;";
public static final String CSS_BACKGROUND_FADING_KEYFRAMES =
"@-webkit-keyframes fade {0%{opacity: 0;} 100% {opacity: 1;}} @-moz-keyframes fade {0%{opacity: 0;} 100% {opacity: 1;}} @-o-keyframes fade {0%{opacity: 0;} 100% {opacity: 1;}} @keyframes fade {0%{opacity: 0;} 100% {opacity: 1;}}; ";
public static final String STYLE_BACKGROUND_LIGHTGRAY = "background-color: rgba(247,247,247,.5);";
/** dynamic styles. use method {@link #style(String, String)} to set styles! */
public static final String STYLE_TEXT_ALIGN = "text-align";
public static final String STYLE_FONT_COLOR = "color";
public static final String STYLE_COLOR = "color";
public static final String VAL_25PERCENT = "25%";
public static final String VAL_100PERCENT = "100%";
public static final String VAL_FALSE = Boolean.FALSE.toString();
public static final String VAL_TRUE = Boolean.TRUE.toString();
public static final String VAL_ALIGN_LEFT = "start";
public static final String VAL_ALIGN_CENTER = "middle";
public static final String VAL_ALIGN_RIGHT = "end";
public static final String BTN_ASSIGN = "tsl2nano.assign";
public static final String BTN_SUBMIT = "tsl2nano.save";
public static final String BTN_CANCEL = "tsl2nano.cancel";
public static final String BTN_SIDENAVCLOSE = "button.sidenav.close";
public static final String BTN_SELECT_ALL = "tsl2nano.selectall";
public static final String BTN_DESELECT_ALL = "tsl2nano.deselectall";
public static final String BTN_PRINT = "tsl2nano.print";
public static final String BTN_EXPORT = "tsl2nano.export";
//frame-ids to create a perspective
public static final String VAL_FRM_SELF = "_self";
public static final String VAL_FRM_BODY_TOP = "_top";
public static final String VAL_FRM_NEWTAB = "_blank";
public static final String VAL_FRM_PARENT = "_parent";
//unused yet!
public static final String VAL_FRM_CENTER = "FRAME_CENTER";
public static final String VAL_FRM_LEFT = "FRAME_LEFT";
public static final String VAL_FRM_RIGHT = "FRAME_RIGHT";
public static final String VAL_FRM_TOP = "FRAME_TOP";
public static final String VAL_FRM_BOTTOM = "FRAME_BOTTOM";
public static final String VAL_OPAC = "opacity:1.0;";
public static final String VAL_OPACITY_0_5 = "opacity:0.5;";
public static final String VAL_OPACITY_0_6 = "opacity:0.6;";
public static final String VAL_OPACITY_0_7 = "opacity:0.7;";
public static final String VAL_OPACITY_0_8 = "opacity:0.8;";
public static final String VAL_OPACITY_0_9 = "opacity:0.9;";
public static final String VAL_TRANSPARENT_INHERIT = "opacity:0.0;";
public static final String VAL_TRANSPARENT = "background-color: transparent;";
public static final String VAL_ROUNDCORNER =
"padding:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;";
public static final String XML_TAG_START = "\\<.*\\>";
public static final String END_TAG = "/";
public static final String PRE_ATTRIBUTE_FLAG = "FLAG:";
public static final String CHAR_SUM = L("sum");
public static final String CHAR_LE = L("le");
public static final String CHAR_GE = L("ge");
public static final String CHAR_DELTA = L("Delta");
public static final String CHAR_DEG = L("deg");
public static final String CHAR_ARROW_DOWN = L("dArr");
public static final String CHAR_ARROW_UP = L("uArr");
public static final String CHAR_ARROW_RIGHT = L("rArr");
public static final String CHAR_ARROW_LEFT = L("lArr");
public static final String CHAR_COPYRIGHT = L("copy");
public static final String CHAR_POINT = L("bull");
protected static final StringBuilder EMPTY_CONTENT = new StringBuilder();
private static final char CSS_ID_SEPARATOR = '$';
static String tableDivStyle;
public static Element appendElements(Element parent, String... tagNames) {
Document doc = parent.getOwnerDocument();
for (int i = 0; i < tagNames.length; i++) {
parent.appendChild(doc.createElement(tagNames[i]));
}
return parent;
}
public static Element embedElements(Element parent, String... tagNames) {
Document doc = parent.getOwnerDocument();
Element p = parent;
for (int i = 0; i < tagNames.length; i++) {
p = (Element) p.appendChild(doc.createElement(tagNames[i]));
}
return p;
}
/**
* convenience delegating to {@link #appendElement(Element, String, String...)}, using tagAndContentAndattributes[0]
* as tag name, tagAndContentAndattributes[1] as content.
*
* @param parent parent element to put the new element into
* @param tagAndContentAndattributes tag (index=0), content (index=1) and attributes with their values
* @return new element
*/
static Element appendTag(Element parent, String... tagAndContentAndattributes) {
return appendElement(parent, tagAndContentAndattributes[0], content(tagAndContentAndattributes[1]),
CollectionUtil.copyOfRange(tagAndContentAndattributes, 2, tagAndContentAndattributes.length));
}
public static Element appendElement(Element parent, String tagName, String... attributes) {
return appendElement(parent, tagName, null, attributes);
}
public static Element appendElement(Element parent, String tagName, StringBuilder content, String... attributes) {
Document doc = parent.getOwnerDocument();
Element e = doc.createElement(tagName);
if (content != null) {
String c = content.toString();
if (isXml(c)) {
appendNodesFromText(e, c);
} else if (c.matches("\\&.+[;]")) {
e.setNodeValue(c);
} else {
e.setTextContent(c);
}
}
appendAttributes(e, attributes);
parent.appendChild(e);
return e;
}
/**
* appendNodesFromText
*
* @param e element to add new nodes
* @param text to be parsed into nodes to be appended to the given element
*/
public static void appendNodesFromText(Element e, String text) {
try {
NodeList childNodes = createNodesFromText(text).getChildNodes();
/*
* fill the parsed nodes into our document
*/
Document doc = e.getOwnerDocument();
for (int i = 0; i < childNodes.getLength(); i++) {
e.appendChild(doc.adoptNode(childNodes.item(i)));
}
} catch (Exception e1) {
//don't interrupt the html response but show the error message.
e.setTextContent(e1.getLocalizedMessage());
}
}
public static Document createNodesFromText(String text) {
text = createHtmlFromText(text);
return createDocument(text);
}
public static String createHtmlFromText(String text) {
LOG.info("trying to parse text into html:" + text);
/*
* 1. if the text contains literals outside of its tags, they have to
* be wrapped into symbolic tags.
* 2. if there are more than one tag, create a root tag
*/
int xmlPrefixEnd = text.indexOf("?>");
if (xmlPrefixEnd != -1) {
text = text.substring(xmlPrefixEnd + 3);
}
final String BEG = begin(TAG_SPAN), END = end(TAG_SPAN);
String prefix = StringUtil.substring(text, null, "<");
if (!Util.isEmpty(prefix)) {
text = text.replace(prefix, BEG + prefix + END);
}
String postfix = StringUtil.substring(text, ">", null, true);
if (!Util.isEmpty(postfix)) {
text = text.replace(postfix, BEG + postfix + END);
}
text = BEG + text + END;
return text;
}
public static Document createDocument(String text) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
if (Util.isEmpty(text)) {
return builder.newDocument();
}
InputSource is = new InputSource(new StringReader(text));
return builder.parse(is);
} catch (Exception ex) {
ManagedException.forward(ex);
return null;
}
}
/**
* appends all given not-null attributes to the element.
* the order of attributes has to follow key1, value1, key2, value2, ...
*
* @param e element to add the attributes
* @param attributes key/value pairs
* @return the given element
*/
public static Element appendAttributes(Element e, Object... attributes) {
Document doc = e.getOwnerDocument();
for (int i = 0; i < attributes.length; i++) {
//disabled flag attribute --> continue
if (Util.isEmpty(attributes[i])) {
continue;
}
String attrName = (String) attributes[i];
Attr attr = null;
if (attrName.startsWith(PRE_ATTRIBUTE_FLAG)) {
attrName = StringUtil.substring(attrName, PRE_ATTRIBUTE_FLAG, null);
attr = doc.createAttribute(attrName);
} else if (i < attributes.length - 1 && !Util.isEmpty(attributes[i + 1])) {
if (ATTR_ID.equals(attrName))
attrName = cssID(attrName);
attr = doc.createAttribute(attrName);
attr.setValue(Util.asString(attributes[++i]));
} else {
//if it is a flag and it's the last attribute
attr = doc.createAttribute(attrName);
}
e.setAttributeNode(attr);
}
return e;
}
public static Element appendLink(Element parent, String name, String href) {
return appendElement(parent, TAG_LINK, new StringBuilder(name), ATTR_HREF, href);
}
public static Element appendStyle(Element parent, String... styles) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < styles.length; i++) {
if (styles[i] == null)
continue;
else if (styles[i].contains(":"))
b.append(styles[i]);
else if (i < styles.length - 1 && styles[i + 1] != null) {
b.append(style(styles[i], styles[++i]));
}
}
return b.length() > 0 ? appendAttributes(parent, TAG_STYLE, b) : parent;
}
/**
* usable to add an element attribute of type boolean. e.g.: formnovalidate='formnovalidate' or 'false'.
*
* @param name boolean attribute name
* @param enable whether to activate the attribute
* @return attribute name and value
*/
public static final String enable(String name, boolean enable) {
return /*"name = " +*/(enable ? name : null);
}
public static final String enableFlag(String name, boolean enable) {
return /*"name = " +*/(enable ? PRE_ATTRIBUTE_FLAG + name : null);
}
public static final String enableName(String name, boolean enable) {
return name + " = " + enable(name, enable);
}
public static final String enableBoolean(String name, boolean enable) {
boolean enabled = enable(name, enable) != null;
return name + " = " + enabled;
}
/**
* exactly one one-value style can be appended as last style element.
*
* @param styles
* @return
*/
public static final String styles(String... styles) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < styles.length; i += 2) {
b.append(i + 1 < styles.length ? style(styles[i], styles[i + 1]) : styles[i]);
}
return b.toString();
}
public static final String style(String styleKey, Object styleValue) {
return styleKey + ": " + styleValue + "; ";
}
public static String toString(Document doc) {
return toString(doc, false);
}
/**
* creates an utf-8 string with indentation.
*
* @param doc document to transform to a string
* @return string
*/
public static String toString(Document doc, boolean omitXmlAndDoctype) {
//set up a transformer
try {
Transformer trans = TransformerFactory.newInstance().newTransformer();
if (omitXmlAndDoctype) {
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
} else {
trans.setOutputProperty(OutputKeys.INDENT, ENV.get("html.dom.indent", "yes"));
// trans.setOutputProperty(OutputKeys.METHOD, "xml");
trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
trans.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "html");
trans.setOutputProperty(OutputKeys.VERSION, "text"); //-> to be ignored
}
//create string from xml tree
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
//on android systems we have problems on null-nodes
if (doc.getDocumentElement() != null)
deleteNullNode(doc.getDocumentElement());
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
String html = sw.toString();
String regexRepl = ENV.get("html.regex.replacement.sed", "");
if (Util.isEmpty(regexRepl)) {
return Plugins.process(INanoPlugin.class).manipulateHtmlResponse(sw.toString());
} else {
String regex = StringUtil.substring(regexRepl, "/", "/");
String repl = StringUtil.substring(regexRepl, regex + "/", "/");
LOG.info("doing regex replacement: regex=" + regex + ", replacement=" + repl);
return Plugins.process(INanoPlugin.class).manipulateHtmlResponse(html.replaceAll(regex, repl));
}
} catch (TransformerException e) {
ManagedException.forward(e);
return null;
}
}
/**
* workaround for android-problem on empty nodes. deleteNullNode
*
* @param root
*/
public static void deleteNullNode(Node root) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i).getNodeType() == Node.TEXT_NODE && nl.item(i).getNodeValue() == null) {
nl.item(i).getParentNode().removeChild(nl.item(i));
} else {
deleteNullNode(nl.item(i));
}
}
}
public static final boolean isURI(String str) {
return NetUtil.isURI(str);
}
/**
* containsXml
*
* @param text text to search
* @return true, if text contains at least one xml tag
*/
public static boolean containsXml(String text) {
return text.matches(".*" + XML_TAG_START + ".*");
}
public static boolean containsHtml(String text) {
return text.contains(""
+ title + "" + createMessage(msg) + "";
}
public static String createMessage(String msg) {
return "" + msg + "
";
}
public static boolean isXml(String txt) {
return StringUtil.isXml(txt);
}
public static String cdata(String data) {
return "";
}
public static String begin(String tagName) {
return "<" + tagName + ">";
}
public static String end(String tagName) {
return "" + tagName + ">";
}
public static String percent(int value) {
return value + "%";
}
public static String L(String content) {
return "&" + content + ";";
}
protected static final StringBuilder content() {
return EMPTY_CONTENT;
}
public static final StringBuilder content(String str) {
return str != null ? new StringBuilder(str) : EMPTY_CONTENT;
}
protected static String convert(String name, Object value, String defaultValue) {
if (value == null) {
return defaultValue;
} else if (name.equals(ATTR_COLOR) || name.equals(ATTR_BGCOLOR) || name.equals(STYLE_BACKGROUND_COLOR)) {
int[] c = (int[]) value;
StringBuilder s = new StringBuilder(6);
for (int i = 0; i < c.length; i++) {
s.append(StringUtil.toHexString(c.toString().getBytes()));
}
return s.toString();
} else {
return value.toString();
}
}
/**
* delegates to {@link #TABLE(String, StringBuilder, String...)} with null content
*/
public static final String[] TABLE(String tableTag, String... attrs) {
return TABLE(tableTag, null, attrs);
}
/**
* decides whether to use the old table tags or its div equivalent. tries to use given attributes as styles. a style
* attribute can only be provided at the end!
*
* @param tableTag
* @param content the tags content as stringbuilder to avoid call parameter problems
* @param styles additional style attributes
* @return div class = tag + attrs
*/
public static final String[] TABLE(String tableTag, StringBuilder content, String... attrs) {
String cont = content != null ? content.toString() : null;
if (ENV.get("layout.grid.oldtabletags", true)) {
return CollectionUtil.concat(new String[] { tableTag, cont }, attrs);
} else {
if (attrs.length > 1 && ATTR_STYLE.equals(attrs[attrs.length - 2]))
attrs[attrs.length - 2] = "nostyle";
String styles = styles(attrs);
return CollectionUtil.concat(new String[] { "div", cont },
Util.isEmpty(styles) ? new String[] {} : new String[] { "style", styles },
new String[] { "class", tableTag });
}
}
public static String tableDivStyles() {
if (tableDivStyle == null) {
InputStream stream = ENV.getResource("style.template");
tableDivStyle = StringUtil.removeFormatChars(String.valueOf(FileUtil.getFileData(stream, "UTF-8")));
ENV.get("layout.tablewrap.width", "800");
tableDivStyle = StringUtil.insertProperties(tableDivStyle, ENV.getProperties());
}
return tableDivStyle;
}
public static Element createSidebarNavMenuButton(Element parent, Element sidenav) {
// see style.template and websocket.client.js.template
// ×
//return "☰ open"; //☰=\u2630, ≡ ≡
//✖ = ✖ or ×
//✘ 10008 2718
appendElement(parent, TAG_SPAN, content("☰"), ATTR_CLASS, "openbtn", "onclick", "openNav()", ATTR_ACCESSKEY, "!");
if (sidenav == null) {
sidenav = appendElement(parent, TAG_DIV, ATTR_ID, "tslSidenav", ATTR_CLASS, "sidenav");
} else { // the last parent is the most important one
sidenav.getParentNode().removeChild(sidenav);
parent.appendChild(sidenav);
}
appendElement(sidenav, TAG_LINK, content("✘"), ATTR_HREF, "javascript:void(0)", ATTR_ID, "button.sidenav.close", ATTR_CLASS, "closebtn", "onclick", "closeNav()", ATTR_ACCESSKEY, "<");
return sidenav;
}
public static String cssID(String id) {
return id.matches("[.]\\w+.*") ? id.replace('.', CSS_ID_SEPARATOR) : id;
}
public static String beanID(String id) {
return id != null && id.matches("[$]\\w+.*") ? id.replace(CSS_ID_SEPARATOR, '.') : id;
}
/**
* As {@link Document#getElementById(String)} returns only ids, where the Attribute-Type is an ID (not the name 'id), we use an XPath vor that.
* @param rootElement
* @param id
* @return
*/
public static Element getElementById(Element rootElement, String id) {
try {
String path = String.format("//*[@id = '%1$s' or @Id = '%1$s' or @ID = '%1$s' or @iD = '%1$s' ]", id);
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList)xPath.evaluate(path, rootElement, XPathConstants.NODESET);
return (Element) nodes.item(0);
}
catch (Exception e) {
return null;
}
}
public static final void reset() {
tableDivStyle = null;
}
}