@@ -11,6 +11,7 @@ import hyphenateStyleName from '../shared/hyphenateStyleName';
11
11
import warnValidStyle from '../shared/warnValidStyle' ;
12
12
import isUnitlessNumber from '../shared/isUnitlessNumber' ;
13
13
import { checkCSSPropertyStringCoercion } from 'shared/CheckStringCoercion' ;
14
+ import { diffInCommitPhase } from 'shared/ReactFeatureFlags' ;
14
15
15
16
/**
16
17
* Operations for dealing with CSS properties.
@@ -64,14 +65,50 @@ export function createDangerousStringForStyles(styles) {
64
65
}
65
66
}
66
67
68
+ function setValueForStyle ( style , styleName , value ) {
69
+ const isCustomProperty = styleName . indexOf ( '--' ) === 0 ;
70
+ if ( __DEV__ ) {
71
+ if ( ! isCustomProperty ) {
72
+ warnValidStyle ( styleName , value ) ;
73
+ }
74
+ }
75
+
76
+ if ( value == null || typeof value === 'boolean' || value === '' ) {
77
+ if ( isCustomProperty ) {
78
+ style . setProperty ( styleName , '' ) ;
79
+ } else if ( styleName === 'float' ) {
80
+ style . cssFloat = '' ;
81
+ } else {
82
+ style [ styleName ] = '' ;
83
+ }
84
+ } else if ( isCustomProperty ) {
85
+ style . setProperty ( styleName , value ) ;
86
+ } else if (
87
+ typeof value === 'number' &&
88
+ value !== 0 &&
89
+ ! isUnitlessNumber ( styleName )
90
+ ) {
91
+ style [ styleName ] = value + 'px' ; // Presumes implicit 'px' suffix for unitless numbers
92
+ } else {
93
+ if ( styleName === 'float' ) {
94
+ style . cssFloat = value ;
95
+ } else {
96
+ if ( __DEV__ ) {
97
+ checkCSSPropertyStringCoercion ( value , styleName ) ;
98
+ }
99
+ style [ styleName ] = ( '' + value ) . trim ( ) ;
100
+ }
101
+ }
102
+ }
103
+
67
104
/**
68
105
* Sets the value for multiple styles on a node. If a value is specified as
69
106
* '' (empty string), the corresponding style property will be unset.
70
107
*
71
108
* @param {DOMElement } node
72
109
* @param {object } styles
73
110
*/
74
- export function setValueForStyles ( node , styles ) {
111
+ export function setValueForStyles ( node , styles , prevStyles ) {
75
112
if ( styles != null && typeof styles !== 'object' ) {
76
113
throw new Error (
77
114
'The `style` prop expects a mapping from style properties to values, ' +
@@ -88,42 +125,39 @@ export function setValueForStyles(node, styles) {
88
125
}
89
126
90
127
const style = node . style ;
91
- for ( const styleName in styles ) {
92
- if ( ! styles . hasOwnProperty ( styleName ) ) {
93
- continue ;
94
- }
95
- const value = styles [ styleName ] ;
96
- const isCustomProperty = styleName . indexOf ( '--' ) === 0 ;
128
+
129
+ if ( diffInCommitPhase && prevStyles != null ) {
97
130
if ( __DEV__ ) {
98
- if ( ! isCustomProperty ) {
99
- warnValidStyle ( styleName , value ) ;
100
- }
131
+ validateShorthandPropertyCollisionInDev ( prevStyles , styles ) ;
101
132
}
102
133
103
- if ( value == null || typeof value === 'boolean' || value === '' ) {
104
- if ( isCustomProperty ) {
105
- style . setProperty ( styleName , '' ) ;
106
- } else if ( styleName === 'float' ) {
107
- style . cssFloat = '' ;
108
- } else {
109
- style [ styleName ] = '' ;
110
- }
111
- } else if ( isCustomProperty ) {
112
- style . setProperty ( styleName , value ) ;
113
- } else if (
114
- typeof value === 'number' &&
115
- value !== 0 &&
116
- ! isUnitlessNumber ( styleName )
117
- ) {
118
- style [ styleName ] = value + 'px' ; // Presumes implicit 'px' suffix for unitless numbers
119
- } else {
120
- if ( styleName === 'float' ) {
121
- style . cssFloat = value ;
122
- } else {
123
- if ( __DEV__ ) {
124
- checkCSSPropertyStringCoercion ( value , styleName ) ;
134
+ for ( const styleName in prevStyles ) {
135
+ if (
136
+ prevStyles . hasOwnProperty ( styleName ) &&
137
+ ( styles == null || ! styles . hasOwnProperty ( styleName ) )
138
+ ) {
139
+ // Clear style
140
+ const isCustomProperty = styleName . indexOf ( '--' ) === 0 ;
141
+ if ( isCustomProperty ) {
142
+ style . setProperty ( styleName , '' ) ;
143
+ } else if ( styleName === 'float' ) {
144
+ style . cssFloat = '' ;
145
+ } else {
146
+ style [ styleName ] = '' ;
125
147
}
126
- style [ styleName ] = ( '' + value ) . trim ( ) ;
148
+ }
149
+ }
150
+ for ( const styleName in styles ) {
151
+ const value = styles [ styleName ] ;
152
+ if ( styles . hasOwnProperty ( styleName ) && prevStyles [ styleName ] !== value ) {
153
+ setValueForStyle ( style , styleName , value ) ;
154
+ }
155
+ }
156
+ } else {
157
+ for ( const styleName in styles ) {
158
+ if ( styles . hasOwnProperty ( styleName ) ) {
159
+ const value = styles [ styleName ] ;
160
+ setValueForStyle ( style , styleName , value ) ;
127
161
}
128
162
}
129
163
}
@@ -167,15 +201,38 @@ function expandShorthandMap(styles) {
167
201
* becomes .style.fontVariant = ''
168
202
*/
169
203
export function validateShorthandPropertyCollisionInDev (
170
- styleUpdates ,
204
+ prevStyles ,
171
205
nextStyles ,
172
206
) {
173
207
if ( __DEV__ ) {
174
208
if ( ! nextStyles ) {
175
209
return ;
176
210
}
177
211
178
- const expandedUpdates = expandShorthandMap ( styleUpdates ) ;
212
+ // Compute the diff as it would happen elsewhere.
213
+ const expandedUpdates = { } ;
214
+ if ( prevStyles ) {
215
+ for ( const key in prevStyles ) {
216
+ if ( prevStyles . hasOwnProperty ( key ) && ! nextStyles . hasOwnProperty ( key ) ) {
217
+ const longhands = shorthandToLonghand [ key ] || [ key ] ;
218
+ for ( let i = 0 ; i < longhands . length ; i ++ ) {
219
+ expandedUpdates [ longhands [ i ] ] = key ;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ for ( const key in nextStyles ) {
225
+ if (
226
+ nextStyles . hasOwnProperty ( key ) &&
227
+ ( ! prevStyles || prevStyles [ key ] !== nextStyles [ key ] )
228
+ ) {
229
+ const longhands = shorthandToLonghand [ key ] || [ key ] ;
230
+ for ( let i = 0 ; i < longhands . length ; i ++ ) {
231
+ expandedUpdates [ longhands [ i ] ] = key ;
232
+ }
233
+ }
234
+ }
235
+
179
236
const expandedStyles = expandShorthandMap ( nextStyles ) ;
180
237
const warnedAbout = { } ;
181
238
for ( const key in expandedUpdates ) {
@@ -193,7 +250,7 @@ export function validateShorthandPropertyCollisionInDev(
193
250
"avoid this, don't mix shorthand and non-shorthand properties " +
194
251
'for the same value; instead, replace the shorthand with ' +
195
252
'separate values.' ,
196
- isValueEmpty ( styleUpdates [ originalKey ] ) ? 'Removing' : 'Updating' ,
253
+ isValueEmpty ( nextStyles [ originalKey ] ) ? 'Removing' : 'Updating' ,
197
254
originalKey ,
198
255
correctOriginalKey ,
199
256
) ;
0 commit comments