From 94da32930523583103eafaa02cc0cbc04f1ea814 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Wed, 24 Jan 2018 17:43:51 -0500 Subject: [PATCH] another stab at #1062; also fix attribute case in static HTML --- src/generators/nodes/Attribute.ts | 14 ++------------ src/generators/nodes/Element.ts | 3 ++- src/utils/fixAttributeCasing.ts | 12 ++++++++++++ test/runtime/samples/attribute-casing/_config.js | 14 ++++++++++---- test/runtime/samples/attribute-casing/main.html | 8 ++++++-- 5 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 src/utils/fixAttributeCasing.ts diff --git a/src/generators/nodes/Attribute.ts b/src/generators/nodes/Attribute.ts index fe36ac7718..01b62d23da 100644 --- a/src/generators/nodes/Attribute.ts +++ b/src/generators/nodes/Attribute.ts @@ -1,5 +1,6 @@ import deindent from '../../utils/deindent'; import { stringify } from '../../utils/stringify'; +import fixAttributeCasing from '../../utils/fixAttributeCasing'; import getExpressionPrecedence from '../../utils/getExpressionPrecedence'; import { DomGenerator } from '../dom/index'; import Node from './shared/Node'; @@ -43,7 +44,7 @@ export default class Attribute { render(block: Block) { const node = this.parent; - const name = fixCasing(this.name); + const name = fixAttributeCasing(this.name); if (name === 'style') { const styleProps = optimizeStyle(this.value); @@ -663,14 +664,3 @@ function getStyleValue(chunks: Node[]) { function isDynamic(value: Node[]) { return value.length > 1 || value[0].type !== 'Text'; } - -const svgAttributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' '); -const svgAttributeLookup = new Map(); -svgAttributes.forEach(name => { - svgAttributeLookup.set(name.toLowerCase(), name); -}); - -function fixCasing(name) { - if (svgAttributeLookup.has(name)) return svgAttributeLookup.get(name); - return name.toLowerCase(); -} \ No newline at end of file diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index ab9c5b8dc4..d2b8ba658b 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -4,6 +4,7 @@ import flattenReference from '../../utils/flattenReference'; import isVoidElementName from '../../utils/isVoidElementName'; import validCalleeObjects from '../../utils/validCalleeObjects'; import reservedNames from '../../utils/reservedNames'; +import fixAttributeCasing from '../../utils/fixAttributeCasing'; import Node from './shared/Node'; import Block from '../dom/Block'; import Attribute from './Attribute'; @@ -427,7 +428,7 @@ export default class Element extends Node { } node.attributes.forEach((attr: Node) => { - open += ` ${attr.name}${stringifyAttributeValue(attr.value)}` + open += ` ${fixAttributeCasing(attr.name)}${stringifyAttributeValue(attr.value)}` }); if (isVoidElementName(node.name)) return open + '>'; diff --git a/src/utils/fixAttributeCasing.ts b/src/utils/fixAttributeCasing.ts new file mode 100644 index 0000000000..bcd7f50edd --- /dev/null +++ b/src/utils/fixAttributeCasing.ts @@ -0,0 +1,12 @@ +const svgAttributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' '); + +const svgAttributeLookup = new Map(); + +svgAttributes.forEach(name => { + svgAttributeLookup.set(name.toLowerCase(), name); +}); + +export default function fixAttributeCasing(name) { + name = name.toLowerCase(); + return svgAttributeLookup.get(name) || name; +} diff --git a/test/runtime/samples/attribute-casing/_config.js b/test/runtime/samples/attribute-casing/_config.js index cdab7b0a18..e179b8c66d 100644 --- a/test/runtime/samples/attribute-casing/_config.js +++ b/test/runtime/samples/attribute-casing/_config.js @@ -2,7 +2,11 @@ export default { html: `
YELL
- + + hellooooo + + + hellooooo `, @@ -11,7 +15,9 @@ export default { const attr = sel => target.querySelector(sel).attributes[0].name; assert.equal(attr('div'), 'class'); - assert.equal(attr('svg'), 'viewBox'); - assert.equal(attr('text'), 'textLength'); + assert.equal(attr('svg#one'), 'viewBox'); + assert.equal(attr('svg#one text'), 'textLength'); + assert.equal(attr('svg#two'), 'viewBox'); + assert.equal(attr('svg#two text'), 'textLength'); } -}; \ No newline at end of file +}; diff --git a/test/runtime/samples/attribute-casing/main.html b/test/runtime/samples/attribute-casing/main.html index 5f630c633b..3c2d5e18a0 100644 --- a/test/runtime/samples/attribute-casing/main.html +++ b/test/runtime/samples/attribute-casing/main.html @@ -1,5 +1,9 @@
YELL
- + hellooooo - \ No newline at end of file + + + + hellooooo +