From d5d04869a87ef12e2082bc4c7ddc8e0e05a5a6a1 Mon Sep 17 00:00:00 2001 From: "J. King" Date: Fri, 28 Apr 2023 18:41:51 -0400 Subject: [PATCH] Resume sanitizing attributes --- RoboFile.php | 2 +- lib/AbstractSanitizer.php | 235 +++++++++++++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 2 deletions(-) diff --git a/RoboFile.php b/RoboFile.php index 07f45b2..6a0481f 100644 --- a/RoboFile.php +++ b/RoboFile.php @@ -493,7 +493,7 @@ class RoboFile extends \Robo\Tasks { ], ]; // retrieve the single-page HTML specification (this is around 12MB in size) - $spec = file_get_contents("html.html"); //$spec = file_get_contents("https://html.spec.whatwg.org/"); + $spec = file_get_contents("https://html.spec.whatwg.org/"); // parse it (this may take several seconds if ($spec) { // define a list of attribute-element maps which the specification omits for some reason diff --git a/lib/AbstractSanitizer.php b/lib/AbstractSanitizer.php index b11c734..935f561 100644 --- a/lib/AbstractSanitizer.php +++ b/lib/AbstractSanitizer.php @@ -27,6 +27,10 @@ abstract class AbstractSanitizer { protected const ACTION_DROP = 1; /** @var int The sanitizer action to block a node, which removes it while (possibly) keeping its children; this only applies to element nodes */ protected const ACTION_BLOCK = 2; + /** @var int The "unknown" kind for elements and attributes */ + protected const KIND_UNKNOWN = 0; + /** @var int The "regular" kind for elements and attributes */ + protected const KIND_REGULAR = 1; /** @var string The HTML namespace */ protected const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; /** @var string The MathML namespace */ @@ -45,6 +49,222 @@ abstract class AbstractSanitizer { protected const KNOWN_ELEMENTS = [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "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", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"], self::HTML_NAMESPACE => ["a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "keygen", "label", "legend", "li", "link", "listing", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "multicol", "nav", "nextid", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "search", "section", "select", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp"]]; /** @var array The set of known attributes, used to determine what the `allowUnknownMarkup` setting applies to */ protected const KNOWN_ATTRIBUTES = [self::NULL_NAMESPACE => ['abbr' => [self::HTML_NAMESPACE => ["td", "th"]], 'accept' => [self::HTML_NAMESPACE => ["form", "input"]], 'accept-charset' => [self::HTML_NAMESPACE => ["form"]], 'accesskey' => [self::HTML_NAMESPACE => ["*"]], 'accumulate' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'action' => [self::HTML_NAMESPACE => ["button", "form"]], 'additive' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'align' => [self::HTML_NAMESPACE => ["caption", "col", "div", "embed", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "iframe", "img", "input", "legend", "object", "p", "table", "tbody", "td", "th", "tr"]], 'alignment-baseline' => [self::SVG_NAMESPACE => ["*"]], 'alink' => [self::HTML_NAMESPACE => ["body"]], 'allow' => [self::HTML_NAMESPACE => ["iframe"]], 'allowfullscreen' => [self::HTML_NAMESPACE => ["iframe"]], 'allowtransparency' => [self::HTML_NAMESPACE => ["iframe"]], 'alt' => [self::HTML_NAMESPACE => ["area", "img", "input"]], 'amplitude' => [self::SVG_NAMESPACE => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'archive' => [self::HTML_NAMESPACE => ["object"]], 'aria-activedescendant' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-atomic' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-autocomplete' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-busy' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-checked' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-colcount' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-colindex' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-colspan' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-controls' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-current' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-describedby' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-details' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-disabled' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-dropeffect' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-errormessage' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-expanded' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-flowto' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-grabbed' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-haspopup' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-hidden' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-invalid' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-keyshortcuts' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-label' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-labelledby' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-level' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-live' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-modal' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-multiline' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-multiselectable' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-orientation' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-owns' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-placeholder' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-posinset' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-pressed' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-readonly' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-relevant' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-required' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-roledescription' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-rowcount' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-rowindex' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-rowspan' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-selected' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-setsize' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-sort' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuemax' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuemin' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuenow' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'aria-valuetext' => [self::HTML_NAMESPACE => ["*"], self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"]], 'as' => [self::HTML_NAMESPACE => ["link"]], 'async' => [self::HTML_NAMESPACE => ["script"]], 'attributeName' => [self::SVG_NAMESPACE => ["animate", "animateTransform", "set"]], 'autocapitalize' => [self::HTML_NAMESPACE => ["*"]], 'autocomplete' => [self::HTML_NAMESPACE => ["button", "fieldset", "form", "input", "object", "output", "select", "textarea"]], 'autofocus' => [self::HTML_NAMESPACE => ["*"]], 'autoplay' => [self::HTML_NAMESPACE => ["audio", "video"]], 'axis' => [self::HTML_NAMESPACE => ["td", "th"]], 'azimuth' => [self::SVG_NAMESPACE => ["feDistantLight"]], 'background' => [self::HTML_NAMESPACE => ["body", "table", "tbody", "td", "tfoot", "th", "thead", "tr"]], 'baseFrequency' => [self::SVG_NAMESPACE => ["feTurbulence"]], 'baseline-shift' => [self::SVG_NAMESPACE => ["*"]], 'begin' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "discard", "set"]], 'behavior' => [self::HTML_NAMESPACE => ["marquee"]], 'bgcolor' => [self::HTML_NAMESPACE => ["body", "table", "td", "th", "tr"]], 'bias' => [self::SVG_NAMESPACE => ["feConvolveMatrix"]], 'blocking' => [self::HTML_NAMESPACE => ["link", "script", "style"]], 'border' => [self::HTML_NAMESPACE => ["img", "input", "object", "table"]], 'bordercolor' => [self::HTML_NAMESPACE => ["table"]], 'bottommargin' => [self::HTML_NAMESPACE => ["body"]], 'by' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'calcMode' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'cellpadding' => [self::HTML_NAMESPACE => ["table"]], 'cellspacing' => [self::HTML_NAMESPACE => ["table"]], 'char' => [self::HTML_NAMESPACE => ["col", "tbody", "td", "th", "tr"]], 'charoff' => [self::HTML_NAMESPACE => ["col", "tbody", "td", "th", "tr"]], 'charset' => [self::HTML_NAMESPACE => ["a", "link", "meta", "script"]], 'checked' => [self::HTML_NAMESPACE => ["input"]], 'cite' => [self::HTML_NAMESPACE => ["blockquote", "del", "ins", "q"]], 'class' => [self::HTML_NAMESPACE => ["*"]], 'classid' => [self::HTML_NAMESPACE => ["object"]], 'clear' => [self::HTML_NAMESPACE => ["br"]], 'clip-path' => [self::SVG_NAMESPACE => ["*"]], 'clip-rule' => [self::SVG_NAMESPACE => ["*"]], 'clipPathUnits' => [self::SVG_NAMESPACE => ["clipPath"]], 'code' => [self::HTML_NAMESPACE => ["object"]], 'codebase' => [self::HTML_NAMESPACE => ["object"]], 'codetype' => [self::HTML_NAMESPACE => ["object"]], 'color' => [self::SVG_NAMESPACE => ["*"], self::HTML_NAMESPACE => ["hr", "link"]], 'color-interpolation' => [self::SVG_NAMESPACE => ["*"]], 'color-interpolation-filters' => [self::SVG_NAMESPACE => ["*"]], 'color-rendering' => [self::SVG_NAMESPACE => ["*"]], 'cols' => [self::HTML_NAMESPACE => ["textarea"]], 'colspan' => [self::HTML_NAMESPACE => ["td", "th"]], 'compact' => [self::HTML_NAMESPACE => ["dl", "menu", "ol", "ul"]], 'content' => [self::HTML_NAMESPACE => ["meta"]], 'contenteditable' => [self::HTML_NAMESPACE => ["*"]], 'contextmenu' => [self::HTML_NAMESPACE => ["*"]], 'controls' => [self::HTML_NAMESPACE => ["audio", "video"]], 'coords' => [self::HTML_NAMESPACE => ["a", "area"]], 'crossorigin' => [self::SVG_NAMESPACE => ["feImage", "image", "script"], self::HTML_NAMESPACE => ["audio", "img", "link", "script", "video"]], 'cursor' => [self::SVG_NAMESPACE => ["*"]], 'cx' => [self::SVG_NAMESPACE => ["circle", "ellipse", "radialGradient"]], 'cy' => [self::SVG_NAMESPACE => ["circle", "ellipse", "radialGradient"]], 'd' => [self::SVG_NAMESPACE => ["path"]], 'data' => [self::HTML_NAMESPACE => ["object"]], 'datafld' => [self::HTML_NAMESPACE => ["a", "button", "div", "fieldset", "frame", "iframe", "img", "input", "label", "legend", "marquee", "object", "select", "span", "textarea"]], 'dataformatas' => [self::HTML_NAMESPACE => ["button", "div", "input", "label", "legend", "marquee", "object", "option", "select", "span", "table"]], 'datapagesize' => [self::HTML_NAMESPACE => ["table"]], 'datasrc' => [self::HTML_NAMESPACE => ["a", "button", "div", "frame", "iframe", "img", "input", "label", "legend", "marquee", "object", "option", "select", "span", "table", "textarea"]], 'datetime' => [self::HTML_NAMESPACE => ["del", "ins", "time"]], 'declare' => [self::HTML_NAMESPACE => ["object"]], 'decoding' => [self::HTML_NAMESPACE => ["img"]], 'default' => [self::HTML_NAMESPACE => ["track"]], 'defer' => [self::HTML_NAMESPACE => ["script"]], 'diffuseConstant' => [self::SVG_NAMESPACE => ["feDiffuseLighting"]], 'dir' => [self::HTML_NAMESPACE => ["*"]], 'direction' => [self::SVG_NAMESPACE => ["*"], self::HTML_NAMESPACE => ["marquee"]], 'dirname' => [self::HTML_NAMESPACE => ["button", "fieldset", "input", "object", "output", "select", "textarea"]], 'disabled' => [self::HTML_NAMESPACE => ["button", "fieldset", "fieldset", "input", "link", "object", "optgroup", "option", "output", "select", "textarea"]], 'display' => [self::SVG_NAMESPACE => ["*"]], 'divisor' => [self::SVG_NAMESPACE => ["feConvolveMatrix"]], 'dominant-baseline' => [self::SVG_NAMESPACE => ["*"]], 'download' => [self::SVG_NAMESPACE => ["a"], self::HTML_NAMESPACE => ["a", "area"]], 'draggable' => [self::HTML_NAMESPACE => ["*"]], 'dropzone' => [self::HTML_NAMESPACE => ["*"]], 'dur' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'dx' => [self::SVG_NAMESPACE => ["feDropShadow", "feOffset", "text", "tspan"]], 'dy' => [self::SVG_NAMESPACE => ["feDropShadow", "feOffset", "text", "tspan"]], 'edgeMode' => [self::SVG_NAMESPACE => ["feGaussianBlur"]], 'elevation' => [self::SVG_NAMESPACE => ["feDistantLight"]], 'enctype' => [self::HTML_NAMESPACE => ["button", "form"]], 'end' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'enterkeyhint' => [self::HTML_NAMESPACE => ["*"]], 'event' => [self::HTML_NAMESPACE => ["script"]], 'exponent' => [self::SVG_NAMESPACE => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'fetchpriority' => [self::HTML_NAMESPACE => ["img", "link", "script"]], 'fill' => [self::SVG_NAMESPACE => ["*"]], 'fill-opacity' => [self::SVG_NAMESPACE => ["*"]], 'fill-rule' => [self::SVG_NAMESPACE => ["*"]], 'filter' => [self::SVG_NAMESPACE => ["*"]], 'filterUnits' => [self::SVG_NAMESPACE => ["filter"]], 'flood-color' => [self::SVG_NAMESPACE => ["*"]], 'flood-opacity' => [self::SVG_NAMESPACE => ["*"]], 'font-family' => [self::SVG_NAMESPACE => ["*"]], 'font-size' => [self::SVG_NAMESPACE => ["*"]], 'font-size-adjust' => [self::SVG_NAMESPACE => ["*"]], 'font-stretch' => [self::SVG_NAMESPACE => ["*"]], 'font-style' => [self::SVG_NAMESPACE => ["*"]], 'font-variant' => [self::SVG_NAMESPACE => ["*"]], 'font-weight' => [self::SVG_NAMESPACE => ["*"]], 'for' => [self::HTML_NAMESPACE => ["label", "output", "script"]], 'form' => [self::HTML_NAMESPACE => ["button", "fieldset", "input", "object", "output", "select", "textarea"]], 'formaction' => [self::HTML_NAMESPACE => ["button", "form"]], 'formenctype' => [self::HTML_NAMESPACE => ["button", "form"]], 'formmethod' => [self::HTML_NAMESPACE => ["button", "form"]], 'formnovalidate' => [self::HTML_NAMESPACE => ["button", "form"]], 'formtarget' => [self::HTML_NAMESPACE => ["button", "form"]], 'fr' => [self::SVG_NAMESPACE => ["radialGradient"]], 'frame' => [self::HTML_NAMESPACE => ["table"]], 'frameborder' => [self::HTML_NAMESPACE => ["iframe"]], 'framespacing' => [self::HTML_NAMESPACE => ["iframe"]], 'from' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'fx' => [self::SVG_NAMESPACE => ["radialGradient"]], 'fy' => [self::SVG_NAMESPACE => ["radialGradient"]], 'glyph-orientation-horizontal' => [self::SVG_NAMESPACE => ["*"]], 'glyph-orientation-vertical' => [self::SVG_NAMESPACE => ["*"]], 'gradientTransform' => [self::SVG_NAMESPACE => ["linearGradient", "radialGradient"]], 'gradientUnits' => [self::SVG_NAMESPACE => ["linearGradient", "radialGradient"]], 'headers' => [self::HTML_NAMESPACE => ["td", "th"]], 'height' => [self::SVG_NAMESPACE => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence", "filter", "foreignObject", "image", "mask", "pattern", "rect", "svg", "symbol", "use"], self::HTML_NAMESPACE => ["canvas", "embed", "iframe", "img", "object", "source", "table", "tbody", "td", "th", "tr", "video"]], 'hidden' => [self::HTML_NAMESPACE => ["*"]], 'high' => [self::HTML_NAMESPACE => ["meter"]], 'href' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "discard", "feImage", "image", "linearGradient", "mpath", "pattern", "radialGradient", "script", "set", "textPath", "use"], self::HTML_NAMESPACE => ["a", "area", "base", "link"]], 'hreflang' => [self::SVG_NAMESPACE => ["a"], self::HTML_NAMESPACE => ["a", "area", "area", "link"]], 'hspace' => [self::HTML_NAMESPACE => ["embed", "iframe", "img", "input", "object"]], 'http-equiv' => [self::HTML_NAMESPACE => ["meta"]], 'id' => [self::HTML_NAMESPACE => ["*"]], 'image-rendering' => [self::SVG_NAMESPACE => ["*"]], 'imagesizes' => [self::HTML_NAMESPACE => ["link"]], 'imagesrcset' => [self::HTML_NAMESPACE => ["link"]], 'in' => [self::SVG_NAMESPACE => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feGaussianBlur", "feMergeNode", "feMorphology", "feOffset", "feSpecularLighting", "feTile"]], 'in2' => [self::SVG_NAMESPACE => ["feBlend", "feComposite", "feDisplacementMap"]], 'inputmode' => [self::HTML_NAMESPACE => ["*"]], 'integrity' => [self::HTML_NAMESPACE => ["link", "script"]], 'intercept' => [self::SVG_NAMESPACE => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'is' => [self::HTML_NAMESPACE => ["*"]], 'ismap' => [self::HTML_NAMESPACE => ["img", "input"]], 'itemid' => [self::HTML_NAMESPACE => ["*"]], 'itemprop' => [self::HTML_NAMESPACE => ["*"]], 'itemref' => [self::HTML_NAMESPACE => ["*"]], 'itemscope' => [self::HTML_NAMESPACE => ["*"]], 'itemtype' => [self::HTML_NAMESPACE => ["*"]], 'k1' => [self::SVG_NAMESPACE => ["feComposite"]], 'k2' => [self::SVG_NAMESPACE => ["feComposite"]], 'k3' => [self::SVG_NAMESPACE => ["feComposite"]], 'k4' => [self::SVG_NAMESPACE => ["feComposite"]], 'kernelMatrix' => [self::SVG_NAMESPACE => ["feConvolveMatrix", "feConvolveMatrix", "feDiffuseLighting", "feSpecularLighting"]], 'keyPoints' => [self::SVG_NAMESPACE => ["animateMotion"]], 'keySplines' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'keyTimes' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform"]], 'kind' => [self::HTML_NAMESPACE => ["track"]], 'label' => [self::HTML_NAMESPACE => ["menu", "optgroup", "option", "track"]], 'lang' => [self::HTML_NAMESPACE => ["*"]], 'language' => [self::HTML_NAMESPACE => ["script"]], 'leftmargin' => [self::HTML_NAMESPACE => ["body"]], 'lengthAdjust' => [self::SVG_NAMESPACE => ["text", "textPath", "tspan"]], 'letter-spacing' => [self::SVG_NAMESPACE => ["*"]], 'lighting-color' => [self::SVG_NAMESPACE => ["*"]], 'limitingConeAngle' => [self::SVG_NAMESPACE => ["feSpotLight"]], 'link' => [self::HTML_NAMESPACE => ["body"]], 'list' => [self::HTML_NAMESPACE => ["input"]], 'loading' => [self::HTML_NAMESPACE => ["iframe", "img"]], 'longdesc' => [self::HTML_NAMESPACE => ["iframe", "img"]], 'loop' => [self::HTML_NAMESPACE => ["audio", "marquee", "video"]], 'low' => [self::HTML_NAMESPACE => ["meter"]], 'lowsrc' => [self::HTML_NAMESPACE => ["img"]], 'manifest' => [self::HTML_NAMESPACE => ["html"]], 'marginheight' => [self::HTML_NAMESPACE => ["body", "iframe"]], 'marginwidth' => [self::HTML_NAMESPACE => ["body", "iframe"]], 'marker-end' => [self::SVG_NAMESPACE => ["*"]], 'marker-mid' => [self::SVG_NAMESPACE => ["*"]], 'marker-start' => [self::SVG_NAMESPACE => ["*"]], 'markerHeight' => [self::SVG_NAMESPACE => ["marker"]], 'markerUnits' => [self::SVG_NAMESPACE => ["marker"]], 'markerWidth' => [self::SVG_NAMESPACE => ["marker"]], 'mask' => [self::SVG_NAMESPACE => ["*"]], 'maskContentUnits' => [self::SVG_NAMESPACE => ["mask"]], 'maskUnits' => [self::SVG_NAMESPACE => ["mask"]], 'max' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"], self::HTML_NAMESPACE => ["input", "meter", "progress"]], 'maxlength' => [self::HTML_NAMESPACE => ["input", "textarea"]], 'media' => [self::SVG_NAMESPACE => ["style"], self::HTML_NAMESPACE => ["link", "meta", "source", "style"]], 'method' => [self::SVG_NAMESPACE => ["textPath"], self::HTML_NAMESPACE => ["button", "form"]], 'methods' => [self::HTML_NAMESPACE => ["a", "link"]], 'min' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"], self::HTML_NAMESPACE => ["input", "meter"]], 'minlength' => [self::HTML_NAMESPACE => ["input", "textarea"]], 'mode' => [self::SVG_NAMESPACE => ["feBlend"]], 'multiple' => [self::HTML_NAMESPACE => ["input", "select"]], 'muted' => [self::HTML_NAMESPACE => ["audio", "video"]], 'name' => [self::HTML_NAMESPACE => ["a", "button", "embed", "fieldset", "form", "iframe", "img", "input", "map", "meta", "object", "option", "output", "select", "slot", "textarea"]], 'nohref' => [self::HTML_NAMESPACE => ["area"]], 'nomodule' => [self::HTML_NAMESPACE => ["script"]], 'nonce' => [self::HTML_NAMESPACE => ["*"]], 'noshade' => [self::HTML_NAMESPACE => ["hr"]], 'novalidate' => [self::HTML_NAMESPACE => ["button", "form"]], 'nowrap' => [self::HTML_NAMESPACE => ["td", "th"]], 'numOctaves' => [self::SVG_NAMESPACE => ["feTurbulence"]], 'offset' => [self::SVG_NAMESPACE => ["feFuncA", "feFuncB", "feFuncG", "feFuncR", "stop"]], 'onabort' => [self::SVG_NAMESPACE => ["svg"]], 'onafterprint' => [self::SVG_NAMESPACE => ["*"]], 'onbeforeprint' => [self::SVG_NAMESPACE => ["*"]], 'onbegin' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'oncancel' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncanplay' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncanplaythrough' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onchange' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onclick' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onclose' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncopy' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncuechange' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oncut' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondblclick' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondrag' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragend' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragenter' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragexit' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragleave' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragover' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondragstart' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondrop' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ondurationchange' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onemptied' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onend' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'onended' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onerror' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onfocus' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onfocusin' => [self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "defs", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video"]], 'onfocusout' => [self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "defs", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video"]], 'onhashchange' => [self::SVG_NAMESPACE => ["*"]], 'oninput' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'oninvalid' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onkeydown' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onkeypress' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onkeyup' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onload' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onloadeddata' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onloadedmetadata' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onloadstart' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmessage' => [self::SVG_NAMESPACE => ["*"]], 'onmousedown' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseenter' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseleave' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmousemove' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseout' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseover' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmouseup' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onmousewheel' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onoffline' => [self::SVG_NAMESPACE => ["*"]], 'ononline' => [self::SVG_NAMESPACE => ["*"]], 'onpagehide' => [self::SVG_NAMESPACE => ["*"]], 'onpageshow' => [self::SVG_NAMESPACE => ["*"]], 'onpaste' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onpause' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onplay' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onplaying' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onpopstate' => [self::SVG_NAMESPACE => ["*"]], 'onprogress' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onratechange' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onrepeat' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'onreset' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onresize' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onscroll' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onseeked' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onseeking' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onselect' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onshow' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"], self::HTML_NAMESPACE => ["*"]], 'onstalled' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onstorage' => [self::SVG_NAMESPACE => ["*"]], 'onsubmit' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onsuspend' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ontimeupdate' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'ontoggle' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onunload' => [self::SVG_NAMESPACE => ["*"]], 'onvolumechange' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'onwaiting' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "defs", "desc", "ellipse", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'opacity' => [self::SVG_NAMESPACE => ["*"]], 'open' => [self::HTML_NAMESPACE => ["details", "dialog"]], 'operator' => [self::SVG_NAMESPACE => ["feComposite", "feMorphology"]], 'optimum' => [self::HTML_NAMESPACE => ["meter"]], 'order' => [self::SVG_NAMESPACE => ["feConvolveMatrix"]], 'orient' => [self::SVG_NAMESPACE => ["marker"]], 'origin' => [self::SVG_NAMESPACE => ["animateMotion"]], 'overflow' => [self::SVG_NAMESPACE => ["*"]], 'paint-order' => [self::SVG_NAMESPACE => ["*"]], 'path' => [self::SVG_NAMESPACE => ["animateMotion", "textPath"]], 'pathLength' => [self::SVG_NAMESPACE => ["circle", "ellipse", "line", "path", "polygon", "polyline", "rect"]], 'pattern' => [self::HTML_NAMESPACE => ["input"]], 'patternContentUnits' => [self::SVG_NAMESPACE => ["pattern"]], 'patternTransform' => [self::SVG_NAMESPACE => ["pattern"]], 'patternUnits' => [self::SVG_NAMESPACE => ["pattern"]], 'ping' => [self::SVG_NAMESPACE => ["a"], self::HTML_NAMESPACE => ["a", "area"]], 'placeholder' => [self::HTML_NAMESPACE => ["input", "textarea"]], 'playbackorder' => [self::SVG_NAMESPACE => ["svg"]], 'playsinline' => [self::HTML_NAMESPACE => ["video"]], 'pointer-events' => [self::SVG_NAMESPACE => ["*"]], 'points' => [self::SVG_NAMESPACE => ["polygon", "polyline"]], 'pointsAtX' => [self::SVG_NAMESPACE => ["feSpotLight"]], 'pointsAtY' => [self::SVG_NAMESPACE => ["feSpotLight"]], 'pointsAtZ' => [self::SVG_NAMESPACE => ["feSpotLight"]], 'popover' => [self::HTML_NAMESPACE => ["*"]], 'popovertarget' => [self::HTML_NAMESPACE => ["*"]], 'popovertargetaction' => [self::HTML_NAMESPACE => ["*"]], 'poster' => [self::HTML_NAMESPACE => ["video"]], 'preload' => [self::HTML_NAMESPACE => ["audio", "video"]], 'preserveAlpha' => [self::SVG_NAMESPACE => ["feConvolveMatrix"]], 'preserveAspectRatio' => [self::SVG_NAMESPACE => ["canvas", "feImage", "image", "marker", "pattern", "svg", "symbol", "view"]], 'primitiveUnits' => [self::SVG_NAMESPACE => ["filter"]], 'profile' => [self::HTML_NAMESPACE => ["head"]], 'r' => [self::SVG_NAMESPACE => ["circle", "radialGradient"]], 'radius' => [self::SVG_NAMESPACE => ["feMorphology"]], 'readonly' => [self::HTML_NAMESPACE => ["form-associated custom elements", "input", "textarea"]], 'refX' => [self::SVG_NAMESPACE => ["marker", "symbol"]], 'refY' => [self::SVG_NAMESPACE => ["marker", "symbol"]], 'referrerpolicy' => [self::SVG_NAMESPACE => ["a"], self::HTML_NAMESPACE => ["a", "area", "iframe", "img", "link", "script"]], 'rel' => [self::SVG_NAMESPACE => ["a"], self::HTML_NAMESPACE => ["a", "area", "form", "link"]], 'repeatCount' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'repeatDur' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'required' => [self::HTML_NAMESPACE => ["input", "select", "textarea"]], 'requiredExtensions' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "mask", "path", "polygon", "polyline", "rect", "set", "svg", "switch", "text", "textPath", "tspan", "unknown", "use", "video"]], 'restart' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'result' => [self::SVG_NAMESPACE => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence"]], 'rev' => [self::HTML_NAMESPACE => ["a", "link"]], 'reversed' => [self::HTML_NAMESPACE => ["ol"]], 'rightmargin' => [self::HTML_NAMESPACE => ["body"]], 'role' => [self::SVG_NAMESPACE => ["a", "audio", "canvas", "circle", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "path", "polygon", "polyline", "rect", "svg", "switch", "symbol", "text", "textPath", "tspan", "unknown", "use", "video", "view"], self::HTML_NAMESPACE => ["*"]], 'rotate' => [self::SVG_NAMESPACE => ["animateMotion", "text", "tspan"]], 'rows' => [self::HTML_NAMESPACE => ["textarea"]], 'rowspan' => [self::HTML_NAMESPACE => ["td", "th"]], 'rules' => [self::HTML_NAMESPACE => ["table"]], 'rx' => [self::SVG_NAMESPACE => ["ellipse", "rect"]], 'ry' => [self::SVG_NAMESPACE => ["ellipse", "rect"]], 'sandbox' => [self::HTML_NAMESPACE => ["iframe"]], 'scale' => [self::SVG_NAMESPACE => ["feDisplacementMap"]], 'scheme' => [self::HTML_NAMESPACE => ["meta"]], 'scope' => [self::HTML_NAMESPACE => ["td", "th"]], 'scrolling' => [self::HTML_NAMESPACE => ["iframe"]], 'seed' => [self::SVG_NAMESPACE => ["feTurbulence"]], 'selected' => [self::HTML_NAMESPACE => ["option"]], 'shape' => [self::HTML_NAMESPACE => ["a", "area"]], 'shape-rendering' => [self::SVG_NAMESPACE => ["*"]], 'side' => [self::SVG_NAMESPACE => ["textPath"]], 'size' => [self::HTML_NAMESPACE => ["hr", "input", "select"]], 'sizes' => [self::HTML_NAMESPACE => ["img", "link", "source"]], 'slope' => [self::SVG_NAMESPACE => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'slot' => [self::HTML_NAMESPACE => ["*"]], 'spacing' => [self::SVG_NAMESPACE => ["textPath"]], 'span' => [self::HTML_NAMESPACE => ["col", "colgroup"]], 'specularConstant' => [self::SVG_NAMESPACE => ["feSpecularLighting"]], 'specularExponent' => [self::SVG_NAMESPACE => ["feSpecularLighting", "feSpotLight"]], 'spellcheck' => [self::HTML_NAMESPACE => ["*"]], 'spreadMethod' => [self::SVG_NAMESPACE => ["linearGradient", "radialGradient"]], 'src' => [self::HTML_NAMESPACE => ["audio", "embed", "iframe", "img", "input", "script", "source", "track", "video"]], 'srcdoc' => [self::HTML_NAMESPACE => ["iframe"]], 'srclang' => [self::HTML_NAMESPACE => ["track"]], 'srcset' => [self::HTML_NAMESPACE => ["img", "source"]], 'standby' => [self::HTML_NAMESPACE => ["object"]], 'start' => [self::HTML_NAMESPACE => ["ol"]], 'startOffset' => [self::SVG_NAMESPACE => ["textPath"]], 'stdDeviation' => [self::SVG_NAMESPACE => ["feDropShadow", "feGaussianBlur"]], 'step' => [self::HTML_NAMESPACE => ["input"]], 'stitchTiles' => [self::SVG_NAMESPACE => ["feTurbulence"]], 'stop-color' => [self::SVG_NAMESPACE => ["*"]], 'stop-opacity' => [self::SVG_NAMESPACE => ["*"]], 'stroke' => [self::SVG_NAMESPACE => ["*"]], 'stroke-dasharray' => [self::SVG_NAMESPACE => ["*"]], 'stroke-dashoffset' => [self::SVG_NAMESPACE => ["*"]], 'stroke-linecap' => [self::SVG_NAMESPACE => ["*"]], 'stroke-linejoin' => [self::SVG_NAMESPACE => ["*"]], 'stroke-miterlimit' => [self::SVG_NAMESPACE => ["*"]], 'stroke-opacity' => [self::SVG_NAMESPACE => ["*"]], 'stroke-width' => [self::SVG_NAMESPACE => ["*"]], 'style' => [self::HTML_NAMESPACE => ["*"]], 'summary' => [self::HTML_NAMESPACE => ["table"]], 'surfaceScale' => [self::SVG_NAMESPACE => ["feDiffuseLighting", "feSpecularLighting"]], 'systemLanguage' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "discard", "ellipse", "foreignObject", "g", "iframe", "image", "line", "mask", "path", "polygon", "polyline", "rect", "set", "svg", "switch", "text", "textPath", "tspan", "unknown", "use", "video"]], 'tabindex' => [self::HTML_NAMESPACE => ["*"]], 'tableValues' => [self::SVG_NAMESPACE => ["feFuncA", "feFuncB", "feFuncG", "feFuncR"]], 'target' => [self::SVG_NAMESPACE => ["a"], self::HTML_NAMESPACE => ["a", "area", "base", "button", "form", "link"]], 'targetX' => [self::SVG_NAMESPACE => ["feConvolveMatrix"]], 'targetY' => [self::SVG_NAMESPACE => ["feConvolveMatrix"]], 'text' => [self::HTML_NAMESPACE => ["body"]], 'text-anchor' => [self::SVG_NAMESPACE => ["*"]], 'text-decoration' => [self::SVG_NAMESPACE => ["*"]], 'text-overflow' => [self::SVG_NAMESPACE => ["*"]], 'text-rendering' => [self::SVG_NAMESPACE => ["*"]], 'textLength' => [self::SVG_NAMESPACE => ["text", "textPath", "tspan"]], 'timelinebegin' => [self::SVG_NAMESPACE => ["svg"]], 'title' => [self::HTML_NAMESPACE => ["*"]], 'to' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "set"]], 'topmargin' => [self::HTML_NAMESPACE => ["body"]], 'transform' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "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", "filter", "foreignObject", "g", "iframe", "image", "line", "marker", "mask", "metadata", "mpath", "path", "polygon", "polyline", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]], 'translate' => [self::HTML_NAMESPACE => ["*"]], 'truespeed' => [self::HTML_NAMESPACE => ["marquee"]], 'type' => [self::SVG_NAMESPACE => ["a", "animateTransform", "feColorMatrix", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feTurbulence", "script", "style"], self::HTML_NAMESPACE => ["a", "area", "area", "button", "embed", "input", "li", "link", "menu", "object", "ol", "script", "source", "style", "ul"]], 'typemustmatch' => [self::HTML_NAMESPACE => ["object"]], 'unicode-bidi' => [self::SVG_NAMESPACE => ["*"]], 'urn' => [self::HTML_NAMESPACE => ["a", "link"]], 'usemap' => [self::HTML_NAMESPACE => ["img", "input", "object"]], 'valign' => [self::HTML_NAMESPACE => ["col", "tbody", "td", "th", "tr"]], 'value' => [self::HTML_NAMESPACE => ["button", "data", "input", "li", "meter", "option", "progress"]], 'values' => [self::SVG_NAMESPACE => ["animate", "animateMotion", "animateTransform", "feColorMatrix"]], 'vector-effect' => [self::SVG_NAMESPACE => ["*"]], 'version' => [self::HTML_NAMESPACE => ["html"]], 'viewBox' => [self::SVG_NAMESPACE => ["marker", "pattern", "svg", "symbol", "view"]], 'visibility' => [self::SVG_NAMESPACE => ["*"]], 'vlink' => [self::HTML_NAMESPACE => ["body"]], 'vspace' => [self::HTML_NAMESPACE => ["embed", "iframe", "img", "input", "object"]], 'white-space' => [self::SVG_NAMESPACE => ["*"]], 'width' => [self::SVG_NAMESPACE => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "feSpecularLighting", "feTile", "feTurbulence", "filter", "foreignObject", "image", "mask", "pattern", "rect", "svg", "symbol", "use"], self::HTML_NAMESPACE => ["canvas", "col", "embed", "hr", "iframe", "img", "object", "pre", "source", "table", "td", "th", "video"]], 'word-spacing' => [self::SVG_NAMESPACE => ["*"]], 'wrap' => [self::HTML_NAMESPACE => ["textarea"]], 'writing-mode' => [self::SVG_NAMESPACE => ["*"]], 'x' => [self::SVG_NAMESPACE => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "image", "mask", "pattern", "rect", "svg", "symbol", "text", "tspan", "use"]], 'x1' => [self::SVG_NAMESPACE => ["line", "linearGradient"]], 'x2' => [self::SVG_NAMESPACE => ["line", "linearGradient"]], 'xChannelSelector' => [self::SVG_NAMESPACE => ["feDisplacementMap"]], 'y' => [self::SVG_NAMESPACE => ["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feGaussianBlur", "feImage", "feMerge", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "foreignObject", "image", "mask", "pattern", "rect", "svg", "symbol", "text", "tspan", "use"]], 'y1' => [self::SVG_NAMESPACE => ["line", "linearGradient"]], 'y2' => [self::SVG_NAMESPACE => ["line", "linearGradient"]], 'yChannelSelector' => [self::SVG_NAMESPACE => ["feDisplacementMap"]], 'z' => [self::SVG_NAMESPACE => ["fePointLight", "feSpotLight"]], 'zoomAndPan' => [self::SVG_NAMESPACE => ["svg", "view"]]], self::XLINK_NAMESPACE => ['href' => [self::SVG_NAMESPACE => ["a", "image", "linearGradient", "pattern", "radialGradient", "script", "textPath", "use", "feImage"]], 'title' => [self::SVG_NAMESPACE => ["a", "image", "linearGradient", "pattern", "radialGradient", "script", "textPath", "use"]]], self::XML_NAMESPACE => ['space' => [self::SVG_NAMESPACE => ["a", "animate", "animateMotion", "animateTransform", "audio", "canvas", "circle", "clipPath", "defs", "desc", "discard", "ellipse", "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", "filter", "foreignObject", "g", "iframe", "image", "line", "linearGradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect", "script", "set", "stop", "style", "svg", "switch", "symbol", "text", "textPath", "title", "tspan", "unknown", "use", "video", "view"]]]]; + /** @var array The baseline list of allowed attributes */ + protected const BASELINE_ATTR = [ + self::HTML_NAMESPACE => [ + 'abbr' => true, + 'accept' => true, + 'accept-charset' => true, + 'accesskey' => true, + 'action' => true, + 'align' => true, + 'alink' => true, + 'allow' => true, + 'allowfullscreen' => true, + 'allowpaymentrequest' => true, + 'alt' => true, + 'anchor' => true, + 'archive' => true, + 'as' => true, + 'async' => true, + 'autocapitalize' => true, + 'autocomplete' => true, + 'autocorrect' => true, + 'autofocus' => true, + 'autopictureinpicture' => true, + 'autoplay' => true, + 'axis' => true, + 'background' => true, + 'behavior' => true, + 'bgcolor' => true, + 'border' => true, + 'bordercolor' => true, + 'capture' => true, + 'cellpadding' => true, + 'cellspacing' => true, + 'challenge' => true, + 'char' => true, + 'charoff' => true, + 'charset' => true, + 'checked' => true, + 'cite' => true, + 'class' => true, + 'classid' => true, + 'clear' => true, + 'code' => true, + 'codebase' => true, + 'codetype' => true, + 'color' => true, + 'cols' => true, + 'colspan' => true, + 'compact' => true, + 'content' => true, + 'contenteditable' => true, + 'controls' => true, + 'controlslist' => true, + 'conversiondestination' => true, + 'coords' => true, + 'crossorigin' => true, + 'csp' => true, + 'data' => true, + 'datetime' => true, + 'declare' => true, + 'decoding' => true, + 'default' => true, + 'defer' => true, + 'dir' => true, + 'direction' => true, + 'dirname' => true, + 'disabled' => true, + 'disablepictureinpicture' => true, + 'disableremoteplayback' => true, + 'disallowdocumentaccess' => true, + 'download' => true, + 'draggable' => true, + 'elementtiming' => true, + 'enctype' => true, + 'end' => true, + 'enterkeyhint' => true, + 'event' => true, + 'exportparts' => true, + 'face' => true, + 'for' => true, + 'form' => true, + 'formaction' => true, + 'formenctype' => true, + 'formmethod' => true, + 'formnovalidate' => true, + 'formtarget' => true, + 'frame' => true, + 'frameborder' => true, + 'headers' => true, + 'height' => true, + 'hidden' => true, + 'high' => true, + 'href' => true, + 'hreflang' => true, + 'hreftranslate' => true, + 'hspace' => true, + 'http-equiv' => true, + 'id' => true, + 'imagesizes' => true, + 'imagesrcset' => true, + 'importance' => true, + 'impressiondata' => true, + 'impressionexpiry' => true, + 'incremental' => true, + 'inert' => true, + 'inputmode' => true, + 'integrity' => true, + 'invisible' => true, + 'is' => true, + 'ismap' => true, + 'keytype' => true, + 'kind' => true, + 'label' => true, + 'lang' => true, + 'language' => true, + 'latencyhint' => true, + 'leftmargin' => true, + 'link' => true, + 'list' => true, + 'loading' => true, + 'longdesc' => true, + 'loop' => true, + 'low' => true, + 'lowsrc' => true, + 'manifest' => true, + 'marginheight' => true, + 'marginwidth' => true, + 'max' => true, + 'maxlength' => true, + 'mayscript' => true, + 'media' => true, + 'method' => true, + 'min' => true, + 'minlength' => true, + 'multiple' => true, + 'muted' => true, + 'name' => true, + 'nohref' => true, + 'nomodule' => true, + 'nonce' => true, + 'noresize' => true, + 'noshade' => true, + 'novalidate' => true, + 'nowrap' => true, + 'object' => true, + 'open' => true, + 'optimum' => true, + 'part' => true, + 'pattern' => true, + 'ping' => true, + 'placeholder' => true, + 'playsinline' => true, + 'policy' => true, + 'poster' => true, + 'preload' => true, + 'pseudo' => true, + 'readonly' => true, + 'referrerpolicy' => true, + 'rel' => true, + 'reportingorigin' => true, + 'required' => true, + 'resources' => true, + 'rev' => true, + 'reversed' => true, + 'role' => true, + 'rows' => true, + 'rowspan' => true, + 'rules' => true, + 'sandbox' => true, + 'scheme' => true, + 'scope' => true, + 'scopes' => true, + 'scrollamount' => true, + 'scrolldelay' => true, + 'scrolling' => true, + 'select' => true, + 'selected' => true, + 'shadowroot' => true, + 'shadowrootdelegatesfocus' => true, + 'shape' => true, + 'size' => true, + 'sizes' => true, + 'slot' => true, + 'span' => true, + 'spellcheck' => true, + 'src' => true, + 'srcdoc' => true, + 'srclang' => true, + 'srcset' => true, + 'standby' => true, + 'start' => true, + 'step' => true, + 'style' => true, + 'summary' => true, + 'tabindex' => true, + 'target' => true, + 'text' => true, + 'title' => true, + 'topmargin' => true, + 'translate' => true, + 'truespeed' => true, + 'trusttoken' => true, + 'type' => true, + 'usemap' => true, + 'valign' => true, + 'value' => true, + 'valuetype' => true, + 'version' => true, + 'virtualkeyboardpolicy' => true, + 'vlink' => true, + 'vspace' => true, + 'webkitdirectory' => true, + 'width' => true, + 'wrap' => true, + ], + ]; /** @var array The default configuration structure */ protected const DEFAULT_CONF = [ 'allowElements' => [ @@ -777,12 +997,25 @@ abstract class AbstractSanitizer { # To determine the sanitize action for an attribute given a Sanitizer # configuration dictionary config, run these steps: # Let kind be attribute’s attribute kind. + $ns = $attr->namespaceURI; + $name = $attr->localName; + $eNs = $attr->ownerElement->namespaceURI; + $eName = $attr->ownerElement->localName; + $set = self::KNOWN_ATTRIBUTES[$ns][$name][$eNs] ?? []; + if (!array_intersect($set, [$eName, "*"])) { # The attribute kind of an attribute is one of regular # or unknown. Let attribute kind be: # - unknown, if the [HTML] specification does not assign any # meaning to attribute’s name. + $kind = self::KIND_UNKNOWN; + } else { # - regular, otherwise. - # If kind is unknown and if config["allowUnknownMarkup"] does not exist or it config["allowUnknownMarkup"] is false: Return drop. + $kind = self::KIND_REGULAR; + } + if ($kind === self::KIND_UNKNOWN && ($this->config['allowUnknownMarkup'] ?? self::DEFAULT_CONF['allowUnknownMarkup'])) { + # If kind is unknown and if config["allowUnknownMarkup"] does not exist or it config["allowUnknownMarkup"] is false: Return drop. + return self::ACTION_DROP; + } elseif ($kind === self::KIND_REGULAR) {} # If kind is regular and attribute’s local name does not match any name in the baseline attribute allow list: Return drop. # If attribute matches any attribute match list in config’s attribute drop list: Return drop. # If attribute allow list exists in config: