| 82 | export type TcbDirectiveInput = TcbDirectiveBoundInput | TcbDirectiveUnsetInput; |
| 83 | |
| 84 | export function getBoundAttributes( |
| 85 | directive: TcbDirectiveMetadata, |
| 86 | node: Template | Element | Component | Directive, |
| 87 | ): TcbBoundAttribute[] { |
| 88 | const boundInputs: TcbBoundAttribute[] = []; |
| 89 | |
| 90 | const processAttribute = (attr: BoundAttribute | TextAttribute) => { |
| 91 | // Skip non-property bindings. |
| 92 | if ( |
| 93 | attr instanceof BoundAttribute && |
| 94 | attr.type !== BindingType.Property && |
| 95 | attr.type !== BindingType.TwoWay |
| 96 | ) { |
| 97 | return; |
| 98 | } |
| 99 | |
| 100 | // Skip the attribute if the directive does not have an input for it. |
| 101 | const inputs = directive.inputs.getByBindingPropertyName(attr.name); |
| 102 | |
| 103 | if (inputs !== null) { |
| 104 | boundInputs.push({ |
| 105 | value: attr.value, |
| 106 | sourceSpan: attr.sourceSpan, |
| 107 | keySpan: attr.keySpan ?? null, |
| 108 | inputs: inputs.map((input: TcbInputMapping) => { |
| 109 | return { |
| 110 | fieldName: input.classPropertyName, |
| 111 | required: input.required, |
| 112 | transformType: input.transformType, |
| 113 | isSignal: input.isSignal, |
| 114 | isTwoWayBinding: attr instanceof BoundAttribute && attr.type === BindingType.TwoWay, |
| 115 | }; |
| 116 | }), |
| 117 | }); |
| 118 | } |
| 119 | }; |
| 120 | |
| 121 | if (node instanceof Template) { |
| 122 | if (node.tagName === 'ng-template') { |
| 123 | node.inputs.forEach(processAttribute); |
| 124 | node.attributes.forEach(processAttribute); |
| 125 | } |
| 126 | |
| 127 | node.templateAttrs.forEach(processAttribute); |
| 128 | } else { |
| 129 | node.inputs.forEach(processAttribute); |
| 130 | node.attributes.forEach(processAttribute); |
| 131 | } |
| 132 | |
| 133 | return boundInputs; |
| 134 | } |
| 135 | |
| 136 | export function checkSplitTwoWayBinding( |
| 137 | inputName: string, |