Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions docs/docs/ref-04-tags-and-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ title tr track u ul var video wbr
The following SVG elements are supported:

```
circle defs g line linearGradient path polygon polyline radialGradient rect stop
svg text
altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion animateTransform circle clipPath color-profile cursor defs desc feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence filter font font-face font-face-format font-face-name font-face-src font-face-uri foreignObject g glyph glyphRef hkern image line linearGradient marker mask metadata missing-glyph mpath path pattern polygon polyline radialGradient rect set stop switch symbol svg text textPath tref tspan use view vkern

```

Expand Down Expand Up @@ -68,8 +67,10 @@ In addition, there is the React-specific attribute `dangerouslySetInnerHTML` ([m

### SVG Attributes

> Note:
>
> The `svgIn` attribute corresponds to the `in` attribute.

```
cx cy d fill fx fy gradientTransform gradientUnits offset points r rx ry
spreadMethod stopColor stopOpacity stroke strokeLinecap strokeWidth transform
version viewBox x1 x2 x y1 y2 y
accentHeight accumulate additive alignmentBaseline alphabetic amplitude arabicForm ascent attributeName attributeType azimuth baseFrequency baseProfile baselineShift bbox begin bias by calcMode capHeight clip clipPath clipPathUnits clipRule colorInterpolation colorInterpolationFilters colorProfile colorRendering contentScriptType contentStyleType cursor cx cy d descent diffuseConstant direction display divisor dominantBaseline dur dx dy edgeMode elevation enableBackground end exponent externalResourcesRequired fill fillOpacity fillRule filter filterRes filterUnits floodColor floodOpacity font fontFamily fontSize fontSizeAdjust fontStretch fontStyle fontVariant fontWeight format from fx fy g1 g2 glyphName glyphOrientationHorizontal glyphOrientationVertical glyphRef gradientTransform gradientUnits hanging horizAdvX horizOriginX horixOriginY ideographic imageRendering in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lengthAdjust letterSpacing lightingColor limitingConeAngle local marker markerEnd markerHeight markerMid markerStart markerUnits markerWidth mask maskContentUnits maskUnits mathematical media mode numOctaves offset opacity operator order orient orientation origin overflow overlinePosition overlineThcikness panose1 path pathLength patternContentUnits patternTransform patternUnits pointerEvents points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY renderingIntent repeatCount repeatDur repeatExtensions requiredExtensions requiredFeatures restart result rotate rx ry scale seed shapeRendering slope spacing specularConstant specularExponent spreadMethod startOffset stdDeviation stemh stemv stitchTiles stopColor stopOpacity strikethroughPosition strikethroughThickness string stroke strokeDasharray strokeDashoffset strokeLinecap strokeLinejoin strokeMiterlimit strokeOpacity strokeWidth surfaceScale svgIn systemLanguage tableValues targetX targetY textAnchor textDecoration textLength textRendering to transform u1 u2 underlinePosition underlineThickness unicode unicodeBidi unicodeRange unitsPerEm vAlphabetic vHanging vIdeographic vMathematical values version vertAdvY vertOriginX vertOriginY viewBox viewTarget visibility widths wordSpacing writingMode x1 x2 x xHeight xChannelSelector xlinkActuate xlinkArcrole xlinkHref xlinkShow xlinkTitle xlinkType xmlBase xmlLang xmlSpace y1 y2 y yChannelSelector z zoomAndPan
```
64 changes: 63 additions & 1 deletion src/core/ReactDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,19 +175,81 @@ var ReactDOM = objMapKeyVal({
wbr: false,

// SVG
altGlyph: false,
altGlyphDef: false,
altGlyphItem: false,
animate: false,
animateColor: false,
animateMotion: false,
animateTransform: false,
circle: false,
clipPath: false,
'color-profile': false,
cursor: false,
defs: false,
desc: false,
feBlend: false,
feColorMatrix: false,
feComponentTransfer: false,
feComposite: false,
feConvolveMatrix: false,
feDiffuseLighting: false,
feDisplacementMap: false,
feDistantLight: false,
feFlood: false,
feFuncA: false,
feFuncB: false,
feFuncG: false,
feFuncR: false,
feGaussianBlur: false,
feImage: false,
feMerge: false,
feMergeNode: false,
feMorphology: false,
feOffset: false,
fePointLight: false,
feSpecularLighting: false,
feSpotLight: false,
feTile: false,
feTurbulence: false,
filter: false,
font: false,
'font-face': false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested that this even works? I'm not sure if the transform actually will parse hyphenated tags.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And while it may work here, the transform step definitely doesn't allow hyphenated nodes - <font-face> gets transformed to React.DOM.font-face.

'font-face-format': false,
'font-face-name': false,
'font-face-src': false,
'font-face-uri': false,
foreignObject: false,
g: false,
glyph: false,
glyphRef: false,
hkern: false,
image: false,
line: false,
linearGradient: false,
marker: false,
mask: false,
metadata: false,
'missing-glyph': false,
mpath: false,
path: false,
pattern: false,
polygon: false,
polyline: false,
radialGradient: false,
rect: false,
set: false,
stop: false,
'switch': false,
svg: false,
text: false
symbol: false,
text: false,
textPath: false,
tref: false,
tspan: false,
use: false,
view: false,
vkern: false
}, createDOMComponentClass);

var injection = {
Expand Down
24 changes: 24 additions & 0 deletions src/dom/DOMProperty.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var DOMPropertyInjection = {
HAS_SIDE_EFFECTS: 0x4,
HAS_BOOLEAN_VALUE: 0x8,
HAS_POSITIVE_NUMERIC_VALUE: 0x10,
MUST_USE_NAMESPACED_ATTRIBUTE: 0x20,

/**
* Inject some specialized knowledge about the DOM. This takes a config object
Expand All @@ -57,13 +58,17 @@ var DOMPropertyInjection = {
* DOMMutationMethods: Properties that require special mutation methods. If
* `value` is undefined, the mutation method should unset the property.
*
* DOMAttributeNamespaces: attribute name to namespace mapping for attributes
* that require setAttributeNS()
*
* @param {object} domPropertyConfig the config as described above.
*/
injectDOMPropertyConfig: function(domPropertyConfig) {
var Properties = domPropertyConfig.Properties || {};
var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};
var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {};

if (domPropertyConfig.isCustomAttribute) {
DOMProperty._isCustomAttributeFunctions.push(
Expand Down Expand Up @@ -101,6 +106,11 @@ var DOMPropertyInjection = {
DOMProperty.getMutationMethod[propName] = mutationMethod;
}

var attributeNamespace = DOMAttributeNamespaces[propName];
if (attributeNamespace) {
DOMProperty.getAttributeNamespace[propName] = attributeNamespace;
}

var propConfig = Properties[propName];
DOMProperty.mustUseAttribute[propName] =
propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;
Expand All @@ -112,6 +122,8 @@ var DOMPropertyInjection = {
propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;
DOMProperty.hasPositiveNumericValue[propName] =
propConfig & DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE;
DOMProperty.mustUseNamespacedAttribute[propName] =
propConfig & DOMPropertyInjection.MUST_USE_NAMESPACED_ATTRIBUTE;

invariant(
!DOMProperty.mustUseAttribute[propName] ||
Expand All @@ -131,6 +143,18 @@ var DOMPropertyInjection = {
'DOMProperty: Cannot have both boolean and positive numeric value: %s',
propName
);
invariant(
!DOMProperty.mustUseAttribute[propName] ||
!DOMProperty.mustUseNamespacedAttribute[propName],
'DOMProperty: Cannot use both attribute and namespaced attribute: %s',
propName
);
invariant(
!DOMProperty.mustUseNamespacedAttribute[propName] ||
!DOMProperty.mustUseProperty[propName],
'DOMProperty: Cannot use both namespaced attribute and property: %s',
propName
);
}
}
};
Expand Down
3 changes: 3 additions & 0 deletions src/dom/DOMPropertyOperations.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ var DOMPropertyOperations = {
mutationMethod(node, value);
} else if (shouldIgnoreValue(name, value)) {
this.deleteValueForProperty(node, name);
} else if (DOMProperty.mustUseNamespacedAttribute[name]) {
var ns = DOMProperty.getAttributeNamespace[name];
node.setAttributeNS(ns, DOMProperty.getAttributeName[name], '' + value);
} else if (DOMProperty.mustUseAttribute[name]) {
node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
} else {
Expand Down
Loading