AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="0.9.9.2" />

 HtmlForeignExtensions

static class HtmlForeignExtensions
A collection of useful helpers when working with foreign content.
using AngleSharp.Dom; using AngleSharp.Dom.Mathml; using AngleSharp.Dom.Svg; using AngleSharp.Extensions; using AngleSharp.Html; using System; using System.Collections.Generic; namespace AngleSharp.Parser.Html { internal static class HtmlForeignExtensions { private static readonly Dictionary<string, string> svgAttributeNames = new Dictionary<string, string>(StringComparer.Ordinal) { { "attributename", "attributeName" }, { "attributetype", "attributeType" }, { "basefrequency", "baseFrequency" }, { "baseprofile", "baseProfile" }, { "calcmode", "calcMode" }, { "clippathunits", "clipPathUnits" }, { "contentscripttype", "contentScriptType" }, { "contentstyletype", "contentStyleType" }, { "diffuseconstant", "diffuseConstant" }, { "edgemode", "edgeMode" }, { "externalresourcesrequired", "externalResourcesRequired" }, { "filterres", "filterRes" }, { "filterunits", "filterUnits" }, { "glyphref", "glyphRef" }, { "gradienttransform", "gradientTransform" }, { "gradientunits", "gradientUnits" }, { "kernelmatrix", "kernelMatrix" }, { "kernelunitlength", "kernelUnitLength" }, { "keypoints", "keyPoints" }, { "keysplines", "keySplines" }, { "keytimes", "keyTimes" }, { "lengthadjust", "lengthAdjust" }, { "limitingconeangle", "limitingConeAngle" }, { "markerheight", "markerHeight" }, { "markerunits", "markerUnits" }, { "markerwidth", "markerWidth" }, { "maskcontentunits", "maskContentUnits" }, { "maskunits", "maskUnits" }, { "numoctaves", "numOctaves" }, { "pathlength", "pathLength" }, { "patterncontentunits", "patternContentUnits" }, { "patterntransform", "patternTransform" }, { "patternunits", "patternUnits" }, { "pointsatx", "pointsAtX" }, { "pointsaty", "pointsAtY" }, { "pointsatz", "pointsAtZ" }, { "preservealpha", "preserveAlpha" }, { "preserveaspectratio", "preserveAspectRatio" }, { "primitiveunits", "primitiveUnits" }, { "refx", "refX" }, { "refy", "refY" }, { "repeatcount", "repeatCount" }, { "repeatdur", "repeatDur" }, { "requiredextensions", "requiredExtensions" }, { "requiredfeatures", "requiredFeatures" }, { "specularconstant", "specularConstant" }, { "specularexponent", "specularExponent" }, { "spreadmethod", "spreadMethod" }, { "startoffset", "startOffset" }, { "stddeviation", "stdDeviation" }, { "stitchtiles", "stitchTiles" }, { "surfacescale", "surfaceScale" }, { "systemlanguage", "systemLanguage" }, { "tablevalues", "tableValues" }, { "targetx", "targetX" }, { "targety", "targetY" }, { "textlength", "textLength" }, { "viewbox", "viewBox" }, { "viewtarget", "viewTarget" }, { "xchannelselector", "xChannelSelector" }, { "ychannelselector", "yChannelSelector" }, { "zoomandpan", "zoomAndPan" } }; private static readonly Dictionary<string, string> svgAdjustedTagNames = new Dictionary<string, string>(StringComparer.Ordinal) { { "altglyph", "altGlyph" }, { "altglyphdef", "altGlyphDef" }, { "altglyphitem", "altGlyphItem" }, { "animatecolor", "animateColor" }, { "animatemotion", "animateMotion" }, { "animatetransform", "animateTransform" }, { "clippath", "clipPath" }, { "feblend", "feBlend" }, { "fecolormatrix", "feColorMatrix" }, { "fecomponenttransfer", "feComponentTransfer" }, { "fecomposite", "feComposite" }, { "feconvolvematrix", "feConvolveMatrix" }, { "fediffuselighting", "feDiffuseLighting" }, { "fedisplacementmap", "feDisplacementMap" }, { "fedistantlight", "feDistantLight" }, { "feflood", "feFlood" }, { "fefunca", "feFuncA" }, { "fefuncb", "feFuncB" }, { "fefuncg", "feFuncG" }, { "fefuncr", "feFuncR" }, { "fegaussianblur", "feGaussianBlur" }, { "feimage", "feImage" }, { "femerge", "feMerge" }, { "femergenode", "feMergeNode" }, { "femorphology", "feMorphology" }, { "feoffset", "feOffset" }, { "fepointlight", "fePointLight" }, { "fespecularlighting", "feSpecularLighting" }, { "fespotlight", "feSpotLight" }, { "fetile", "feTile" }, { "feturbulence", "feTurbulence" }, { "foreignobject", "foreignObject" }, { "glyphref", "glyphRef" }, { "lineargradient", "linearGradient" }, { "radialgradient", "radialGradient" }, { "textpath", "textPath" } }; public static string SanatizeSvgTagName(this string localName) { string value = null; if (svgAdjustedTagNames.TryGetValue(localName, out value)) return value; return localName; } public static MathElement Setup(this MathElement element, HtmlTagToken tag) { int count = tag.Attributes.Count; for (int i = 0; i < count; i++) { KeyValuePair<string, string> keyValuePair = tag.Attributes[i]; string key = keyValuePair.Key; keyValuePair = tag.Attributes[i]; string value = keyValuePair.Value; element.AdjustAttribute(key.AdjustToMathAttribute(), value); } return element; } public static SvgElement Setup(this SvgElement element, HtmlTagToken tag) { int count = tag.Attributes.Count; for (int i = 0; i < count; i++) { KeyValuePair<string, string> keyValuePair = tag.Attributes[i]; string key = keyValuePair.Key; keyValuePair = tag.Attributes[i]; string value = keyValuePair.Value; element.AdjustAttribute(key.AdjustToSvgAttribute(), value); } return element; } public static void AdjustAttribute(this Element element, string name, string value) { if (IsXLinkAttribute(name)) element.SetAttribute(NamespaceNames.XLinkUri, name.Substring(name.IndexOf(':') + 1), value); else if (IsXmlAttribute(name)) { element.SetAttribute(NamespaceNames.XmlUri, name, value); } else if (IsXmlNamespaceAttribute(name)) { element.SetAttribute(NamespaceNames.XmlNsUri, name, value); } else { element.SetOwnAttribute(name, value, false); } } public static string AdjustToMathAttribute(this string attributeName) { if (attributeName.Is("definitionurl")) return "definitionURL"; return attributeName; } public static string AdjustToSvgAttribute(this string attributeName) { string value = null; if (svgAttributeNames.TryGetValue(attributeName, out value)) return value; return attributeName; } private static bool IsXmlNamespaceAttribute(string name) { if (name.Length > 4) { if (!name.Is(NamespaceNames.XmlNsPrefix)) return name.Is("xmlns:xlink"); return true; } return false; } private static bool IsXmlAttribute(string name) { if (name.Length > 7 && "xml:".EqualsSubset(name, 0, 4)) { if (!TagNames.Base.EqualsSubset(name, 4, 4) && !AttributeNames.Lang.EqualsSubset(name, 4, 4)) return AttributeNames.Space.EqualsSubset(name, 4, 5); return true; } return false; } private static bool IsXLinkAttribute(string name) { if (name.Length > 9 && "xlink:".EqualsSubset(name, 0, 6)) { if (!AttributeNames.Actuate.EqualsSubset(name, 6, 7) && !AttributeNames.Arcrole.EqualsSubset(name, 6, 7) && !AttributeNames.Href.EqualsSubset(name, 6, 4) && !AttributeNames.Role.EqualsSubset(name, 6, 4) && !AttributeNames.Show.EqualsSubset(name, 6, 4) && !AttributeNames.Type.EqualsSubset(name, 6, 4)) return AttributeNames.Title.EqualsSubset(name, 6, 5); return true; } return false; } private static bool EqualsSubset(this string a, string b, int index, int length) { return string.Compare(a, 0, b, index, length, StringComparison.Ordinal) == 0; } } }