diff --git a/src/renderers/dom/client/__tests__/ReactDOMSVG-test.js b/src/renderers/dom/client/__tests__/ReactDOMSVG-test.js index ed24ad4acaec5..84fb2711f42ab 100644 --- a/src/renderers/dom/client/__tests__/ReactDOMSVG-test.js +++ b/src/renderers/dom/client/__tests__/ReactDOMSVG-test.js @@ -21,45 +21,6 @@ describe('ReactDOMSVG', function() { ReactDOMServer = require('ReactDOMServer'); }); - it('creates initial markup for known hyphenated attributes', function() { - var markup = ReactDOMServer.renderToString( - - ); - expect(markup).toContain('clip-path="url(#starlet)"'); - }); - - it('creates initial markup for camel case attributes', function() { - var markup = ReactDOMServer.renderToString( - - ); - expect(markup).toContain('viewBox="0 0 100 100"'); - }); - - it('deprecates camel casing of hyphenated attributes', function() { - spyOn(console, 'error'); - var markup = ReactDOMServer.renderToString( - - ); - expect(markup).toContain('clip-path="url(#starlet)"'); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('clipPath'); - expect(console.error.argsForCall[0][0]).toContain('clip-path'); - }); - - it('creates initial markup for unknown hyphenated attributes', function() { - var markup = ReactDOMServer.renderToString( - - ); - expect(markup).toContain('the-word="the-bird"'); - }); - - it('creates initial markup for unknown camel case attributes', function() { - var markup = ReactDOMServer.renderToString( - - ); - expect(markup).toContain('theWord="theBird"'); - }); - it('creates initial namespaced markup', function() { var markup = ReactDOMServer.renderToString( diff --git a/src/renderers/dom/shared/DOMPropertyOperations.js b/src/renderers/dom/shared/DOMPropertyOperations.js index dc0c3fb7f9eee..1ce9e29b753fb 100644 --- a/src/renderers/dom/shared/DOMPropertyOperations.js +++ b/src/renderers/dom/shared/DOMPropertyOperations.js @@ -126,31 +126,6 @@ var DOMPropertyOperations = { return name + '=' + quoteAttributeValueForBrowser(value); }, - /** - * Creates markup for an SVG property. - * - * @param {string} name - * @param {*} value - * @return {string} Markup string, or empty string if the property was invalid. - */ - createMarkupForSVGAttribute: function(name, value) { - if (__DEV__) { - ReactDOMInstrumentation.debugTool.onCreateMarkupForSVGAttribute(name, value); - } - if (!isAttributeNameSafe(name) || value == null) { - return ''; - } - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? - DOMProperty.properties[name] : null; - if (propertyInfo) { - // Migration path for deprecated camelCase aliases for SVG attributes - var { attributeName } = propertyInfo; - return attributeName + '=' + quoteAttributeValueForBrowser(value); - } else { - return name + '=' + quoteAttributeValueForBrowser(value); - } - }, - /** * Sets the value for a property on a node. * @@ -210,18 +185,6 @@ var DOMPropertyOperations = { } }, - setValueForSVGAttribute: function(node, name, value) { - if (__DEV__) { - ReactDOMInstrumentation.debugTool.onSetValueForSVGAttribute(node, name, value); - } - if (DOMProperty.properties.hasOwnProperty(name)) { - // Migration path for deprecated camelCase aliases for SVG attributes - DOMPropertyOperations.setValueForProperty(node, name, value); - } else { - DOMPropertyOperations.setValueForAttribute(node, name, value); - } - }, - /** * Deletes the value for a property on a node. * @@ -257,16 +220,6 @@ var DOMPropertyOperations = { } }, - deleteValueForSVGAttribute: function(node, name) { - var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? - DOMProperty.properties[name] : null; - if (propertyInfo) { - DOMPropertyOperations.deleteValueForProperty(node, name); - } else { - node.removeAttribute(name); - } - }, - }; ReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', { diff --git a/src/renderers/dom/shared/ReactDOMComponent.js b/src/renderers/dom/shared/ReactDOMComponent.js index f7bf1bb122ab7..21a43102300b4 100644 --- a/src/renderers/dom/shared/ReactDOMComponent.js +++ b/src/renderers/dom/shared/ReactDOMComponent.js @@ -638,8 +638,6 @@ ReactDOMComponent.Mixin = { if (propKey !== CHILDREN) { markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); } - } else if (this._namespaceURI === DOMNamespaces.svg) { - markup = DOMPropertyOperations.createMarkupForSVGAttribute(propKey, propValue); } else { markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue); } @@ -851,11 +849,6 @@ ReactDOMComponent.Mixin = { // listener (e.g., onClick={null}) deleteListener(this, propKey); } - } else if (this._namespaceURI === DOMNamespaces.svg) { - DOMPropertyOperations.deleteValueForSVGAttribute( - getNode(this), - propKey - ); } else if ( DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { @@ -922,12 +915,6 @@ ReactDOMComponent.Mixin = { propKey, nextProp ); - } else if (this._namespaceURI === DOMNamespaces.svg) { - DOMPropertyOperations.setValueForSVGAttribute( - getNode(this), - propKey, - nextProp - ); } else if ( DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { diff --git a/src/renderers/dom/shared/ReactDOMDebugTool.js b/src/renderers/dom/shared/ReactDOMDebugTool.js index 6933080298ba4..9fcc3763fadb1 100644 --- a/src/renderers/dom/shared/ReactDOMDebugTool.js +++ b/src/renderers/dom/shared/ReactDOMDebugTool.js @@ -12,8 +12,6 @@ 'use strict'; var ReactDOMUnknownPropertyDevtool = require('ReactDOMUnknownPropertyDevtool'); -var ReactDOMSVGDeprecatedAttributeDevtool = - require('ReactDOMSVGDeprecatedAttributeDevtool'); var warning = require('warning'); @@ -55,21 +53,14 @@ var ReactDOMDebugTool = { onCreateMarkupForProperty(name, value) { emitEvent('onCreateMarkupForProperty', name, value); }, - onCreateMarkupForSVGAttribute(name, value) { - emitEvent('onCreateMarkupForSVGAttribute', name, value); - }, onSetValueForProperty(node, name, value) { emitEvent('onSetValueForProperty', node, name, value); }, - onSetValueForSVGAttribute(node, name, value) { - emitEvent('onSetValueForSVGAttribute', node, name, value); - }, onDeleteValueForProperty(node, name) { emitEvent('onDeleteValueForProperty', node, name); }, }; ReactDOMDebugTool.addDevtool(ReactDOMUnknownPropertyDevtool); -ReactDOMDebugTool.addDevtool(ReactDOMSVGDeprecatedAttributeDevtool); module.exports = ReactDOMDebugTool; diff --git a/src/renderers/dom/shared/SVGDOMPropertyConfig.js b/src/renderers/dom/shared/SVGDOMPropertyConfig.js index effa92f76959c..88fecca249c72 100644 --- a/src/renderers/dom/shared/SVGDOMPropertyConfig.js +++ b/src/renderers/dom/shared/SVGDOMPropertyConfig.js @@ -18,30 +18,60 @@ var NS = { var SVGDOMPropertyConfig = { Properties: { - clipPath: null, - fillOpacity: null, - fontFamily: null, - fontSize: null, - markerEnd: null, - markerMid: null, - markerStart: null, - stopColor: null, - stopOpacity: null, - strokeDasharray: null, - strokeLinecap: null, - strokeOpacity: null, - strokeWidth: null, - textAnchor: null, - xlinkActuate: null, - xlinkArcrole: null, - xlinkHref: null, - xlinkRole: null, - xlinkShow: null, - xlinkTitle: null, - xlinkType: null, - xmlBase: null, - xmlLang: null, - xmlSpace: null, + clipPath: MUST_USE_ATTRIBUTE, + cx: MUST_USE_ATTRIBUTE, + cy: MUST_USE_ATTRIBUTE, + d: MUST_USE_ATTRIBUTE, + dx: MUST_USE_ATTRIBUTE, + dy: MUST_USE_ATTRIBUTE, + fill: MUST_USE_ATTRIBUTE, + fillOpacity: MUST_USE_ATTRIBUTE, + fontFamily: MUST_USE_ATTRIBUTE, + fontSize: MUST_USE_ATTRIBUTE, + fx: MUST_USE_ATTRIBUTE, + fy: MUST_USE_ATTRIBUTE, + gradientTransform: MUST_USE_ATTRIBUTE, + gradientUnits: MUST_USE_ATTRIBUTE, + markerEnd: MUST_USE_ATTRIBUTE, + markerMid: MUST_USE_ATTRIBUTE, + markerStart: MUST_USE_ATTRIBUTE, + offset: MUST_USE_ATTRIBUTE, + opacity: MUST_USE_ATTRIBUTE, + patternContentUnits: MUST_USE_ATTRIBUTE, + patternUnits: MUST_USE_ATTRIBUTE, + points: MUST_USE_ATTRIBUTE, + preserveAspectRatio: MUST_USE_ATTRIBUTE, + r: MUST_USE_ATTRIBUTE, + rx: MUST_USE_ATTRIBUTE, + ry: MUST_USE_ATTRIBUTE, + spreadMethod: MUST_USE_ATTRIBUTE, + stopColor: MUST_USE_ATTRIBUTE, + stopOpacity: MUST_USE_ATTRIBUTE, + stroke: MUST_USE_ATTRIBUTE, + strokeDasharray: MUST_USE_ATTRIBUTE, + strokeLinecap: MUST_USE_ATTRIBUTE, + strokeOpacity: MUST_USE_ATTRIBUTE, + strokeWidth: MUST_USE_ATTRIBUTE, + textAnchor: MUST_USE_ATTRIBUTE, + transform: MUST_USE_ATTRIBUTE, + version: MUST_USE_ATTRIBUTE, + viewBox: MUST_USE_ATTRIBUTE, + x1: MUST_USE_ATTRIBUTE, + x2: MUST_USE_ATTRIBUTE, + x: MUST_USE_ATTRIBUTE, + xlinkActuate: MUST_USE_ATTRIBUTE, + xlinkArcrole: MUST_USE_ATTRIBUTE, + xlinkHref: MUST_USE_ATTRIBUTE, + xlinkRole: MUST_USE_ATTRIBUTE, + xlinkShow: MUST_USE_ATTRIBUTE, + xlinkTitle: MUST_USE_ATTRIBUTE, + xlinkType: MUST_USE_ATTRIBUTE, + xmlBase: MUST_USE_ATTRIBUTE, + xmlLang: MUST_USE_ATTRIBUTE, + xmlSpace: MUST_USE_ATTRIBUTE, + y1: MUST_USE_ATTRIBUTE, + y2: MUST_USE_ATTRIBUTE, + y: MUST_USE_ATTRIBUTE, }, DOMAttributeNamespaces: { xlinkActuate: NS.xlink, @@ -60,9 +90,15 @@ var SVGDOMPropertyConfig = { fillOpacity: 'fill-opacity', fontFamily: 'font-family', fontSize: 'font-size', + gradientTransform: 'gradientTransform', + gradientUnits: 'gradientUnits', markerEnd: 'marker-end', markerMid: 'marker-mid', markerStart: 'marker-start', + patternContentUnits: 'patternContentUnits', + patternUnits: 'patternUnits', + preserveAspectRatio: 'preserveAspectRatio', + spreadMethod: 'spreadMethod', stopColor: 'stop-color', stopOpacity: 'stop-opacity', strokeDasharray: 'stroke-dasharray', @@ -70,6 +106,7 @@ var SVGDOMPropertyConfig = { strokeOpacity: 'stroke-opacity', strokeWidth: 'stroke-width', textAnchor: 'text-anchor', + viewBox: 'viewBox', xlinkActuate: 'xlink:actuate', xlinkArcrole: 'xlink:arcrole', xlinkHref: 'xlink:href', diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js index 974e6b4a8cec3..279692a19978a 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js @@ -259,79 +259,6 @@ describe('ReactDOMComponent', function() { expect(container.firstChild.hasAttribute('height')).toBe(false); }); - it('should remove known SVG camel case attributes', function() { - var container = document.createElement('div'); - ReactDOM.render(, container); - - expect(container.firstChild.hasAttribute('viewBox')).toBe(true); - ReactDOM.render(, container); - expect(container.firstChild.hasAttribute('viewBox')).toBe(false); - }); - - it('should remove known SVG hyphenated attributes', function() { - var container = document.createElement('div'); - ReactDOM.render(, container); - - expect(container.firstChild.hasAttribute('clip-path')).toBe(true); - ReactDOM.render(, container); - expect(container.firstChild.hasAttribute('clip-path')).toBe(false); - }); - - it('should remove arbitrary SVG hyphenated attributes', function() { - var container = document.createElement('div'); - ReactDOM.render(, container); - - expect(container.firstChild.hasAttribute('the-word')).toBe(true); - ReactDOM.render(, container); - expect(container.firstChild.hasAttribute('the-word')).toBe(false); - }); - - it('should remove arbitrary SVG camel case attributes', function() { - var container = document.createElement('div'); - ReactDOM.render(, container); - - if (ReactDOMFeatureFlags.useCreateElement) { - // jsdom's svg parsing makes attributes lowercase, so only assert this - // in createElement mode... - expect(container.firstChild.hasAttribute('theWord')).toBe(true); - } - ReactDOM.render(, container); - expect(container.firstChild.hasAttribute('theWord')).toBe(false); - }); - - it('should remove SVG attributes that should have been hyphenated', function() { - spyOn(console, 'error'); - var container = document.createElement('div'); - ReactDOM.render(, container); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('clipPath'); - expect(console.error.argsForCall[0][0]).toContain('clip-path'); - - expect(container.firstChild.hasAttribute('clip-path')).toBe(true); - ReactDOM.render(, container); - expect(container.firstChild.hasAttribute('clip-path')).toBe(false); - }); - - it('should remove namespaced SVG attributes', function() { - var container = document.createElement('div'); - ReactDOM.render( - - - , - container - ); - - expect(container.firstChild.firstChild.hasAttributeNS( - 'http://www.w3.org/1999/xlink', - 'href' - )).toBe(true); - ReactDOM.render(, container); - expect(container.firstChild.firstChild.hasAttributeNS( - 'http://www.w3.org/1999/xlink', - 'href' - )).toBe(false); - }); - it('should remove properties', function() { var container = document.createElement('div'); ReactDOM.render(
, container); @@ -403,99 +330,6 @@ describe('ReactDOMComponent', function() { expect(container.childNodes[0].getAttribute('myattr')).toBe('myval'); }); - it('should update known hyphenated attributes for SVG tags', function() { - var container = document.createElement('div'); - - var beforeUpdate = ; - ReactDOM.render(beforeUpdate, container); - - var afterUpdate = ; - ReactDOM.render(afterUpdate, container); - - expect(container.childNodes[0].getAttribute('clip-path')).toBe( - 'url(#starlet)' - ); - }); - - it('should update camel case attributes for SVG tags', function() { - var container = document.createElement('div'); - - var beforeUpdate = ; - ReactDOM.render(beforeUpdate, container); - - var afterUpdate = ; - ReactDOM.render(afterUpdate, container); - - expect(container.childNodes[0].getAttribute('viewBox')).toBe( - '0 0 100 100' - ); - }); - - it('should warn camel casing hyphenated attributes for SVG tags', function() { - spyOn(console, 'error'); - var container = document.createElement('div'); - - var beforeUpdate = ; - ReactDOM.render(beforeUpdate, container); - - var afterUpdate = ; - ReactDOM.render(afterUpdate, container); - - expect(container.childNodes[0].getAttribute('clip-path')).toBe( - 'url(#starlet)' - ); - expect(console.error.argsForCall.length).toBe(1); - expect(console.error.argsForCall[0][0]).toContain('clipPath'); - expect(console.error.argsForCall[0][0]).toContain('clip-path'); - }); - - it('should update arbitrary hyphenated attributes for SVG tags', function() { - var container = document.createElement('div'); - - var beforeUpdate = ; - ReactDOM.render(beforeUpdate, container); - - var afterUpdate = ; - ReactDOM.render(afterUpdate, container); - - expect(container.childNodes[0].getAttribute('the-word')).toBe('the-bird'); - }); - - it('should update arbitrary camel case attributes for SVG tags', function() { - var container = document.createElement('div'); - - var beforeUpdate = ; - ReactDOM.render(beforeUpdate, container); - - var afterUpdate = ; - ReactDOM.render(afterUpdate, container); - - expect(container.childNodes[0].getAttribute('theWord')).toBe('theBird'); - }); - - it('should update namespaced SVG attributes', function() { - var container = document.createElement('div'); - - var beforeUpdate = ( - - - - ); - ReactDOM.render(beforeUpdate, container); - - var afterUpdate = ( - - - - ); - ReactDOM.render(afterUpdate, container); - - expect(container.firstChild.firstChild.getAttributeNS( - 'http://www.w3.org/1999/xlink', - 'href' - )).toBe('http://i.imgur.com/JvqCM2p.png'); - }); - it('should clear all the styles when removing `style`', function() { var styles = {display: 'none', color: 'red'}; var container = document.createElement('div'); diff --git a/src/renderers/dom/shared/devtools/ReactDOMSVGDeprecatedAttributeDevtool.js b/src/renderers/dom/shared/devtools/ReactDOMSVGDeprecatedAttributeDevtool.js deleted file mode 100644 index 0bfd77f8fe717..0000000000000 --- a/src/renderers/dom/shared/devtools/ReactDOMSVGDeprecatedAttributeDevtool.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright 2013-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMSVGDeprecatedAttributeDevtool - */ - -'use strict'; - -var DOMProperty = require('DOMProperty'); - -var warning = require('warning'); - -if (__DEV__) { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true, - }; - var warnedSVGAttributes = {}; - - var warnDeprecatedSVGAttribute = function(name) { - if (!DOMProperty.properties.hasOwnProperty(name)) { - return; - } - - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedSVGAttributes.hasOwnProperty(name) && warnedSVGAttributes[name]) { - return; - } - - var { attributeName, attributeNamespace } = DOMProperty.properties[name]; - if (attributeNamespace || name === attributeName) { - return; - } - - warning( - false, - 'SVG property %s is deprecated. Use the original attribute name ' + - '%s for SVG tags instead.', - name, - attributeName - ); - }; -} - -var ReactDOMSVGDeprecatedAttributeDevtool = { - onCreateMarkupForSVGAttribute(name, value) { - warnDeprecatedSVGAttribute(name); - }, - onSetValueForSVGAttribute(node, name, value) { - warnDeprecatedSVGAttribute(name); - }, -}; - -module.exports = ReactDOMSVGDeprecatedAttributeDevtool; diff --git a/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js b/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js index 5adc359063e1e..b83082dfa6d03 100644 --- a/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js +++ b/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js @@ -82,6 +82,6 @@ var ReactDOMUnknownPropertyDevtool = { onDeleteValueForProperty(node, name) { warnUnknownProperty(name); }, -}; +} module.exports = ReactDOMUnknownPropertyDevtool;