From f256450c2521360a492e9e9a172f737e64839159 Mon Sep 17 00:00:00 2001 From: Garth Poitras <411908+gpoitch@users.noreply.github.com> Date: Tue, 1 Aug 2023 11:30:23 -0400 Subject: [PATCH 1/3] Apply attribute name handling in pretty mode --- src/index.js | 12 +- src/pretty.js | 23 ++- src/util.js | 4 +- test/pretty.test.js | 461 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 490 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index 781ccc41..4ceda2a0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,11 @@ -import { encodeEntities, styleObjToCss, UNSAFE_NAME } from './util.js'; +import { + encodeEntities, + styleObjToCss, + UNSAFE_NAME, + NAMESPACE_REPLACE_REGEX, + HTML_LOWER_CASE, + SVG_CAMEL_CASE +} from './util.js'; import { options, h, Fragment } from 'preact'; import { CHILDREN, @@ -454,9 +461,6 @@ function _renderToString(vnode, context, isSvgMode, selectValue, parent) { return s + '>' + html + ''; } -const HTML_LOWER_CASE = /^accessK|^auto[A-Z]|^ch|^col|cont|cross|dateT|encT|form[A-Z]|frame|hrefL|inputM|maxL|minL|noV|playsI|readO|rowS|spellC|src[A-Z]|tabI|item[A-Z]/; -const SVG_CAMEL_CASE = /^ac|^ali|arabic|basel|cap|clipPath$|clipRule$|color|dominant|enable|fill|flood|font|glyph[^R]|horiz|image|letter|lighting|marker[^WUH]|overline|panose|pointe|paint|rendering|shape|stop|strikethrough|stroke|text[^L]|transform|underline|unicode|units|^v[^i]|^w|^xH/; -const NAMESPACE_REPLACE_REGEX = /^(xlink|xmlns|xml)(:|[A-Z])/; const SELF_CLOSING = new Set([ 'area', 'base', diff --git a/src/pretty.js b/src/pretty.js index 4e37d92c..08f1c699 100644 --- a/src/pretty.js +++ b/src/pretty.js @@ -6,8 +6,10 @@ import { getChildren, createComponent, UNSAFE_NAME, - XLINK, - VOID_ELEMENTS + VOID_ELEMENTS, + NAMESPACE_REPLACE_REGEX, + HTML_LOWER_CASE, + SVG_CAMEL_CASE } from './util.js'; import { COMMIT, DIFF, DIFFED, RENDER, SKIP_EFFECTS } from './constants.js'; import { options, Fragment } from 'preact'; @@ -243,8 +245,21 @@ function _renderToStringPretty( } else if (name === 'className') { if (typeof props.class !== 'undefined') continue; name = 'class'; - } else if (isSvgMode && XLINK.test(name)) { - name = name.toLowerCase().replace(/^xlink:?/, 'xlink:'); + } else if (name === 'acceptCharset') { + name = 'accept-charset'; + } else if (name === 'httpEquiv') { + name = 'http-equiv'; + } else if (NAMESPACE_REPLACE_REGEX.test(name)) { + name = name.replace(NAMESPACE_REPLACE_REGEX, '$1:$2').toLowerCase(); + } else if (isSvgMode) { + if (SVG_CAMEL_CASE.test(name)) { + name = + name === 'panose1' + ? 'panose-1' + : name.replace(/([A-Z])/g, '-$1').toLowerCase(); + } + } else if (HTML_LOWER_CASE.test(name)) { + name = name.toLowerCase(); } if (name === 'htmlFor') { diff --git a/src/util.js b/src/util.js index c3a598e1..bc80ea48 100644 --- a/src/util.js +++ b/src/util.js @@ -1,6 +1,8 @@ export const VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/; export const UNSAFE_NAME = /[\s\n\\/='"\0<>]/; -export const XLINK = /^xlink:?./; +export const NAMESPACE_REPLACE_REGEX = /^(xlink|xmlns|xml)(:|[A-Z])/; +export const HTML_LOWER_CASE = /^accessK|^auto[A-Z]|^ch|^col|cont|cross|dateT|encT|form[A-Z]|frame|hrefL|inputM|maxL|minL|noV|playsI|readO|rowS|spellC|src[A-Z]|tabI|item[A-Z]/; +export const SVG_CAMEL_CASE = /^ac|^ali|arabic|basel|cap|clipPath$|clipRule$|color|dominant|enable|fill|flood|font|glyph[^R]|horiz|image|letter|lighting|marker[^WUH]|overline|panose|pointe|paint|rendering|shape|stop|strikethrough|stroke|text[^L]|transform|underline|unicode|units|^v[^i]|^w|^xH/; // DOM properties that should NOT have "px" added when numeric const ENCODED_ENTITIES = /["&<]/; diff --git a/test/pretty.test.js b/test/pretty.test.js index 7d6ecd1a..db657e0e 100644 --- a/test/pretty.test.js +++ b/test/pretty.test.js @@ -5,7 +5,7 @@ import { expect } from 'chai'; import { dedent } from './utils.js'; describe('pretty', () => { - let prettyRender = (jsx) => render(jsx, {}, { pretty: true }); + let prettyRender = (jsx, opts) => render(jsx, {}, { pretty: true, ...opts }); it('should render no whitespace by default', () => { let rendered = basicRender( @@ -196,4 +196,463 @@ describe('pretty', () => { it('should not render function children', () => { expect(prettyRender(
{() => {}}
)).to.equal('
'); }); + + it('should render SVG elements', () => { + let rendered = prettyRender( + + + +
+ + + + + + ); + + expect(rendered).to.equal( + `\n\t\n\t\n\t\t
\n\t
\n\t\n\t\t\n\t\n
` + ); + }); + + describe('Attribute casing', () => { + it('should have correct SVG casing', () => { + const svgAttributes = { + accentHeight: 'accent-height', + accumulate: 'accumulate', + additive: 'additive', + alignmentBaseline: 'alignment-baseline', + allowReorder: 'allowReorder', // unsure + alphabetic: 'alphabetic', + amplitude: 'amplitude', + arabicForm: 'arabic-form', + ascent: 'ascent', + attributeName: 'attributeName', + attributeType: 'attributeType', + autoReverse: 'autoReverse', // unsure + azimuth: 'azimuth', + baseFrequency: 'baseFrequency', + baselineShift: 'baseline-shift', + baseProfile: 'baseProfile', + bbox: 'bbox', + begin: 'begin', + bias: 'bias', + by: 'by', + calcMode: 'calcMode', + capHeight: 'cap-height', + class: 'class', + clip: 'clip', + clipPathUnits: 'clipPathUnits', + clipPath: 'clip-path', + clipRule: 'clip-rule', + color: 'color', + colorInterpolation: 'color-interpolation', + colorInterpolationFilters: 'color-interpolation-filters', + colorProfile: 'color-profile', + colorRendering: 'color-rendering', + contentScriptType: 'contentScriptType', + contentStyleType: 'contentStyleType', + crossorigin: 'crossorigin', + cursor: 'cursor', + cx: 'cx', + cy: 'cy', + d: 'd', + decelerate: 'decelerate', + descent: 'descent', + diffuseConstant: 'diffuseConstant', + direction: 'direction', + display: 'display', + divisor: 'divisor', + dominantBaseline: 'dominant-baseline', + dur: 'dur', + dx: 'dx', + dy: 'dy', + edgeMode: 'edgeMode', + elevation: 'elevation', + enableBackground: 'enable-background', + end: 'end', + exponent: 'exponent', + fill: 'fill', + fillOpacity: 'fill-opacity', + fillRule: 'fill-rule', + filter: 'filter', + filterRes: 'filterRes', + filterUnits: 'filterUnits', + floodColor: 'flood-color', + floodOpacity: 'flood-opacity', + fontFamily: 'font-family', + fontSize: 'font-size', + fontSizeAdjust: 'font-size-adjust', + fontStretch: 'font-stretch', + fontStyle: 'font-style', + fontVariant: 'font-variant', + fontWeight: 'font-weight', + format: 'format', + from: 'from', + fx: 'fx', + fy: 'fy', + g1: 'g1', + g2: 'g2', + glyphName: 'glyph-name', + glyphOrientationHorizontal: 'glyph-orientation-horizontal', + glyphOrientationVertical: 'glyph-orientation-vertical', + glyphRef: 'glyphRef', + gradientTransform: 'gradientTransform', + gradientUnits: 'gradientUnits', + hanging: 'hanging', + horizAdvX: 'horiz-adv-x', + horizOriginX: 'horiz-origin-x', + ideographic: 'ideographic', + imageRendering: 'image-rendering', + in: 'in', + in2: 'in2', + intercept: 'intercept', + k: 'k', + k1: 'k1', + k2: 'k2', + k3: 'k3', + k4: 'k4', + kernelMatrix: 'kernelMatrix', + kernelUnitLength: 'kernelUnitLength', + kerning: 'kerning', + keyPoints: 'keyPoints', + keySplines: 'keySplines', + keyTimes: 'keyTimes', + lengthAdjust: 'lengthAdjust', + letterSpacing: 'letter-spacing', + lightingColor: 'lighting-color', + limitingConeAngle: 'limitingConeAngle', + local: 'local', + markerEnd: 'marker-end', + markerMid: 'marker-mid', + markerStart: 'marker-start', + markerHeight: 'markerHeight', + markerUnits: 'markerUnits', + markerWidth: 'markerWidth', + mask: 'mask', + maskContentUnits: 'maskContentUnits', + maskUnits: 'maskUnits', + mathematical: 'mathematical', + numOctaves: 'numOctaves', + offset: 'offset', + opacity: 'opacity', + operator: 'operator', + order: 'order', + orient: 'orient', + orientation: 'orientation', + origin: 'origin', + overflow: 'overflow', + overlinePosition: 'overline-position', + overlineThickness: 'overline-thickness', + panose1: 'panose-1', + paintOrder: 'paint-order', + pathLength: 'pathLength', + patternContentUnits: 'patternContentUnits', + patternTransform: 'patternTransform', + patternUnits: 'patternUnits', + pointerEvents: 'pointer-events', + points: 'points', + pointsAtX: 'pointsAtX', + pointsAtY: 'pointsAtY', + pointsAtZ: 'pointsAtZ', + preserveAlpha: 'preserveAlpha', + preserveAspectRatio: 'preserveAspectRatio', + primitiveUnits: 'primitiveUnits', + r: 'r', + radius: 'radius', + refX: 'refX', + refY: 'refY', + rel: 'rel', + renderingIntent: 'rendering-intent', + repeatCount: 'repeatCount', + repeatDur: 'repeatDur', + requiredExtensions: 'requiredExtensions', + requiredFeatures: 'requiredFeatures', + restart: 'restart', + result: 'result', + rotate: 'rotate', + rx: 'rx', + ry: 'ry', + scale: 'scale', + seed: 'seed', + shapeRendering: 'shape-rendering', + slope: 'slope', + spacing: 'spacing', + specularConstant: 'specularConstant', + specularExponent: 'specularExponent', + speed: 'speed', + spreadMethod: 'spreadMethod', + startOffset: 'startOffset', + stdDeviation: 'stdDeviation', + stemh: 'stemh', + stemv: 'stemv', + stitchTiles: 'stitchTiles', + stopColor: 'stop-color', + stopOpacity: 'stop-opacity', + strikethroughPosition: 'strikethrough-position', + strikethroughThickness: 'strikethrough-thickness', + string: 'string', + stroke: 'stroke', + strokeDasharray: 'stroke-dasharray', + strokeDashoffset: 'stroke-dashoffset', + strokeLinecap: 'stroke-linecap', + strokeLinejoin: 'stroke-linejoin', + strokeMiterlimit: 'stroke-miterlimit', + strokeOpacity: 'stroke-opacity', + strokeWidth: 'stroke-width', + surfaceScale: 'surfaceScale', + systemLanguage: 'systemLanguage', + tableValues: 'tableValues', + targetX: 'targetX', + targetY: 'targetY', + textAnchor: 'text-anchor', + textDecoration: 'text-decoration', + textRendering: 'text-rendering', + textLength: 'textLength', + to: 'to', + transform: 'transform', + transformOrigin: 'transform-origin', + u1: 'u1', + u2: 'u2', + underlinePosition: 'underline-position', + underlineThickness: 'underline-thickness', + unicode: 'unicode', + unicodeBidi: 'unicode-bidi', + unicodeRange: 'unicode-range', + unitsPerEm: 'units-per-em', + vAlphabetic: 'v-alphabetic', + vHanging: 'v-hanging', + vIdeographic: 'v-ideographic', + vMathematical: 'v-mathematical', + values: 'values', + vectorEffect: 'vector-effect', + version: 'version', + vertAdvY: 'vert-adv-y', + vertOriginX: 'vert-origin-x', + vertOriginY: 'vert-origin-y', + viewBox: 'viewBox', + viewTarget: 'viewTarget', + visibility: 'visibility', + widths: 'widths', + wordSpacing: 'word-spacing', + writingMode: 'writing-mode', + x: 'x', + xHeight: 'x-height', + x1: 'x1', + x2: 'x2', + xChannelSelector: 'xChannelSelector', + xlinkActuate: 'xlink:actuate', + xlinkArcrole: 'xlink:arcrole', + xlinkHref: 'xlink:href', + xlinkRole: 'xlink:role', + xlinkShow: 'xlink:show', + xlinkTitle: 'xlink:title', + xlinkType: 'xlink:type', + xmlBase: 'xml:base', + xmlLang: 'xml:lang', + xmlSpace: 'xml:space', + y: 'y', + y1: 'y1', + y2: 'y2', + yChannelSelector: 'yChannelSelector', + z: 'z', + zoomAndPan: 'zoomAndPan' + }; + + for (let name in svgAttributes) { + let value = svgAttributes[name]; + + let rendered = prettyRender( + + + + ); + expect(rendered).to.equal( + `\n\t\n` + ); + } + }); + + it('should have correct HTML casing', () => { + let htmlAttributes = { + accept: 'accept', + acceptCharset: 'accept-charset', + accessKey: 'accesskey', + action: 'action', + allow: 'allow', + // allowFullScreen: '', // unsure? + // allowTransparency: '', // unsure? + alt: 'alt', + as: 'as', + async: 'async', + autocomplete: 'autocomplete', + autoComplete: 'autocomplete', + autocorrect: 'autocorrect', + autoCorrect: 'autocorrect', + autofocus: 'autofocus', + autoFocus: 'autofocus', + autoPlay: 'autoplay', + capture: 'capture', + cellPadding: 'cellPadding', + cellSpacing: 'cellSpacing', + charSet: 'charset', + challenge: 'challenge', + checked: 'checked', + cite: 'cite', + class: 'class', + className: 'class', + cols: 'cols', + colSpan: 'colspan', + content: 'content', + contentEditable: 'contenteditable', + contextMenu: 'contextmenu', + controls: 'controls', + coords: 'coords', + crossOrigin: 'crossorigin', + data: 'data', + dateTime: 'datetime', + default: 'default', + defaultChecked: 'checked', + defaultValue: 'value', + defer: 'defer', + dir: 'dir', + disabled: 'disabled', + download: 'download', + decoding: 'decoding', + draggable: 'draggable', + encType: 'enctype', + enterkeyhint: 'enterkeyhint', + for: 'for', + form: 'form', + formAction: 'formaction', + formEncType: 'formenctype', + formMethod: 'formmethod', + formNoValidate: 'formnovalidate', + formTarget: 'formtarget', + frameBorder: 'frameborder', + headers: 'headers', + height: 'height', + hidden: 'hidden', + high: 'high', + href: 'href', + hrefLang: 'hreflang', + htmlFor: 'for', + httpEquiv: 'http-equiv', + icon: 'icon', + id: 'id', + indeterminate: 'indeterminate', + inputMode: 'inputmode', + integrity: 'integrity', + is: 'is', + kind: 'kind', + label: 'label', + lang: 'lang', + list: 'list', + loading: 'loading', + loop: 'loop', + low: 'low', + manifest: 'manifest', + max: 'max', + maxLength: 'maxlength', + media: 'media', + method: 'method', + min: 'min', + minLength: 'minlength', + multiple: 'multiple', + muted: 'muted', + name: 'name', + nomodule: 'nomodule', + nonce: 'nonce', + noValidate: 'novalidate', + open: 'open', + optimum: 'optimum', + part: 'part', + pattern: 'pattern', + ping: 'ping', + placeholder: 'placeholder', + playsInline: 'playsinline', + poster: 'poster', + preload: 'preload', + readonly: 'readonly', + readOnly: 'readonly', + referrerpolicy: 'referrerpolicy', + rel: 'rel', + required: 'required', + reversed: 'reversed', + role: 'role', + rows: 'rows', + rowSpan: 'rowspan', + sandbox: 'sandbox', + scope: 'scope', + scoped: 'scoped', + scrolling: 'scrolling', + seamless: 'seamless', + selected: 'selected', + shape: 'shape', + size: 'size', + sizes: 'sizes', + slot: 'slot', + span: 'span', + spellcheck: 'spellcheck', + spellCheck: 'spellcheck', + src: 'src', + srcset: 'srcset', + srcDoc: 'srcdoc', + srcLang: 'srclang', + srcSet: 'srcset', + start: 'start', + step: 'step', + style: 'style', + summary: 'summary', + tabIndex: 'tabindex', + target: 'target', + title: 'title', + type: 'type', + useMap: 'useMap', + value: 'value', + volume: 'volume', + width: 'width', + wmode: 'wmode', + wrap: 'wrap', + + // Non-standard Attributes + autocapitalize: 'autocapitalize', + autoCapitalize: 'autocapitalize', + results: 'results', + translate: 'translate', + + // RDFa Attributes + about: 'about', + datatype: 'datatype', + inlist: 'inlist', + prefix: 'prefix', + property: 'property', + resource: 'resource', + typeof: 'typeof', + vocab: 'vocab', + + // Microdata Attributes + itemProp: 'itemprop', + itemScope: 'itemscope', + itemType: 'itemtype', + itemID: 'itemid', + itemRef: 'itemref' + }; + + for (let name in htmlAttributes) { + let value = htmlAttributes[name]; + + if (name === 'checked') { + let rendered = prettyRender(, { + jsx: false + }); + expect(rendered).to.equal(``); + continue; + } else { + let rendered = prettyRender(
); + expect(rendered).to.equal(`
`); + } + } + }); + }); }); From bccd1d6b4094a8481282484b0d6ca20677ce2532 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Fri, 4 Aug 2023 12:07:00 +0200 Subject: [PATCH 2/3] Add changeset --- .changeset/plenty-cycles-work.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/plenty-cycles-work.md diff --git a/.changeset/plenty-cycles-work.md b/.changeset/plenty-cycles-work.md new file mode 100644 index 00000000..477347ef --- /dev/null +++ b/.changeset/plenty-cycles-work.md @@ -0,0 +1,5 @@ +--- +"preact-render-to-string": patch +--- + +Apply attribute name handling in pretty mode From 0fe2d130838160ba181fb0b417d904789dcffffa Mon Sep 17 00:00:00 2001 From: Garth Poitras <411908+gpoitch@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:17:20 -0400 Subject: [PATCH 3/3] util attributes --- test/pretty.test.js | 409 +------------------------------------------- test/render.test.js | 408 +------------------------------------------ test/utils.js | 407 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 409 insertions(+), 815 deletions(-) diff --git a/test/pretty.test.js b/test/pretty.test.js index db657e0e..a5812dc2 100644 --- a/test/pretty.test.js +++ b/test/pretty.test.js @@ -2,7 +2,7 @@ import basicRender from '../src/index.js'; import { render } from '../src/jsx.js'; import { h, Fragment } from 'preact'; import { expect } from 'chai'; -import { dedent } from './utils.js'; +import { dedent, svgAttributes, htmlAttributes } from './utils.js'; describe('pretty', () => { let prettyRender = (jsx, opts) => render(jsx, {}, { pretty: true, ...opts }); @@ -217,248 +217,6 @@ describe('pretty', () => { describe('Attribute casing', () => { it('should have correct SVG casing', () => { - const svgAttributes = { - accentHeight: 'accent-height', - accumulate: 'accumulate', - additive: 'additive', - alignmentBaseline: 'alignment-baseline', - allowReorder: 'allowReorder', // unsure - alphabetic: 'alphabetic', - amplitude: 'amplitude', - arabicForm: 'arabic-form', - ascent: 'ascent', - attributeName: 'attributeName', - attributeType: 'attributeType', - autoReverse: 'autoReverse', // unsure - azimuth: 'azimuth', - baseFrequency: 'baseFrequency', - baselineShift: 'baseline-shift', - baseProfile: 'baseProfile', - bbox: 'bbox', - begin: 'begin', - bias: 'bias', - by: 'by', - calcMode: 'calcMode', - capHeight: 'cap-height', - class: 'class', - clip: 'clip', - clipPathUnits: 'clipPathUnits', - clipPath: 'clip-path', - clipRule: 'clip-rule', - color: 'color', - colorInterpolation: 'color-interpolation', - colorInterpolationFilters: 'color-interpolation-filters', - colorProfile: 'color-profile', - colorRendering: 'color-rendering', - contentScriptType: 'contentScriptType', - contentStyleType: 'contentStyleType', - crossorigin: 'crossorigin', - cursor: 'cursor', - cx: 'cx', - cy: 'cy', - d: 'd', - decelerate: 'decelerate', - descent: 'descent', - diffuseConstant: 'diffuseConstant', - direction: 'direction', - display: 'display', - divisor: 'divisor', - dominantBaseline: 'dominant-baseline', - dur: 'dur', - dx: 'dx', - dy: 'dy', - edgeMode: 'edgeMode', - elevation: 'elevation', - enableBackground: 'enable-background', - end: 'end', - exponent: 'exponent', - fill: 'fill', - fillOpacity: 'fill-opacity', - fillRule: 'fill-rule', - filter: 'filter', - filterRes: 'filterRes', - filterUnits: 'filterUnits', - floodColor: 'flood-color', - floodOpacity: 'flood-opacity', - fontFamily: 'font-family', - fontSize: 'font-size', - fontSizeAdjust: 'font-size-adjust', - fontStretch: 'font-stretch', - fontStyle: 'font-style', - fontVariant: 'font-variant', - fontWeight: 'font-weight', - format: 'format', - from: 'from', - fx: 'fx', - fy: 'fy', - g1: 'g1', - g2: 'g2', - glyphName: 'glyph-name', - glyphOrientationHorizontal: 'glyph-orientation-horizontal', - glyphOrientationVertical: 'glyph-orientation-vertical', - glyphRef: 'glyphRef', - gradientTransform: 'gradientTransform', - gradientUnits: 'gradientUnits', - hanging: 'hanging', - horizAdvX: 'horiz-adv-x', - horizOriginX: 'horiz-origin-x', - ideographic: 'ideographic', - imageRendering: 'image-rendering', - in: 'in', - in2: 'in2', - intercept: 'intercept', - k: 'k', - k1: 'k1', - k2: 'k2', - k3: 'k3', - k4: 'k4', - kernelMatrix: 'kernelMatrix', - kernelUnitLength: 'kernelUnitLength', - kerning: 'kerning', - keyPoints: 'keyPoints', - keySplines: 'keySplines', - keyTimes: 'keyTimes', - lengthAdjust: 'lengthAdjust', - letterSpacing: 'letter-spacing', - lightingColor: 'lighting-color', - limitingConeAngle: 'limitingConeAngle', - local: 'local', - markerEnd: 'marker-end', - markerMid: 'marker-mid', - markerStart: 'marker-start', - markerHeight: 'markerHeight', - markerUnits: 'markerUnits', - markerWidth: 'markerWidth', - mask: 'mask', - maskContentUnits: 'maskContentUnits', - maskUnits: 'maskUnits', - mathematical: 'mathematical', - numOctaves: 'numOctaves', - offset: 'offset', - opacity: 'opacity', - operator: 'operator', - order: 'order', - orient: 'orient', - orientation: 'orientation', - origin: 'origin', - overflow: 'overflow', - overlinePosition: 'overline-position', - overlineThickness: 'overline-thickness', - panose1: 'panose-1', - paintOrder: 'paint-order', - pathLength: 'pathLength', - patternContentUnits: 'patternContentUnits', - patternTransform: 'patternTransform', - patternUnits: 'patternUnits', - pointerEvents: 'pointer-events', - points: 'points', - pointsAtX: 'pointsAtX', - pointsAtY: 'pointsAtY', - pointsAtZ: 'pointsAtZ', - preserveAlpha: 'preserveAlpha', - preserveAspectRatio: 'preserveAspectRatio', - primitiveUnits: 'primitiveUnits', - r: 'r', - radius: 'radius', - refX: 'refX', - refY: 'refY', - rel: 'rel', - renderingIntent: 'rendering-intent', - repeatCount: 'repeatCount', - repeatDur: 'repeatDur', - requiredExtensions: 'requiredExtensions', - requiredFeatures: 'requiredFeatures', - restart: 'restart', - result: 'result', - rotate: 'rotate', - rx: 'rx', - ry: 'ry', - scale: 'scale', - seed: 'seed', - shapeRendering: 'shape-rendering', - slope: 'slope', - spacing: 'spacing', - specularConstant: 'specularConstant', - specularExponent: 'specularExponent', - speed: 'speed', - spreadMethod: 'spreadMethod', - startOffset: 'startOffset', - stdDeviation: 'stdDeviation', - stemh: 'stemh', - stemv: 'stemv', - stitchTiles: 'stitchTiles', - stopColor: 'stop-color', - stopOpacity: 'stop-opacity', - strikethroughPosition: 'strikethrough-position', - strikethroughThickness: 'strikethrough-thickness', - string: 'string', - stroke: 'stroke', - strokeDasharray: 'stroke-dasharray', - strokeDashoffset: 'stroke-dashoffset', - strokeLinecap: 'stroke-linecap', - strokeLinejoin: 'stroke-linejoin', - strokeMiterlimit: 'stroke-miterlimit', - strokeOpacity: 'stroke-opacity', - strokeWidth: 'stroke-width', - surfaceScale: 'surfaceScale', - systemLanguage: 'systemLanguage', - tableValues: 'tableValues', - targetX: 'targetX', - targetY: 'targetY', - textAnchor: 'text-anchor', - textDecoration: 'text-decoration', - textRendering: 'text-rendering', - textLength: 'textLength', - to: 'to', - transform: 'transform', - transformOrigin: 'transform-origin', - u1: 'u1', - u2: 'u2', - underlinePosition: 'underline-position', - underlineThickness: 'underline-thickness', - unicode: 'unicode', - unicodeBidi: 'unicode-bidi', - unicodeRange: 'unicode-range', - unitsPerEm: 'units-per-em', - vAlphabetic: 'v-alphabetic', - vHanging: 'v-hanging', - vIdeographic: 'v-ideographic', - vMathematical: 'v-mathematical', - values: 'values', - vectorEffect: 'vector-effect', - version: 'version', - vertAdvY: 'vert-adv-y', - vertOriginX: 'vert-origin-x', - vertOriginY: 'vert-origin-y', - viewBox: 'viewBox', - viewTarget: 'viewTarget', - visibility: 'visibility', - widths: 'widths', - wordSpacing: 'word-spacing', - writingMode: 'writing-mode', - x: 'x', - xHeight: 'x-height', - x1: 'x1', - x2: 'x2', - xChannelSelector: 'xChannelSelector', - xlinkActuate: 'xlink:actuate', - xlinkArcrole: 'xlink:arcrole', - xlinkHref: 'xlink:href', - xlinkRole: 'xlink:role', - xlinkShow: 'xlink:show', - xlinkTitle: 'xlink:title', - xlinkType: 'xlink:type', - xmlBase: 'xml:base', - xmlLang: 'xml:lang', - xmlSpace: 'xml:space', - y: 'y', - y1: 'y1', - y2: 'y2', - yChannelSelector: 'yChannelSelector', - z: 'z', - zoomAndPan: 'zoomAndPan' - }; - for (let name in svgAttributes) { let value = svgAttributes[name]; @@ -474,171 +232,6 @@ describe('pretty', () => { }); it('should have correct HTML casing', () => { - let htmlAttributes = { - accept: 'accept', - acceptCharset: 'accept-charset', - accessKey: 'accesskey', - action: 'action', - allow: 'allow', - // allowFullScreen: '', // unsure? - // allowTransparency: '', // unsure? - alt: 'alt', - as: 'as', - async: 'async', - autocomplete: 'autocomplete', - autoComplete: 'autocomplete', - autocorrect: 'autocorrect', - autoCorrect: 'autocorrect', - autofocus: 'autofocus', - autoFocus: 'autofocus', - autoPlay: 'autoplay', - capture: 'capture', - cellPadding: 'cellPadding', - cellSpacing: 'cellSpacing', - charSet: 'charset', - challenge: 'challenge', - checked: 'checked', - cite: 'cite', - class: 'class', - className: 'class', - cols: 'cols', - colSpan: 'colspan', - content: 'content', - contentEditable: 'contenteditable', - contextMenu: 'contextmenu', - controls: 'controls', - coords: 'coords', - crossOrigin: 'crossorigin', - data: 'data', - dateTime: 'datetime', - default: 'default', - defaultChecked: 'checked', - defaultValue: 'value', - defer: 'defer', - dir: 'dir', - disabled: 'disabled', - download: 'download', - decoding: 'decoding', - draggable: 'draggable', - encType: 'enctype', - enterkeyhint: 'enterkeyhint', - for: 'for', - form: 'form', - formAction: 'formaction', - formEncType: 'formenctype', - formMethod: 'formmethod', - formNoValidate: 'formnovalidate', - formTarget: 'formtarget', - frameBorder: 'frameborder', - headers: 'headers', - height: 'height', - hidden: 'hidden', - high: 'high', - href: 'href', - hrefLang: 'hreflang', - htmlFor: 'for', - httpEquiv: 'http-equiv', - icon: 'icon', - id: 'id', - indeterminate: 'indeterminate', - inputMode: 'inputmode', - integrity: 'integrity', - is: 'is', - kind: 'kind', - label: 'label', - lang: 'lang', - list: 'list', - loading: 'loading', - loop: 'loop', - low: 'low', - manifest: 'manifest', - max: 'max', - maxLength: 'maxlength', - media: 'media', - method: 'method', - min: 'min', - minLength: 'minlength', - multiple: 'multiple', - muted: 'muted', - name: 'name', - nomodule: 'nomodule', - nonce: 'nonce', - noValidate: 'novalidate', - open: 'open', - optimum: 'optimum', - part: 'part', - pattern: 'pattern', - ping: 'ping', - placeholder: 'placeholder', - playsInline: 'playsinline', - poster: 'poster', - preload: 'preload', - readonly: 'readonly', - readOnly: 'readonly', - referrerpolicy: 'referrerpolicy', - rel: 'rel', - required: 'required', - reversed: 'reversed', - role: 'role', - rows: 'rows', - rowSpan: 'rowspan', - sandbox: 'sandbox', - scope: 'scope', - scoped: 'scoped', - scrolling: 'scrolling', - seamless: 'seamless', - selected: 'selected', - shape: 'shape', - size: 'size', - sizes: 'sizes', - slot: 'slot', - span: 'span', - spellcheck: 'spellcheck', - spellCheck: 'spellcheck', - src: 'src', - srcset: 'srcset', - srcDoc: 'srcdoc', - srcLang: 'srclang', - srcSet: 'srcset', - start: 'start', - step: 'step', - style: 'style', - summary: 'summary', - tabIndex: 'tabindex', - target: 'target', - title: 'title', - type: 'type', - useMap: 'useMap', - value: 'value', - volume: 'volume', - width: 'width', - wmode: 'wmode', - wrap: 'wrap', - - // Non-standard Attributes - autocapitalize: 'autocapitalize', - autoCapitalize: 'autocapitalize', - results: 'results', - translate: 'translate', - - // RDFa Attributes - about: 'about', - datatype: 'datatype', - inlist: 'inlist', - prefix: 'prefix', - property: 'property', - resource: 'resource', - typeof: 'typeof', - vocab: 'vocab', - - // Microdata Attributes - itemProp: 'itemprop', - itemScope: 'itemscope', - itemType: 'itemtype', - itemID: 'itemid', - itemRef: 'itemref' - }; - for (let name in htmlAttributes) { let value = htmlAttributes[name]; diff --git a/test/render.test.js b/test/render.test.js index 9d00a0ca..e6b6fe1c 100644 --- a/test/render.test.js +++ b/test/render.test.js @@ -19,6 +19,7 @@ import { } from 'preact/hooks'; import { expect } from 'chai'; import { spy, stub, match } from 'sinon'; +import { svgAttributes, htmlAttributes } from './utils.js'; function shallowRender(vnode) { return renderToStringJSX(vnode, context, { @@ -1601,248 +1602,6 @@ describe('render', () => { describe('Attribute casing', () => { it('should have correct SVG casing', () => { - const svgAttributes = { - accentHeight: 'accent-height', - accumulate: 'accumulate', - additive: 'additive', - alignmentBaseline: 'alignment-baseline', - allowReorder: 'allowReorder', // unsure - alphabetic: 'alphabetic', - amplitude: 'amplitude', - arabicForm: 'arabic-form', - ascent: 'ascent', - attributeName: 'attributeName', - attributeType: 'attributeType', - autoReverse: 'autoReverse', // unsure - azimuth: 'azimuth', - baseFrequency: 'baseFrequency', - baselineShift: 'baseline-shift', - baseProfile: 'baseProfile', - bbox: 'bbox', - begin: 'begin', - bias: 'bias', - by: 'by', - calcMode: 'calcMode', - capHeight: 'cap-height', - class: 'class', - clip: 'clip', - clipPathUnits: 'clipPathUnits', - clipPath: 'clip-path', - clipRule: 'clip-rule', - color: 'color', - colorInterpolation: 'color-interpolation', - colorInterpolationFilters: 'color-interpolation-filters', - colorProfile: 'color-profile', - colorRendering: 'color-rendering', - contentScriptType: 'contentScriptType', - contentStyleType: 'contentStyleType', - crossorigin: 'crossorigin', - cursor: 'cursor', - cx: 'cx', - cy: 'cy', - d: 'd', - decelerate: 'decelerate', - descent: 'descent', - diffuseConstant: 'diffuseConstant', - direction: 'direction', - display: 'display', - divisor: 'divisor', - dominantBaseline: 'dominant-baseline', - dur: 'dur', - dx: 'dx', - dy: 'dy', - edgeMode: 'edgeMode', - elevation: 'elevation', - enableBackground: 'enable-background', - end: 'end', - exponent: 'exponent', - fill: 'fill', - fillOpacity: 'fill-opacity', - fillRule: 'fill-rule', - filter: 'filter', - filterRes: 'filterRes', - filterUnits: 'filterUnits', - floodColor: 'flood-color', - floodOpacity: 'flood-opacity', - fontFamily: 'font-family', - fontSize: 'font-size', - fontSizeAdjust: 'font-size-adjust', - fontStretch: 'font-stretch', - fontStyle: 'font-style', - fontVariant: 'font-variant', - fontWeight: 'font-weight', - format: 'format', - from: 'from', - fx: 'fx', - fy: 'fy', - g1: 'g1', - g2: 'g2', - glyphName: 'glyph-name', - glyphOrientationHorizontal: 'glyph-orientation-horizontal', - glyphOrientationVertical: 'glyph-orientation-vertical', - glyphRef: 'glyphRef', - gradientTransform: 'gradientTransform', - gradientUnits: 'gradientUnits', - hanging: 'hanging', - horizAdvX: 'horiz-adv-x', - horizOriginX: 'horiz-origin-x', - ideographic: 'ideographic', - imageRendering: 'image-rendering', - in: 'in', - in2: 'in2', - intercept: 'intercept', - k: 'k', - k1: 'k1', - k2: 'k2', - k3: 'k3', - k4: 'k4', - kernelMatrix: 'kernelMatrix', - kernelUnitLength: 'kernelUnitLength', - kerning: 'kerning', - keyPoints: 'keyPoints', - keySplines: 'keySplines', - keyTimes: 'keyTimes', - lengthAdjust: 'lengthAdjust', - letterSpacing: 'letter-spacing', - lightingColor: 'lighting-color', - limitingConeAngle: 'limitingConeAngle', - local: 'local', - markerEnd: 'marker-end', - markerMid: 'marker-mid', - markerStart: 'marker-start', - markerHeight: 'markerHeight', - markerUnits: 'markerUnits', - markerWidth: 'markerWidth', - mask: 'mask', - maskContentUnits: 'maskContentUnits', - maskUnits: 'maskUnits', - mathematical: 'mathematical', - numOctaves: 'numOctaves', - offset: 'offset', - opacity: 'opacity', - operator: 'operator', - order: 'order', - orient: 'orient', - orientation: 'orientation', - origin: 'origin', - overflow: 'overflow', - overlinePosition: 'overline-position', - overlineThickness: 'overline-thickness', - panose1: 'panose-1', - paintOrder: 'paint-order', - pathLength: 'pathLength', - patternContentUnits: 'patternContentUnits', - patternTransform: 'patternTransform', - patternUnits: 'patternUnits', - pointerEvents: 'pointer-events', - points: 'points', - pointsAtX: 'pointsAtX', - pointsAtY: 'pointsAtY', - pointsAtZ: 'pointsAtZ', - preserveAlpha: 'preserveAlpha', - preserveAspectRatio: 'preserveAspectRatio', - primitiveUnits: 'primitiveUnits', - r: 'r', - radius: 'radius', - refX: 'refX', - refY: 'refY', - rel: 'rel', - renderingIntent: 'rendering-intent', - repeatCount: 'repeatCount', - repeatDur: 'repeatDur', - requiredExtensions: 'requiredExtensions', - requiredFeatures: 'requiredFeatures', - restart: 'restart', - result: 'result', - rotate: 'rotate', - rx: 'rx', - ry: 'ry', - scale: 'scale', - seed: 'seed', - shapeRendering: 'shape-rendering', - slope: 'slope', - spacing: 'spacing', - specularConstant: 'specularConstant', - specularExponent: 'specularExponent', - speed: 'speed', - spreadMethod: 'spreadMethod', - startOffset: 'startOffset', - stdDeviation: 'stdDeviation', - stemh: 'stemh', - stemv: 'stemv', - stitchTiles: 'stitchTiles', - stopColor: 'stop-color', - stopOpacity: 'stop-opacity', - strikethroughPosition: 'strikethrough-position', - strikethroughThickness: 'strikethrough-thickness', - string: 'string', - stroke: 'stroke', - strokeDasharray: 'stroke-dasharray', - strokeDashoffset: 'stroke-dashoffset', - strokeLinecap: 'stroke-linecap', - strokeLinejoin: 'stroke-linejoin', - strokeMiterlimit: 'stroke-miterlimit', - strokeOpacity: 'stroke-opacity', - strokeWidth: 'stroke-width', - surfaceScale: 'surfaceScale', - systemLanguage: 'systemLanguage', - tableValues: 'tableValues', - targetX: 'targetX', - targetY: 'targetY', - textAnchor: 'text-anchor', - textDecoration: 'text-decoration', - textRendering: 'text-rendering', - textLength: 'textLength', - to: 'to', - transform: 'transform', - transformOrigin: 'transform-origin', - u1: 'u1', - u2: 'u2', - underlinePosition: 'underline-position', - underlineThickness: 'underline-thickness', - unicode: 'unicode', - unicodeBidi: 'unicode-bidi', - unicodeRange: 'unicode-range', - unitsPerEm: 'units-per-em', - vAlphabetic: 'v-alphabetic', - vHanging: 'v-hanging', - vIdeographic: 'v-ideographic', - vMathematical: 'v-mathematical', - values: 'values', - vectorEffect: 'vector-effect', - version: 'version', - vertAdvY: 'vert-adv-y', - vertOriginX: 'vert-origin-x', - vertOriginY: 'vert-origin-y', - viewBox: 'viewBox', - viewTarget: 'viewTarget', - visibility: 'visibility', - widths: 'widths', - wordSpacing: 'word-spacing', - writingMode: 'writing-mode', - x: 'x', - xHeight: 'x-height', - x1: 'x1', - x2: 'x2', - xChannelSelector: 'xChannelSelector', - xlinkActuate: 'xlink:actuate', - xlinkArcrole: 'xlink:arcrole', - xlinkHref: 'xlink:href', - xlinkRole: 'xlink:role', - xlinkShow: 'xlink:show', - xlinkTitle: 'xlink:title', - xlinkType: 'xlink:type', - xmlBase: 'xml:base', - xmlLang: 'xml:lang', - xmlSpace: 'xml:space', - y: 'y', - y1: 'y1', - y2: 'y2', - yChannelSelector: 'yChannelSelector', - z: 'z', - zoomAndPan: 'zoomAndPan' - }; - for (let name in svgAttributes) { let value = svgAttributes[name]; @@ -1871,171 +1630,6 @@ describe('render', () => { }); it('should have correct HTML casing', () => { - let htmlAttributes = { - accept: 'accept', - acceptCharset: 'accept-charset', - accessKey: 'accesskey', - action: 'action', - allow: 'allow', - // allowFullScreen: '', // unsure? - // allowTransparency: '', // unsure? - alt: 'alt', - as: 'as', - async: 'async', - autocomplete: 'autocomplete', - autoComplete: 'autocomplete', - autocorrect: 'autocorrect', - autoCorrect: 'autocorrect', - autofocus: 'autofocus', - autoFocus: 'autofocus', - autoPlay: 'autoplay', - capture: 'capture', - cellPadding: 'cellPadding', - cellSpacing: 'cellSpacing', - charSet: 'charset', - challenge: 'challenge', - checked: 'checked', - cite: 'cite', - class: 'class', - className: 'class', - cols: 'cols', - colSpan: 'colspan', - content: 'content', - contentEditable: 'contenteditable', - contextMenu: 'contextmenu', - controls: 'controls', - coords: 'coords', - crossOrigin: 'crossorigin', - data: 'data', - dateTime: 'datetime', - default: 'default', - defaultChecked: 'checked', - defaultValue: 'value', - defer: 'defer', - dir: 'dir', - disabled: 'disabled', - download: 'download', - decoding: 'decoding', - draggable: 'draggable', - encType: 'enctype', - enterkeyhint: 'enterkeyhint', - for: 'for', - form: 'form', - formAction: 'formaction', - formEncType: 'formenctype', - formMethod: 'formmethod', - formNoValidate: 'formnovalidate', - formTarget: 'formtarget', - frameBorder: 'frameborder', - headers: 'headers', - height: 'height', - hidden: 'hidden', - high: 'high', - href: 'href', - hrefLang: 'hreflang', - htmlFor: 'for', - httpEquiv: 'http-equiv', - icon: 'icon', - id: 'id', - indeterminate: 'indeterminate', - inputMode: 'inputmode', - integrity: 'integrity', - is: 'is', - kind: 'kind', - label: 'label', - lang: 'lang', - list: 'list', - loading: 'loading', - loop: 'loop', - low: 'low', - manifest: 'manifest', - max: 'max', - maxLength: 'maxlength', - media: 'media', - method: 'method', - min: 'min', - minLength: 'minlength', - multiple: 'multiple', - muted: 'muted', - name: 'name', - nomodule: 'nomodule', - nonce: 'nonce', - noValidate: 'novalidate', - open: 'open', - optimum: 'optimum', - part: 'part', - pattern: 'pattern', - ping: 'ping', - placeholder: 'placeholder', - playsInline: 'playsinline', - poster: 'poster', - preload: 'preload', - readonly: 'readonly', - readOnly: 'readonly', - referrerpolicy: 'referrerpolicy', - rel: 'rel', - required: 'required', - reversed: 'reversed', - role: 'role', - rows: 'rows', - rowSpan: 'rowspan', - sandbox: 'sandbox', - scope: 'scope', - scoped: 'scoped', - scrolling: 'scrolling', - seamless: 'seamless', - selected: 'selected', - shape: 'shape', - size: 'size', - sizes: 'sizes', - slot: 'slot', - span: 'span', - spellcheck: 'spellcheck', - spellCheck: 'spellcheck', - src: 'src', - srcset: 'srcset', - srcDoc: 'srcdoc', - srcLang: 'srclang', - srcSet: 'srcset', - start: 'start', - step: 'step', - style: 'style', - summary: 'summary', - tabIndex: 'tabindex', - target: 'target', - title: 'title', - type: 'type', - useMap: 'useMap', - value: 'value', - volume: 'volume', - width: 'width', - wmode: 'wmode', - wrap: 'wrap', - - // Non-standard Attributes - autocapitalize: 'autocapitalize', - autoCapitalize: 'autocapitalize', - results: 'results', - translate: 'translate', - - // RDFa Attributes - about: 'about', - datatype: 'datatype', - inlist: 'inlist', - prefix: 'prefix', - property: 'property', - resource: 'resource', - typeof: 'typeof', - vocab: 'vocab', - - // Microdata Attributes - itemProp: 'itemprop', - itemScope: 'itemscope', - itemType: 'itemtype', - itemID: 'itemid', - itemRef: 'itemref' - }; - for (let name in htmlAttributes) { let value = htmlAttributes[name]; diff --git a/test/utils.js b/test/utils.js index abb3418a..4c2b5d2d 100644 --- a/test/utils.js +++ b/test/utils.js @@ -10,3 +10,410 @@ export function dedent([str]) { .join('\n') .replace(/(^\n+|\n+\s*$)/g, ''); } + +export const svgAttributes = { + accentHeight: 'accent-height', + accumulate: 'accumulate', + additive: 'additive', + alignmentBaseline: 'alignment-baseline', + allowReorder: 'allowReorder', // unsure + alphabetic: 'alphabetic', + amplitude: 'amplitude', + arabicForm: 'arabic-form', + ascent: 'ascent', + attributeName: 'attributeName', + attributeType: 'attributeType', + autoReverse: 'autoReverse', // unsure + azimuth: 'azimuth', + baseFrequency: 'baseFrequency', + baselineShift: 'baseline-shift', + baseProfile: 'baseProfile', + bbox: 'bbox', + begin: 'begin', + bias: 'bias', + by: 'by', + calcMode: 'calcMode', + capHeight: 'cap-height', + class: 'class', + clip: 'clip', + clipPathUnits: 'clipPathUnits', + clipPath: 'clip-path', + clipRule: 'clip-rule', + color: 'color', + colorInterpolation: 'color-interpolation', + colorInterpolationFilters: 'color-interpolation-filters', + colorProfile: 'color-profile', + colorRendering: 'color-rendering', + contentScriptType: 'contentScriptType', + contentStyleType: 'contentStyleType', + crossorigin: 'crossorigin', + cursor: 'cursor', + cx: 'cx', + cy: 'cy', + d: 'd', + decelerate: 'decelerate', + descent: 'descent', + diffuseConstant: 'diffuseConstant', + direction: 'direction', + display: 'display', + divisor: 'divisor', + dominantBaseline: 'dominant-baseline', + dur: 'dur', + dx: 'dx', + dy: 'dy', + edgeMode: 'edgeMode', + elevation: 'elevation', + enableBackground: 'enable-background', + end: 'end', + exponent: 'exponent', + fill: 'fill', + fillOpacity: 'fill-opacity', + fillRule: 'fill-rule', + filter: 'filter', + filterRes: 'filterRes', + filterUnits: 'filterUnits', + floodColor: 'flood-color', + floodOpacity: 'flood-opacity', + fontFamily: 'font-family', + fontSize: 'font-size', + fontSizeAdjust: 'font-size-adjust', + fontStretch: 'font-stretch', + fontStyle: 'font-style', + fontVariant: 'font-variant', + fontWeight: 'font-weight', + format: 'format', + from: 'from', + fx: 'fx', + fy: 'fy', + g1: 'g1', + g2: 'g2', + glyphName: 'glyph-name', + glyphOrientationHorizontal: 'glyph-orientation-horizontal', + glyphOrientationVertical: 'glyph-orientation-vertical', + glyphRef: 'glyphRef', + gradientTransform: 'gradientTransform', + gradientUnits: 'gradientUnits', + hanging: 'hanging', + horizAdvX: 'horiz-adv-x', + horizOriginX: 'horiz-origin-x', + ideographic: 'ideographic', + imageRendering: 'image-rendering', + in: 'in', + in2: 'in2', + intercept: 'intercept', + k: 'k', + k1: 'k1', + k2: 'k2', + k3: 'k3', + k4: 'k4', + kernelMatrix: 'kernelMatrix', + kernelUnitLength: 'kernelUnitLength', + kerning: 'kerning', + keyPoints: 'keyPoints', + keySplines: 'keySplines', + keyTimes: 'keyTimes', + lengthAdjust: 'lengthAdjust', + letterSpacing: 'letter-spacing', + lightingColor: 'lighting-color', + limitingConeAngle: 'limitingConeAngle', + local: 'local', + markerEnd: 'marker-end', + markerMid: 'marker-mid', + markerStart: 'marker-start', + markerHeight: 'markerHeight', + markerUnits: 'markerUnits', + markerWidth: 'markerWidth', + mask: 'mask', + maskContentUnits: 'maskContentUnits', + maskUnits: 'maskUnits', + mathematical: 'mathematical', + numOctaves: 'numOctaves', + offset: 'offset', + opacity: 'opacity', + operator: 'operator', + order: 'order', + orient: 'orient', + orientation: 'orientation', + origin: 'origin', + overflow: 'overflow', + overlinePosition: 'overline-position', + overlineThickness: 'overline-thickness', + panose1: 'panose-1', + paintOrder: 'paint-order', + pathLength: 'pathLength', + patternContentUnits: 'patternContentUnits', + patternTransform: 'patternTransform', + patternUnits: 'patternUnits', + pointerEvents: 'pointer-events', + points: 'points', + pointsAtX: 'pointsAtX', + pointsAtY: 'pointsAtY', + pointsAtZ: 'pointsAtZ', + preserveAlpha: 'preserveAlpha', + preserveAspectRatio: 'preserveAspectRatio', + primitiveUnits: 'primitiveUnits', + r: 'r', + radius: 'radius', + refX: 'refX', + refY: 'refY', + rel: 'rel', + renderingIntent: 'rendering-intent', + repeatCount: 'repeatCount', + repeatDur: 'repeatDur', + requiredExtensions: 'requiredExtensions', + requiredFeatures: 'requiredFeatures', + restart: 'restart', + result: 'result', + rotate: 'rotate', + rx: 'rx', + ry: 'ry', + scale: 'scale', + seed: 'seed', + shapeRendering: 'shape-rendering', + slope: 'slope', + spacing: 'spacing', + specularConstant: 'specularConstant', + specularExponent: 'specularExponent', + speed: 'speed', + spreadMethod: 'spreadMethod', + startOffset: 'startOffset', + stdDeviation: 'stdDeviation', + stemh: 'stemh', + stemv: 'stemv', + stitchTiles: 'stitchTiles', + stopColor: 'stop-color', + stopOpacity: 'stop-opacity', + strikethroughPosition: 'strikethrough-position', + strikethroughThickness: 'strikethrough-thickness', + string: 'string', + stroke: 'stroke', + strokeDasharray: 'stroke-dasharray', + strokeDashoffset: 'stroke-dashoffset', + strokeLinecap: 'stroke-linecap', + strokeLinejoin: 'stroke-linejoin', + strokeMiterlimit: 'stroke-miterlimit', + strokeOpacity: 'stroke-opacity', + strokeWidth: 'stroke-width', + surfaceScale: 'surfaceScale', + systemLanguage: 'systemLanguage', + tableValues: 'tableValues', + targetX: 'targetX', + targetY: 'targetY', + textAnchor: 'text-anchor', + textDecoration: 'text-decoration', + textRendering: 'text-rendering', + textLength: 'textLength', + to: 'to', + transform: 'transform', + transformOrigin: 'transform-origin', + u1: 'u1', + u2: 'u2', + underlinePosition: 'underline-position', + underlineThickness: 'underline-thickness', + unicode: 'unicode', + unicodeBidi: 'unicode-bidi', + unicodeRange: 'unicode-range', + unitsPerEm: 'units-per-em', + vAlphabetic: 'v-alphabetic', + vHanging: 'v-hanging', + vIdeographic: 'v-ideographic', + vMathematical: 'v-mathematical', + values: 'values', + vectorEffect: 'vector-effect', + version: 'version', + vertAdvY: 'vert-adv-y', + vertOriginX: 'vert-origin-x', + vertOriginY: 'vert-origin-y', + viewBox: 'viewBox', + viewTarget: 'viewTarget', + visibility: 'visibility', + widths: 'widths', + wordSpacing: 'word-spacing', + writingMode: 'writing-mode', + x: 'x', + xHeight: 'x-height', + x1: 'x1', + x2: 'x2', + xChannelSelector: 'xChannelSelector', + xlinkActuate: 'xlink:actuate', + xlinkArcrole: 'xlink:arcrole', + xlinkHref: 'xlink:href', + xlinkRole: 'xlink:role', + xlinkShow: 'xlink:show', + xlinkTitle: 'xlink:title', + xlinkType: 'xlink:type', + xmlBase: 'xml:base', + xmlLang: 'xml:lang', + xmlSpace: 'xml:space', + y: 'y', + y1: 'y1', + y2: 'y2', + yChannelSelector: 'yChannelSelector', + z: 'z', + zoomAndPan: 'zoomAndPan' +}; + +export const htmlAttributes = { + accept: 'accept', + acceptCharset: 'accept-charset', + accessKey: 'accesskey', + action: 'action', + allow: 'allow', + // allowFullScreen: '', // unsure? + // allowTransparency: '', // unsure? + alt: 'alt', + as: 'as', + async: 'async', + autocomplete: 'autocomplete', + autoComplete: 'autocomplete', + autocorrect: 'autocorrect', + autoCorrect: 'autocorrect', + autofocus: 'autofocus', + autoFocus: 'autofocus', + autoPlay: 'autoplay', + capture: 'capture', + cellPadding: 'cellPadding', + cellSpacing: 'cellSpacing', + charSet: 'charset', + challenge: 'challenge', + checked: 'checked', + cite: 'cite', + class: 'class', + className: 'class', + cols: 'cols', + colSpan: 'colspan', + content: 'content', + contentEditable: 'contenteditable', + contextMenu: 'contextmenu', + controls: 'controls', + coords: 'coords', + crossOrigin: 'crossorigin', + data: 'data', + dateTime: 'datetime', + default: 'default', + defaultChecked: 'checked', + defaultValue: 'value', + defer: 'defer', + dir: 'dir', + disabled: 'disabled', + download: 'download', + decoding: 'decoding', + draggable: 'draggable', + encType: 'enctype', + enterkeyhint: 'enterkeyhint', + for: 'for', + form: 'form', + formAction: 'formaction', + formEncType: 'formenctype', + formMethod: 'formmethod', + formNoValidate: 'formnovalidate', + formTarget: 'formtarget', + frameBorder: 'frameborder', + headers: 'headers', + height: 'height', + hidden: 'hidden', + high: 'high', + href: 'href', + hrefLang: 'hreflang', + htmlFor: 'for', + httpEquiv: 'http-equiv', + icon: 'icon', + id: 'id', + indeterminate: 'indeterminate', + inputMode: 'inputmode', + integrity: 'integrity', + is: 'is', + kind: 'kind', + label: 'label', + lang: 'lang', + list: 'list', + loading: 'loading', + loop: 'loop', + low: 'low', + manifest: 'manifest', + max: 'max', + maxLength: 'maxlength', + media: 'media', + method: 'method', + min: 'min', + minLength: 'minlength', + multiple: 'multiple', + muted: 'muted', + name: 'name', + nomodule: 'nomodule', + nonce: 'nonce', + noValidate: 'novalidate', + open: 'open', + optimum: 'optimum', + part: 'part', + pattern: 'pattern', + ping: 'ping', + placeholder: 'placeholder', + playsInline: 'playsinline', + poster: 'poster', + preload: 'preload', + readonly: 'readonly', + readOnly: 'readonly', + referrerpolicy: 'referrerpolicy', + rel: 'rel', + required: 'required', + reversed: 'reversed', + role: 'role', + rows: 'rows', + rowSpan: 'rowspan', + sandbox: 'sandbox', + scope: 'scope', + scoped: 'scoped', + scrolling: 'scrolling', + seamless: 'seamless', + selected: 'selected', + shape: 'shape', + size: 'size', + sizes: 'sizes', + slot: 'slot', + span: 'span', + spellcheck: 'spellcheck', + spellCheck: 'spellcheck', + src: 'src', + srcset: 'srcset', + srcDoc: 'srcdoc', + srcLang: 'srclang', + srcSet: 'srcset', + start: 'start', + step: 'step', + style: 'style', + summary: 'summary', + tabIndex: 'tabindex', + target: 'target', + title: 'title', + type: 'type', + useMap: 'useMap', + value: 'value', + volume: 'volume', + width: 'width', + wmode: 'wmode', + wrap: 'wrap', + + // Non-standard Attributes + autocapitalize: 'autocapitalize', + autoCapitalize: 'autocapitalize', + results: 'results', + translate: 'translate', + + // RDFa Attributes + about: 'about', + datatype: 'datatype', + inlist: 'inlist', + prefix: 'prefix', + property: 'property', + resource: 'resource', + typeof: 'typeof', + vocab: 'vocab', + + // Microdata Attributes + itemProp: 'itemprop', + itemScope: 'itemscope', + itemType: 'itemtype', + itemID: 'itemid', + itemRef: 'itemref' +};