From fddb4008d1a4c3ba2fcfbe7d47e5b4e2516e57d4 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Tue, 25 Jul 2017 04:07:04 +0300 Subject: [PATCH] Extend and improve propTypes. Optimize javascript hidden classes and inline caching in V8. Add lengthAdjust and textLength text / tspan attributes. --- elements/TSpan.js | 9 +--- elements/Text.js | 9 +--- elements/TextPath.js | 11 +--- lib/attributes.js | 39 ++++++++------ lib/props.js | 118 +++++++++++++++++++++++++++++++++++++++---- 5 files changed, 137 insertions(+), 49 deletions(-) diff --git a/elements/TSpan.js b/elements/TSpan.js index 540291f6..37b0d7cb 100644 --- a/elements/TSpan.js +++ b/elements/TSpan.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import createReactNativeComponentClass from 'react-native/Libraries/Renderer/shims/createReactNativeComponentClass'; import extractText from '../lib/extract/extractText'; -import {pathProps, fontProps} from '../lib/props'; +import {textProps} from '../lib/props'; import {TSpanAttibutes} from '../lib/attributes'; import extractProps from '../lib/extract/extractProps'; import Shape from './Shape'; @@ -11,12 +11,7 @@ import Shape from './Shape'; export default class extends Shape { static displayName = 'TSpan'; - static propTypes = { - ...pathProps, - ...fontProps, - dx: PropTypes.string, - dy: PropTypes.string, - }; + static propTypes = textProps; //noinspection JSUnusedGlobalSymbols static childContextTypes = { diff --git a/elements/Text.js b/elements/Text.js index d8d68b29..b86cba68 100644 --- a/elements/Text.js +++ b/elements/Text.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import createReactNativeComponentClass from 'react-native/Libraries/Renderer/shims/createReactNativeComponentClass'; import extractText from '../lib/extract/extractText'; -import {pathProps, fontProps} from '../lib/props'; +import {textProps} from '../lib/props'; import {TextAttributes} from '../lib/attributes'; import extractProps from '../lib/extract/extractProps'; import Shape from './Shape'; @@ -10,12 +10,7 @@ import Shape from './Shape'; export default class extends Shape { static displayName = 'Text'; - static propTypes = { - ...pathProps, - ...fontProps, - dx: PropTypes.string, - dy: PropTypes.string, - }; + static propTypes = textProps; //noinspection JSUnusedGlobalSymbols static childContextTypes = { diff --git a/elements/TextPath.js b/elements/TextPath.js index c715f11e..5656252f 100644 --- a/elements/TextPath.js +++ b/elements/TextPath.js @@ -4,7 +4,7 @@ import createReactNativeComponentClass from 'react-native/Libraries/Renderer/shi import {TextPathAttributes} from '../lib/attributes'; import extractText from '../lib/extract/extractText'; import Shape from './Shape'; -import {pathProps, fontProps} from '../lib/props'; +import {textPathProps} from '../lib/props'; import extractProps from '../lib/extract/extractProps'; import TSpan from './TSpan'; @@ -13,14 +13,7 @@ const idExpReg = /^#(.+)$/; export default class extends Shape { static displayName = 'Span'; - static propTypes = { - ...pathProps, - ...fontProps, - href: PropTypes.string.isRequired, - method: PropTypes.oneOf(['align', 'stretch']), - spacing: PropTypes.oneOf(['auto', 'exact']), - startOffset: PropTypes.string - }; + static propTypes = textPathProps; render() { let {children, href, startOffset, ...props} = this.props; diff --git a/lib/attributes.js b/lib/attributes.js index 59c1fe19..f1b17c81 100644 --- a/lib/attributes.js +++ b/lib/attributes.js @@ -85,30 +85,37 @@ const RenderableAttributes = { }; const GroupAttributes = { + ...RenderableAttributes, font: { diff: fontDiffer }, - ...RenderableAttributes }; const UseAttributes = { + ...RenderableAttributes, href: true, width: true, height: true, - ...RenderableAttributes }; const SymbolAttributes = { + ...ViewBoxAttributes, name: true, - ...ViewBoxAttributes }; const PathAttributes = { + ...RenderableAttributes, d: true, - ...RenderableAttributes +}; + +const TextSpecificAttributes = { + ...RenderableAttributes, + lengthAdjust: true, + textLength: true, }; const TextAttributes = { + ...TextSpecificAttributes, font: { diff: fontDiffer }, @@ -117,20 +124,20 @@ const TextAttributes = { rotate: arrayDiffer, positionX: arrayDiffer, positionY: arrayDiffer, - ...RenderableAttributes }; const TextPathAttributes = { + ...TextSpecificAttributes, href: true, + startOffset: true, method: true, spacing: true, - startOffset: true, - ...RenderableAttributes + side: true, }; const TSpanAttibutes = { + ...TextAttributes, content: true, - ...TextAttributes }; const ClipPathAttributes = { @@ -138,6 +145,7 @@ const ClipPathAttributes = { }; const GradientAttributes = { + ...ClipPathAttributes, gradient: { diff: arrayDiffer }, @@ -145,18 +153,18 @@ const GradientAttributes = { gradientTransform: { diff: arrayDiffer }, - ...ClipPathAttributes }; const LinearGradientAttributes = { + ...GradientAttributes, x1: true, y1: true, x2: true, y2: true, - ...GradientAttributes }; const RadialGradientAttributes = { + ...GradientAttributes, fx: true, fy: true, rx: true, @@ -164,26 +172,26 @@ const RadialGradientAttributes = { cx: true, cy: true, r: true, - ...GradientAttributes }; const CircleAttributes = { + ...RenderableAttributes, cx: true, cy: true, r: true, - ...RenderableAttributes }; const EllipseAttributes = { + ...RenderableAttributes, cx: true, cy: true, rx: true, ry: true, - ...RenderableAttributes }; const ImageAttributes = { + ...RenderableAttributes, x: true, y: true, width: true, @@ -191,25 +199,24 @@ const ImageAttributes = { src: true, align: true, meetOrSlice: true, - ...RenderableAttributes }; const LineAttributes = { + ...RenderableAttributes, x1: true, y1: true, x2: true, y2: true, - ...RenderableAttributes }; const RectAttributes = { + ...RenderableAttributes, x: true, y: true, width: true, height: true, rx: true, ry: true, - ...RenderableAttributes }; export { diff --git a/lib/props.js b/lib/props.js index b3d39a00..29561c2e 100644 --- a/lib/props.js +++ b/lib/props.js @@ -48,6 +48,16 @@ const strokeProps = { strokeMiterlimit: numberProp }; +const pathProps = { + ...fillProps, + ...strokeProps, + ...clipProps, + ...transformProps, + ...responderProps, + ...touchableProps, + ...definationProps +}; + // normal | italic | oblique | inherit // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/font-style const fontStyle = PropTypes.oneOf(['normal', 'italic', 'oblique']); @@ -127,6 +137,102 @@ const fontProps = { font }; +/* + Name Value Initial value Animatable + lengthAdjust spacing | spacingAndGlyphs spacing yes + https://svgwg.org/svg2-draft/text.html#TextElementLengthAdjustAttribute + https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/lengthAdjust + */ +const lengthAdjust = PropTypes.oneOf(['spacing', 'spacingAndGlyphs']); + +/* + Name Value Initial value Animatable + textLength | | See below yes + https://svgwg.org/svg2-draft/text.html#TextElementTextLengthAttribute + https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/textLength +*/ +const textLength = PropTypes.string; + +const textSpecificProps = { + ...pathProps, + ...fontProps, + lengthAdjust, + textLength, +} + +// https://svgwg.org/svg2-draft/text.html#TSpanAttributes +const textProps = { + ...textSpecificProps, + dx: PropTypes.string, + dy: PropTypes.string, +} + +/* + Name + side + Value + left | right + initial value + left + Animatable + yes + https://svgwg.org/svg2-draft/text.html#TextPathElementSideAttribute +*/ +const side = PropTypes.oneOf(['left', 'right']); + +/* + Name + startOffset + Value + | | + initial value + 0 + Animatable + yes + https://svgwg.org/svg2-draft/text.html#TextPathElementStartOffsetAttribute + https://developer.mozilla.org/en/docs/Web/SVG/Element/textPath + */ +const startOffset = PropTypes.string; + +/* + Name + method + Value + align | stretch + initial value + align + Animatable + yes + https://svgwg.org/svg2-draft/text.html#TextPathElementMethodAttribute + https://developer.mozilla.org/en/docs/Web/SVG/Element/textPath + */ +const method = PropTypes.oneOf(['align', 'stretch']); + +/* + Name + spacing + Value + auto | exact + initial value + exact + Animatable + yes + https://svgwg.org/svg2-draft/text.html#TextPathElementSpacingAttribute + https://developer.mozilla.org/en/docs/Web/SVG/Element/textPath + */ +const spacing = PropTypes.oneOf(['auto', 'exact']); + +// https://svgwg.org/svg2-draft/text.html#TextPathAttributes +// https://developer.mozilla.org/en/docs/Web/SVG/Element/textPath +const textPathProps = { + ...textSpecificProps, + href: PropTypes.string.isRequired, + startOffset, + method, + spacing, + side, +} + const transformProps = { scale: numberProp, scaleX: numberProp, @@ -147,21 +253,13 @@ const transformProps = { transform: PropTypes.oneOfType([PropTypes.object, PropTypes.string]) }; -const pathProps = { - ...fillProps, - ...strokeProps, - ...clipProps, - ...transformProps, - ...responderProps, - ...touchableProps, - ...definationProps -}; - export { numberProp, fillProps, strokeProps, fontProps, + textProps, + textPathProps, clipProps, pathProps, responderProps,