@@ -160,6 +160,7 @@ export default class ElementWrapper extends Wrapper {
160
160
bindings : Binding [ ] ;
161
161
event_handlers : EventHandler [ ] ;
162
162
class_dependencies : string [ ] ;
163
+ dynamic_style_dependencies : Set < string > ;
163
164
has_dynamic_attribute : boolean ;
164
165
165
166
select_binding_dependencies ?: Set < string > ;
@@ -214,6 +215,8 @@ export default class ElementWrapper extends Wrapper {
214
215
return ;
215
216
}
216
217
218
+ this . dynamic_style_dependencies = new Set ( ) ;
219
+
217
220
if ( this . node . children . length ) {
218
221
this . node . lets . forEach ( l => {
219
222
extract_names ( l . value || l . name ) . forEach ( name => {
@@ -801,11 +804,13 @@ export default class ElementWrapper extends Wrapper {
801
804
}
802
805
803
806
add_attributes ( block : Block ) {
804
- // Get all the class dependencies first
807
+ // Get all the class and style dependencies first
805
808
this . attributes . forEach ( ( attribute ) => {
806
809
if ( attribute . node . name === 'class' ) {
807
810
const dependencies = attribute . node . get_dependencies ( ) ;
808
811
push_array ( this . class_dependencies , dependencies ) ;
812
+ } else if ( attribute . node . name === 'style' ) {
813
+ add_to_set ( this . dynamic_style_dependencies , attribute . node . get_dependencies ( ) ) ;
809
814
}
810
815
} ) ;
811
816
@@ -1170,8 +1175,18 @@ export default class ElementWrapper extends Wrapper {
1170
1175
1171
1176
add_styles ( block : Block ) {
1172
1177
const has_spread = this . node . attributes . some ( attr => attr . is_spread ) ;
1178
+
1179
+ let style_changed_var : Identifier | undefined ;
1180
+ const maybe_create_style_changed_var = ( ) => {
1181
+ if ( ! style_changed_var && this . dynamic_style_dependencies . size ) {
1182
+ style_changed_var = block . get_unique_name ( 'style_changed' ) ;
1183
+ const style_attr_dirty = block . renderer . dirty ( [ ...this . dynamic_style_dependencies ] ) ;
1184
+ block . chunks . update . push ( b `const ${ style_changed_var } = ${ style_attr_dirty } ;` ) ;
1185
+ }
1186
+ } ;
1187
+
1173
1188
this . node . styles . forEach ( ( style_directive ) => {
1174
- const { name, expression, should_cache , important } = style_directive ;
1189
+ const { name, expression, important , should_cache } = style_directive ;
1175
1190
1176
1191
const snippet = expression . manipulate ( block ) ;
1177
1192
let cached_snippet : Identifier | undefined ;
@@ -1184,24 +1199,40 @@ export default class ElementWrapper extends Wrapper {
1184
1199
1185
1200
block . chunks . hydrate . push ( updater ) ;
1186
1201
1187
- const dependencies = expression . dynamic_dependencies ( ) ;
1202
+ // Assume that style has changed through the spread attribute
1188
1203
if ( has_spread ) {
1189
1204
block . chunks . update . push ( updater ) ;
1190
- } else if ( dependencies . length > 0 ) {
1205
+ } else {
1206
+ const self_deps = expression . dynamic_dependencies ( ) ;
1207
+ const all_deps = new Set ( [
1208
+ ...self_deps ,
1209
+ ...this . dynamic_style_dependencies
1210
+ ] ) ;
1211
+
1212
+ if ( all_deps . size === 0 ) return ;
1213
+
1214
+ let condition = block . renderer . dirty ( [ ...all_deps ] ) ;
1215
+
1191
1216
if ( should_cache ) {
1192
- block . chunks . update . push ( b `
1193
- if (${ block . renderer . dirty ( dependencies ) } && (${ cached_snippet } !== (${ cached_snippet } = ${ snippet } ))) {
1194
- ${ updater }
1195
- }
1196
- ` ) ;
1197
- } else {
1198
- block . chunks . update . push ( b `
1199
- if (${ block . renderer . dirty ( dependencies ) } ) {
1200
- ${ updater }
1201
- }
1202
- ` ) ;
1217
+ condition = x `${ condition } && ${ cached_snippet } !== (${ cached_snippet } = ${ snippet } )` ;
1203
1218
}
1219
+
1220
+ if ( this . dynamic_style_dependencies . size > 0 ) {
1221
+ maybe_create_style_changed_var ( ) ;
1222
+ // If all dependencies are same as the style attribute dependencies, then we can skip the dirty check
1223
+ condition =
1224
+ all_deps . size === this . dynamic_style_dependencies . size
1225
+ ? style_changed_var
1226
+ : x `${ style_changed_var } || ${ condition } ` ;
1227
+ }
1228
+
1229
+ block . chunks . update . push ( b `
1230
+ if (${ condition } ) {
1231
+ ${ updater }
1232
+ }
1233
+ ` ) ;
1204
1234
}
1235
+
1205
1236
} ) ;
1206
1237
}
1207
1238
0 commit comments