(tNode: TNode, attrNameToInject: string)
| 341 | * @publicApi |
| 342 | */ |
| 343 | export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): string | null { |
| 344 | ngDevMode && assertTNodeType(tNode, TNodeType.AnyContainer | TNodeType.AnyRNode); |
| 345 | ngDevMode && assertDefined(tNode, 'expecting tNode'); |
| 346 | if (attrNameToInject === 'class') { |
| 347 | return tNode.classes; |
| 348 | } |
| 349 | if (attrNameToInject === 'style') { |
| 350 | return tNode.styles; |
| 351 | } |
| 352 | |
| 353 | const attrs = tNode.attrs; |
| 354 | if (attrs) { |
| 355 | const attrsLength = attrs.length; |
| 356 | let i = 0; |
| 357 | while (i < attrsLength) { |
| 358 | const value = attrs[i]; |
| 359 | |
| 360 | // If we hit a `Bindings` or `Template` marker then we are done. |
| 361 | if (isNameOnlyAttributeMarker(value)) break; |
| 362 | |
| 363 | // Skip namespaced attributes |
| 364 | if (value === AttributeMarker.NamespaceURI) { |
| 365 | // we skip the next two values |
| 366 | // as namespaced attributes looks like |
| 367 | // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist', |
| 368 | // 'existValue', ...] |
| 369 | i = i + 2; |
| 370 | } else if (typeof value === 'number') { |
| 371 | // Skip to the first value of the marked attribute. |
| 372 | i++; |
| 373 | while (i < attrsLength && typeof attrs[i] === 'string') { |
| 374 | i++; |
| 375 | } |
| 376 | } else if (value === attrNameToInject) { |
| 377 | return attrs[i + 1] as string; |
| 378 | } else { |
| 379 | i = i + 2; |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | return null; |
| 384 | } |
| 385 | |
| 386 | function notFoundValueOrThrow<T>( |
| 387 | notFoundValue: T | null, |
no test coverage detected