ForeignNames.java
package org.jsoup.parser;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Attributes;
import static org.jsoup.internal.Normalizer.asciiLowerCase;
import static org.jsoup.internal.Normalizer.equalsIgnoreAsciiCase;
import static org.jsoup.parser.Parser.NamespaceMathml;
import static org.jsoup.parser.Parser.NamespaceSvg;
/** Applies the SVG and MathML name casing rules used when parsing HTML. */
final class ForeignNames {
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign
private static final String[] SvgTags = {
"altGlyph", "altGlyphDef", "altGlyphItem", "animateColor", "animateMotion",
"animateTransform", "clipPath", "feBlend", "feColorMatrix", "feComponentTransfer",
"feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight",
"feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR",
"feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology",
"feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile",
"feTurbulence", "foreignObject", "glyphRef", "linearGradient", "radialGradient", "textPath"
};
// https://html.spec.whatwg.org/multipage/parsing.html#adjust-svg-attributes
private static final String[] SvgAttributes = {
"attributeName", "attributeType", "baseFrequency", "baseProfile", "calcMode",
"clipPathUnits", "diffuseConstant", "edgeMode", "filterUnits", "glyphRef",
"gradientTransform", "gradientUnits", "kernelMatrix", "kernelUnitLength", "keyPoints",
"keySplines", "keyTimes", "lengthAdjust", "limitingConeAngle", "markerHeight",
"markerUnits", "markerWidth", "maskContentUnits", "maskUnits", "numOctaves",
"pathLength", "patternContentUnits", "patternTransform", "patternUnits", "pointsAtX",
"pointsAtY", "pointsAtZ", "preserveAlpha", "preserveAspectRatio", "primitiveUnits",
"refX", "refY", "repeatCount", "repeatDur", "requiredExtensions",
"requiredFeatures", "specularConstant", "specularExponent", "spreadMethod", "startOffset",
"stdDeviation", "stitchTiles", "surfaceScale", "systemLanguage", "tableValues",
"targetX", "targetY", "textLength", "viewBox", "viewTarget",
"xChannelSelector", "yChannelSelector", "zoomAndPan"
};
private ForeignNames() {}
/** Use the defined case if there is one, otherwise lowercase. */
static String tagName(String name, String namespace) {
if (NamespaceSvg.equals(namespace)) {
for (String svgName : SvgTags) {
if (equalsIgnoreAsciiCase(svgName, name)) return svgName;
}
}
return asciiLowerCase(name);
}
/** Use the defined case if there is one, otherwise lowercase. */
static void normalizeAttributes(Attributes attributes, String namespace) {
for (Attribute attribute : attributes) {
String orig = attribute.getKey();
String adjusted = null;
if (NamespaceSvg.equals(namespace)) {
for (String name : SvgAttributes) {
if (equalsIgnoreAsciiCase(name, orig)) {
adjusted = name;
break;
}
}
} else if (NamespaceMathml.equals(namespace) && equalsIgnoreAsciiCase(orig, "definitionURL")) {
adjusted = "definitionURL";
}
if (adjusted == null) adjusted = asciiLowerCase(orig);
if (!adjusted.equals(orig)) attribute.setKey(adjusted);
}
}
}