MCPcopy
hub / github.com/angular/angular / createCustomElement

Function createCustomElement

packages/elements/src/create-custom-element.ts:132–255  ·  view source on GitHub ↗
(
  component: Type<any>,
  config: NgElementConfig,
)

Source from the content-addressed store, hash-verified

130 * @publicApi
131 */
132export function createCustomElement<P>(
133 component: Type<any>,
134 config: NgElementConfig,
135): NgElementConstructor<P> {
136 const inputs = getComponentInputs(component, config.injector);
137
138 const strategyFactory =
139 config.strategyFactory || new ComponentNgElementStrategyFactory(component);
140
141 const attributeToPropertyInputs = getDefaultAttributeToPropertyInputs(inputs);
142
143 class NgElementImpl extends NgElement {
144 // Work around a bug in closure typed optimizations(b/79557487) where it is not honoring static
145 // field externs. So using quoted access to explicitly prevent renaming.
146 static readonly ['observedAttributes'] = Object.keys(attributeToPropertyInputs);
147
148 protected override get ngElementStrategy(): NgElementStrategy {
149 // TODO(andrewseguin): Add e2e tests that cover cases where the constructor isn't called. For
150 // now this is tested using a Google internal test suite.
151 if (!this._ngElementStrategy) {
152 const strategy = (this._ngElementStrategy = strategyFactory.create(
153 this.injector || config.injector,
154 ));
155
156 // Re-apply pre-existing input values (set as properties on the element) through the
157 // strategy.
158 // TODO(alxhub): why are we doing this? this makes no sense.
159 inputs.forEach(({propName, transform}) => {
160 if (!this.hasOwnProperty(propName)) {
161 // No pre-existing value for `propName`.
162 return;
163 }
164
165 // Delete the property from the DOM node and re-apply it through the strategy.
166 const value = (this as any)[propName];
167 delete (this as any)[propName];
168 strategy.setInputValue(propName, value, transform);
169 });
170 }
171
172 return this._ngElementStrategy!;
173 }
174
175 private _ngElementStrategy?: NgElementStrategy;
176
177 constructor(private readonly injector?: Injector) {
178 super();
179 }
180
181 override attributeChangedCallback(
182 attrName: string,
183 oldValue: string | null,
184 newValue: string,
185 namespace?: string,
186 ): void {
187 const [propName, transform] = attributeToPropertyInputs[attrName]!;
188 this.ngElementStrategy.setInputValue(propName, newValue, transform);
189 }

Callers 7

createTestCustomElementFunction · 0.90
slots_spec.tsFile · 0.90
constructorMethod · 0.90
constructorMethod · 0.90
demo-app.routes.tsFile · 0.90

Calls 3

getComponentInputsFunction · 0.90
forEachMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…