package core.framework.impl.template.node; import core.framework.api.util.Exceptions; import core.framework.impl.template.TemplateMetaContext; import core.framework.impl.template.fragment.BooleanAttributeFragment; import core.framework.impl.template.fragment.ContainerFragment; import core.framework.impl.template.fragment.HTMLContentFragment; import core.framework.impl.template.fragment.TextContentFragment; import core.framework.impl.template.fragment.URLFragment; import core.framework.impl.template.parser.HTMLParser; import core.framework.impl.template.source.TemplateSource; /** * @author neo */ public class Attribute { public final String name; public final String tagName; public final String location; public String value; public boolean hasDoubleQuote; public Attribute(String name, String tagName, String location) { this.name = name; this.tagName = tagName; this.location = location; } boolean isDynamic() { return name.startsWith("c:"); } boolean isMessage() { return name.startsWith("m:"); } void addStaticContent(ContainerFragment parent) { parent.addStaticContent(" "); parent.addStaticContent(name); if (value != null) { parent.addStaticContent("="); if (hasDoubleQuote) parent.addStaticContent("\""); parent.addStaticContent(value); if (hasDoubleQuote) parent.addStaticContent("\""); } } boolean isDynamicBooleanAttribute() { return "c:checked".equals(name) || "c:selected".equals(name) || "c:disabled".equals(name) || "c:readonly".equals(name) || "c:multiple".equals(name) || "c:ismap".equals(name) || "c:defer".equals(name); } void addBooleanAttribute(ContainerFragment parent, TemplateMetaContext context) { parent.add(new BooleanAttributeFragment(name.substring(2), value, context, location)); } boolean isCDNAttribute() { if ("link".equals(tagName) && ("c:href".equals(name) || "href".equals(name))) return true; if ("script".equals(tagName) && ("c:src".equals(name) || "src".equals(name))) return true; if ("img".equals(tagName) && ("c:src".equals(name) || "src".equals(name))) return true; return false; } void addCDNAttribute(ContainerFragment parent, TemplateMetaContext context) { String attributeName = isDynamic() ? name.substring(2) : name; if (isDynamic()) { parent.addStaticContent(" "); parent.addStaticContent(attributeName); parent.addStaticContent("="); parent.add(new URLFragment(value, context, true, location)); } else { if (context.cdn != null) { // expand cdn during compiling parent.addStaticContent(" "); parent.addStaticContent(attributeName); parent.addStaticContent("="); parent.addStaticContent(context.cdn.url(value)); } else { addStaticContent(parent); } } } void addValueAttribute(ContainerFragment parent, TemplateMetaContext context) { parent.addStaticContent(" "); parent.addStaticContent(name.substring(name.lastIndexOf(':') + 1)); if ("c:href".equals(name)) { parent.addStaticContent("="); parent.add(new URLFragment(value, context, false, location)); } else if (name.startsWith("c:html:")) { parent.addStaticContent("=\""); parent.add(new HTMLContentFragment(value, context, location)); parent.addStaticContent("\""); } else { parent.addStaticContent("=\""); parent.add(new TextContentFragment(value, context, location)); parent.addStaticContent("\""); } } void addMessageAttribute(ContainerFragment parent, TemplateMetaContext context) { String message = context.message.message(value).orElseThrow(() -> Exceptions.error("can not find message, key={}, location={}", value, location)); parent.addStaticContent(" "); parent.addStaticContent(name.substring(2)); parent.addStaticContent("=\""); parent.addStaticContent(message); parent.addStaticContent("\""); } void addDynamicContent(ContainerFragment parent, TemplateMetaContext context, TemplateSource source) { switch (name) { case "c:text": parent.add(new TextContentFragment(value, context, location)); break; case "c:html": parent.add(new HTMLContentFragment(value, context, location)); break; case "m:text": String message = context.message.message(value).orElseThrow(() -> Exceptions.error("can not find message, key={}, location={}", value, location)); parent.addStaticContent(message); break; case "c:include": TemplateSource includedSource = source.resolve(value); Document document = new HTMLParser(includedSource).parse(); document.buildTemplate(parent, context, includedSource); break; default: throw Exceptions.error("not supported dynamic content attribute, name={}", name); } } }