()
| 255 | } |
| 256 | |
| 257 | override execute(): null { |
| 258 | // `this.inputs` contains only those bindings not matched by any directive. These bindings go to |
| 259 | // the element itself. |
| 260 | let elId: TcbExpr | null = null; |
| 261 | |
| 262 | // TODO(alxhub): this could be more efficient. |
| 263 | for (const binding of this.inputs) { |
| 264 | const isPropertyBinding = |
| 265 | binding.type === BindingType.Property || binding.type === BindingType.TwoWay; |
| 266 | |
| 267 | if (isPropertyBinding && this.claimedInputs?.has(binding.name)) { |
| 268 | // Skip this binding as it was claimed by a directive. |
| 269 | continue; |
| 270 | } |
| 271 | |
| 272 | const expr = widenBinding( |
| 273 | tcbExpression(binding.value, this.tcb, this.scope), |
| 274 | this.tcb, |
| 275 | binding.value, |
| 276 | ); |
| 277 | |
| 278 | if (this.tcb.env.config.checkTypeOfDomBindings && isPropertyBinding) { |
| 279 | if (binding.name !== 'style' && binding.name !== 'class') { |
| 280 | if (elId === null) { |
| 281 | elId = this.scope.resolve(this.target); |
| 282 | } |
| 283 | // A direct binding to a property. |
| 284 | const propertyName = REGISTRY.getMappedPropName(binding.name); |
| 285 | const stmt = new TcbExpr( |
| 286 | `${elId.print()}[${TcbExpr.quoteAndEscape(propertyName)}] = ${expr.wrapForTypeChecker().print()}`, |
| 287 | ).addParseSpanInfo(binding.sourceSpan); |
| 288 | this.scope.addStatement(stmt); |
| 289 | } else { |
| 290 | this.scope.addStatement(expr); |
| 291 | } |
| 292 | } else { |
| 293 | // A binding to an animation, attribute, class or style. For now, only validate the right- |
| 294 | // hand side of the expression. |
| 295 | // TODO: properly check class and style bindings. |
| 296 | this.scope.addStatement(expr); |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | return null; |
| 301 | } |
| 302 | } |
nothing calls this directly
no test coverage detected