Commit graph

108 commits

Author SHA1 Message Date
Matthieu Riegler
5d9cc8f408 refactor(core): remove the standalone feature (#58288)
By removing the standalone feature, we reduce the amount of code generated for components but at the cost of including the `StandaloneService` in the main bundle even if no standalone components are included in it.

PR Close #58288
2024-10-24 16:19:02 -07:00
Matthieu Riegler
57134dd344 refactor(core): drop the Mutable utility type. (#58124)
The complexity of this type isn't necessary, `Writable` is well suited where it was used.

PR Close #58124
2024-10-10 10:47:50 +00:00
Charles Lyding
2545743ad1 refactor(core): support external runtime styles via a component feature (#57922)
The shared style host now has the capability to add component styles as
link elements with external style references. This is currently unused
within the runtime but is an enabling feature for upcoming features such
as automatic component style HMR and development server deferred
stylesheet processing. Instead of inline style content that is then
added to a `style` element for each host node, a `link` element with a
stylesheet `rel` attribute and a `href` attribute can now be created.
The development server must be configured to provide the relevant
component stylesheet upon request. The Angular CLI development server
will provide this functionality once this capability is enabled.
Since the primary use of this capability is development mode and will
not be used for production code, server (SSR) style reuse is currently
not yet implemented but may be implemented in the future.

A component feature is used to provide the DOM renderer access to any
external styles that were emitted at compile time. When external styles
are present, the `getExternalStyles` function will be present on the
runtime component metadata object. The DOM render will use this function
to access and encapsulate the external style URLs as required by the
component.

PR Close #57922
2024-09-30 13:25:12 -07:00
Joey Perrott
9dbe6fc18b refactor: update license text to point to angular.dev (#57901)
Update license text to point to angular.dev instead of angular.io

PR Close #57901
2024-09-24 15:33:00 +02:00
Joey Perrott
31fdf0fbea refactor: migrate core to prettier formatting (#55488)
Migrate formatting to prettier for core from clang-format

PR Close #55488
2024-04-29 09:49:19 -07:00
Pawel Kozlowski
99bfbabe50 refactor(core): break circular dependencies in preparation for queries as signals (#54103)
Break circular dependencies by using type imports and code moves.

PR Close #54103
2024-02-06 15:04:36 +00:00
Kristiyan Kostadinov
50b22a4260 refactor(core): move input signals into own directory (#54200)
Moves the signal input code into its own directory to avoid too many files in the `authoring` root once model inputs are introduced.

PR Close #54200
2024-02-01 15:58:50 +00:00
Paul Gschwendtner
1d95a832e3 refactor(core): detect signal inputs at runtime using input flags (#53571)
This commit introduces a new enum for capturing additional metadata
about inputs. Called `InputFlags`. These will be built up at compile
time and then propagated into the runtime logic, in a way that does
not require additional lookup dictionaries data structures, or
additional memory allocations for "common inputs" that do not have any flags.

The flags will incorporate information on whether an input is signal
based. This can then be used to avoid megamorphic accesses when such
input is set- as we'd not need to check the input field value. This also
avoids cases where an input signal may be used as initial value for an
input (as we'd not incorrectly detect the input as a signal input then).

The new metadata emit will be useful for incorporating additional
metadata for inputs, such as whether they are required etc (although
required inputs are a build-time only construct right now- but this is a
good illustration of why input flags can be useful). An alternative
could have been to have an additional boolean entry for signal inputs,
but allocating a number with more flexible input flags seems more future
proof and more reasonable andreadable.

More information on the megamorphic access when updating an input
signal
https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner
32f908ab70 fix(core): do not accidentally inherit input transforms when overridden (#53571)
Currently when a base class defines an input with a transform, derived
classes re-defining the input via `@Input`, or `inputs: [<..>]`, end up
inherting the transform due to a bug in the inherit definitions feature.

This commit fixes this. We verified in the Google codebase that this is
an unlikely occurrence and it's trivial to fix on user side by removing
the re-declaration/override, or explictly adding the necessary
transform.

Conceptually, the behavior was quite inconsistent as everything else of
inputs was overridden as expected. i.e. alias, required state etc. The
exception were input transforms. This commit fixes this.

PR Close #53571
2024-01-04 12:07:13 -08:00
Kristiyan Kostadinov
c7c7ea9813 fix(core): inherit host directives (#52992)
Adds support for inheriting host directives from the parent class. This is consistent with how we inherit other features like host bindings.

Fixes #51203.

PR Close #52992
2023-11-20 13:16:15 -08:00
Pawel Kozlowski
6c8776ff71 fix(core): limit rate of markers invocations (#52742)
This PR assures that the performance markers are invoked
only once for a given feature.

Closes #52524

PR Close #52742
2023-11-09 19:58:26 +00:00
Alan Agius
93d32a9acb fix(core): guard usages of performance.mark (#52505)
While `performance.mark` is available on all supported browsers and node.js version this API is not available in JSDOM which is used by Jest and Cloudflare worker.

This commit, updates the usage to a safer variant.

PR Close #52505
2023-11-03 07:43:36 -07:00
Pawel Kozlowski
225914b75e refactor(core): use performance API for control flow and standalone (#52370)
This commit adds a standard performance marker that can be viewed in Chrome dev tools and other tooling.
See more info at https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark

PR Close #52370
2023-10-31 12:43:51 -07:00
Kristiyan Kostadinov
7368b8aaeb fix(core): host directive validation not picking up duplicate directives on component node (#52073)
Fixes that, depending on the matching and import order, in some cases we weren't throwing the error saying that a directive matched multiple times on the same element.

Fixes #52072.

PR Close #52073
2023-10-09 12:39:19 -07:00
Andrew Kushnir
031b599a55 fix(core): ensure that standalone components get correct injector instances (#50954)
Prior to this change, we've used `componentDef.id` as a key in a Map that acts as a cache to avoid re-creating injector instances for standalone components. In v16, the logic that generates the id has changed from an auto-incremental to a generation based on metadata. If multiple components have similar metadata, their ids might overlap.

This commit updates the logic to stop using `componentDef.id` as a key and instead, use the `componentDef` itself. This would ensure that we always have a correct instance of an injector associated with a standalone component instance.

Resolves #50724.

PR Close #50954
2023-07-10 07:07:44 -07:00
Kristiyan Kostadinov
68017d4e75 feat(core): add ability to transform input values (#50420)
According to the HTML specification most attributes are defined as strings, however some can be interpreted as different types like booleans or numbers. [In the HTML standard](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes), boolean attributes are considered `true` if they are present on a DOM node and `false` if they are omitted. Common examples of boolean attributes are `disabled` on interactive elements like `<button>` or `checked` on `<input type="checkbox">`. Another example of an attribute that is defined as a string, but interpreted as a different type is the `value` attribute of `<input type="number">` which logs a warning and ignores the value if it can't be parsed as a number.

Historically, authoring Angular inputs that match the native behavior in a type-safe way has been difficult for developers, because Angular interprets all static attributes as strings. While some recent TypeScript versions made this easier by allowing setters and getters to have different types, supporting this pattern still requires a lot of boilerplate and additional properties to be declared. For example, currently developers have to write something like this to have a `disabled` input that behaves like the native one:

```typescript
import {Directive, Input} from '@angular/core';

@Directive({selector: 'mat-checkbox'})
export class MatCheckbox {
  @Input()
  get disabled() {
    return this._disabled;
  }
  set disabled(value: any) {
    this._disabled = typeof value === 'boolean' ? value : (value != null && value !== 'false');
  }
  private _disabled = false;
}
```

This feature aims to address the issue by introducing a `transform` property on inputs. If an input has a `transform` function, any values set through the template will be passed through the function before being assigned to the directive instance. The example from above can be rewritten to the following:

```typescript
import {Directive, Input, booleanAttribute} from '@angular/core';

@Directive({selector: 'mat-checkbox'})
export class MatCheckbox {
  @Input({transform: booleanAttribute}) disabled: boolean = false;
}
```

These changes also add the `booleanAttribute` and `numberAttribute` utilities to `@angular/core` since they're common enough to be useful for most projects.

Fixes #8968.
Fixes #14761.

PR Close #50420
2023-05-30 13:01:13 -07:00
Kristiyan Kostadinov
f6da091228 refactor(compiler): introduce compiler infrastructure for input transforms (#50225)
Adds the necessary compiler changes to support input transform functions. The compiler output has changed in the following ways:

### Directive handler
The directive handler now extracts a reference to the input transform function and it resolves the type of its first parameter. It also asserts that the type can be referenced in the compiled output and that it doesn't clash with any pre-existing `ngAcceptInputType_` members.

### .d.ts
In the generated declaration files the compiler now inserts an `ngAcceptInputType_` member for each input with a `transform` function. The member's type corresponds to the type of the first parameter of the function, e.g.

```typescript
// foo.directive.ts
@Directive()
export class Foo {
  @Input({transform: (incomingValue: string) => parseInt(incomingValue)}) value: number;
}

// foo.directive.d.ts
export class Foo {
  value: number;
  static ngAcceptInputType_value: string;
}
```

### Type check block
If an input has `transform` function, the TCB will use the type of its first parameter for the setter type. This uses the same infrastructure as the `ngAcceptInputType_` members.

### Directive declaration
The generated runtime directive declaration call now includes the `transform` function in the `inputs` map, if the input is being transformed. The function will be picked up by the runtime in the next commit to do the actual transformation.

```typescript
// foo.directive.ts
@Directive()
export class Foo {
  @Input({transform: (incomingValue: string) => parseInt(incomingValue)}) value: number;
}

// foo.directive.js
export class Foo {
  ɵdir = ɵɵdefineDirective({
    inputs: {
      value: ['value', 'value', incomingValue => parseInt(incomingValue)]
    }
  });
}
```

PR Close #50225
2023-05-22 14:48:02 +00:00
Kristiyan Kostadinov
8b44ba3170 fix(core): host directives incorrectly validating aliased bindings (#50364)
Fixes that the host directives feature was incorrectly throwing the conflicting alias error when an aliased binding was being exposed under the same alias.

Fixes #48951.

PR Close #50364
2023-05-19 15:09:48 +00:00
Kristiyan Kostadinov
f97bebf17a fix(compiler-cli): implement more host directive validations as diagnostics (#47768)
Implements more of the runtime validations for host directives as compiler diagnostics so that they can be caught earlier. Also does some minor cleanup.

PR Close #47768
2022-10-17 12:12:22 +02:00
Kristiyan Kostadinov
07d9a27da2 refactor(core): handle ngOnChanges in host directives (#47597)
The `NgOnChanges` feature matches some legacy ViewEngine behavior where the keys in the `SimpleChanges` object are based on the *declared* names of the inputs, not the public or minified names. This is achieved by constructing the `DirectiveDef.declaredInputs` object at the same time as when `DirectiveDef.inputs` is created.

This logic breaks down for host directives, because they can re-alias the input under a different public name which won't be present in the `declaredInputs`.

These changes add some logic to patch the directive def aliases onto the `declaredInputs`. There is some validation in place to ensure that this patching doesn't overwrite any pre-existing inputs.

PR Close #47597
2022-10-03 10:07:51 -07:00
Kristiyan Kostadinov
50f8928d56 refactor(core): add host directive definitions validation (#47589)
Adds some logic to ensure that host directives are configured correctly.

PR Close #47589
2022-09-30 10:52:12 -07:00
Kristiyan Kostadinov
76a8c68cc1 refactor(core): add input and output filtering for host directives (#47536)
Adds the logic that will filter out unexposed inputs/outputs and apply the aliases that the author specified when writing the host directives.

PR Close #47536
2022-09-29 15:48:59 -07:00
Kristiyan Kostadinov
3fe21a67ca refactor(core): expose host directives to their host through DI (#47476)
Exposes the host directives to the host and its descendants through DI. This can be useful, because it allows the host to further configure the host directives.

PR Close #47476
2022-09-23 13:58:17 -07:00
Kristiyan Kostadinov
adb1a61677 refactor(core): invoke basic host directives (#47430)
Expands the runtime to allow for basic host directives to be invoked within a template. This is achieved by making a second pass over the directives that were matched based on their selectors and producing a new array of directives that include host directives. Note that the ordering in the array is important, because it determines which host bindings and DI tokens will be overwritten.

PR Close #47430
2022-09-19 09:43:06 +02:00
Kristiyan Kostadinov
54ceed53e2 refactor(compiler): add support for host directives (#46868)
This is the compile-time implementation of the `hostDirectives` feature plus a little bit of runtime code to illustrate how the newly-generated code will plug into the runtime. It works by creating a call to the new `ɵɵHostDirectivesFeature` feature whenever a directive has a `hostDirectives` field. Afterwards `ɵɵHostDirectivesFeature` will patch a new function onto the directive definition that will be invoked during directive matching.

For example, if we take the following definition:

```ts
@Directive({
  hostDirectives: [HostA, {directive: HostB, inputs: ['input: alias']}]
})
class MyDir {}
```

Will compile to:

```js
MyDir.ɵdir = ɵɵdefineComponent({
  features: [ɵɵHostDirectivesFeature([HostA, {
    directive: HostB,
    inputs: {
      input: "alias"
    }
  }])]
});
```

The template type checking is implemented during directive matching by adding the host directives applied on the host to the array of matched directives whenever the host is matched in a template.

Relates to #8785.

PR Close #46868
2022-08-22 16:00:35 -07:00
John Vandenberg
c14c701775 docs: fix spelling (#46713)
PR Close #46713
2022-07-08 20:54:52 +00:00
Ramesh Thiruchelvam
df1652e7d7 refactor(common): align tree shakable error messages to new format (#46370)
Align tree shakable error messages are simplified with the new format and errorMessage variables are removed.

```ts
throw new RuntimeError(
  RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
  ngDevMode && 'Injector has already been destroyed.');
```

PR Close #46370
2022-06-15 14:05:54 -07:00
Kristiyan Kostadinov
0206c10f8e refactor(core): minor ComponentDef improvements (#46093)
Makes the following improvements in the runtime:
* Uses the unique ID of the component definition to keep track of its injector in the `StandaloneFeature`, instead of the definition itself. This reduces the amount of memory we can leak, if something doesn't get cleaned up.
* Changes the naming and description of the `ComponentDef.id` to reflect what it is used for.

PR Close #46093
2022-06-02 13:41:27 -07:00
George Kalpakas
cd0096df2c docs: fix inline JSDoc tags (@see --> @link) (#46040)
In some places, the [@see][1] JSDoc tag was incorrectly used instead of
the [@link][2] inline tag, leading to warnings during doc generation and
the `@see` tags being ignored (and thus shown in the docs as is).
Replace the `@see` tags with the intended `@link` tags.

[1]: https://jsdoc.app/tags-see.html
[2]: https://jsdoc.app/tags-inline-link.html

PR Close #46040
2022-05-19 13:32:20 -07:00
Pawel Kozlowski
410d81f0e2 refactor(core): disallow standalone components in importProvidersFrom calls (#45837)
This commit narrows down acceptable argument types of the
`importProvidersFrom` function. More specifically, it rejects
standalone components as a source of imports.

PR Close #45837
2022-05-03 13:12:36 -07:00
Alex Rickabaugh
d322052db3 refactor(core): guard against importProvidersFrom in components (#45838)
`importProvidersFrom` provides a bridge from the world of NgModule-based DI
configuration to the new, "standalone" world of direct providers and
environment injectors. Early user feedback suggested some confusion around
where this function was supposed to be used, particularly around importing
NgModule-based providers into standalone component `providers` arrays, which
is not the intended use. This confusion is exacerbated by the fact that due
to the unified `Provider` type, this kind of misconfiguration was happily
accepted by the type system.

This commit changes the return type of `importProvidersFrom` to wrap the
returned providers in an opaque type that prevents them from being used in
component provider contexts. This, together with stronger documentation
around the purpose and functionality of `importProvidersFrom`, should
address some of the above confusion.

PR Close #45838
2022-05-02 15:50:44 -07:00
Andrew Scott
f3eb7d9ecb fix(core): Ensure the StandaloneService is retained after closure minification (#45783)
In order to survive closure minification correctly, static properties need to
be annotated with @nocollapse.

For more history, see https://github.com/angular/angular/pull/28050

PR Close #45783
2022-04-27 13:05:33 -07:00
Pawel Kozlowski
2b5c2d6938 refactor(core): create a standalone injector during applicationBootstrap (#45766)
This commit changes the injectors hiearchy created during applicationBootstrap.
From now on a standalone injector (holding all the ambient providers of a
standalone component) is create as a child of the application injector.
This change alligns injectors hierarchy for bootstrapped and dynamically
created standalone components.

PR Close #45766
2022-04-27 09:03:50 -07:00
Andrew Kushnir
5771b18a98 feat(core): add the bootstrapApplication function (#45674)
This commit implements the `bootstrapApplication` function that allows bootstrapping an application and pass a standalone component as a root component.

PR Close #45674
2022-04-21 17:47:54 -07:00
Pawel Kozlowski
9e4c4bc42a docs(core): add API documentation to standalone-related classes (#45687)
This commit adds some internal documentation.

PR Close #45687
2022-04-20 16:01:56 -07:00
Pawel Kozlowski
3616d7eb59 refactor(core): implement standalone injectors (#45687)
This commit implements the `StandaloneFeature` which provides for the
creation of standalone injectors, for those components which need them. The
feature-based implementation ensures the machinery for standalone injectors
is properly tree-shakable.

PR Close #45687
2022-04-20 16:01:56 -07:00
Alex Rickabaugh
d8086a1dbf refactor(compiler-cli): emit StandaloneFeature for standalone components (#45672)
This commit adds an emit for standalone components of the
`StandaloneFeature`, which will support creation of standalone injectors and
any other mechanisms necessary for standalone component functionality at
runtime.

Using a feature allows for standalone functionality to be tree-shaken in
applications that aren't using them.

PR Close #45672
2022-04-20 05:45:56 -07:00
Kristiyan Kostadinov
57f8ab2ed8 fix(core): better error message when directive extends a component (#45658)
We throw an error when a directive is trying to extend a component, but we don't actually say which class is responsible which can be difficult to track down. These changes add the two class names to the error message.

PR Close #45658
2022-04-18 09:24:23 -07:00
Ramesh Thiruchelvam
bc03a2e3e3 refactor(core): make the error messages tree shakable (#44359)
Long error messages can be tree-shaken in the production build and replaced with error codes.

See: https://github.com/angular/angular/pull/44219#issuecomment-983216374

PR Close #44359
2022-01-18 17:38:10 -08:00
cexbrayat
bf158e7ff0 fix(core): remove duplicated EMPTY_OBJ constant (#41066)
The codebase currently contains several `EMPTY_OBJ` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating, we decided to remove the duplicated symbols.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.

PR Close #41066
2021-03-04 11:08:49 -08:00
cexbrayat
e12d9dec64 fix(core): remove duplicated EMPTY_ARRAY constant (#40991)
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.

PR Close #40991
2021-03-01 09:00:43 -08:00
Misko Hevery
88f8ddd3d3 Revert "fix(core): remove duplicated EMPTY_ARRAY constant (#40587)"
This reverts commit 34aa9c3531.
2021-01-28 14:35:03 -08:00
cexbrayat
34aa9c3531 fix(core): remove duplicated EMPTY_ARRAY constant (#40587)
The codebase currently contains several `EMPTY_ARRAY` constants,
and they can end up in the bundle of an application.
A recent commit 6fbe219 tipped us off
as it introduced several `noop` occurrences in the golden symbol files.
After investigating with @petebacondarwin,
we decided to remove the duplicated symbols.

This probably shaves only a few bytes,
but this commit removes the duplicated functions,
by always using the one in `core/src/utils/empty`.

PR Close #40587
2021-01-28 08:55:53 -08:00
Misko Hevery
b2579d43cd refactor(core): Add injector debug information to LViewDebug (#38707)
Extended the `LViewDebug` to display node-injector information for each
node.

PR Close #38707
2020-09-28 16:15:59 -04:00
Misko Hevery
737506e79c fix(core): Allow modification of lifecycle hooks any time before bootstrap (#35464)
Currently we read lifecycle hooks eagerly during `ɵɵdefineComponent`.
The result is that it is not possible to do any sort of meta-programing
such as mixins or adding lifecycle hooks using custom decorators since
any such code executes after `ɵɵdefineComponent` has extracted the
lifecycle hooks from the prototype. Additionally the behavior is
inconsistent between AOT and JIT mode. In JIT mode overriding lifecycle
hooks is possible because the whole `ɵɵdefineComponent` is placed in
getter which is executed lazily. This is because JIT mode must compile a
template which can be specified as `templateURL` and those we are
waiting for its resolution.

- `+` `ɵɵdefineComponent` becomes smaller as it no longer needs to copy
  lifecycle hooks from prototype to `ComponentDef`
- `-` `ɵɵNgOnChangesFeature` feature is now always included with the
  codebase as it is no longer tree shakable.

Previously we have read lifecycle hooks from prototype in the
`ɵɵdefineComponent` so that lifecycle hook access would be monomorphic.
This decision was made before we had `T*` data structures. By not
reading the lifecycle hooks we are moving the megamorhic read form
`ɵɵdefineComponent` to instructions. However, the reads happen on
`firstTemplatePass` only and are subsequently cached in the `T*` data
structures. The result is that the overall performance should be same
(or slightly better as the intermediate `ComponentDef` has been
removed.)

- [ ] Remove `ɵɵNgOnChangesFeature` from compiler. (It will no longer
      be a feature.)
- [ ] Discuss the future of `Features` as they hinder meta-programing.

Fix #30497

PR Close #35464
2020-07-15 16:22:46 -07:00
Joey Perrott
d1ea1f4c7f build: update license headers to reference Google LLC (#37205)
Update the license headers throughout the repository to reference Google LLC
rather than Google Inc, for the required license headers.

PR Close #37205
2020-05-26 14:26:58 -04:00
Joey Perrott
698b0288be build: reformat repo to new clang@1.4.0 (#36613)
PR Close #36613
2020-04-14 12:08:36 -07:00
Doug Parker
9cf85d2177 fix(core): remove side effects from ɵɵNgOnChangesFeature() (#35769)
`ɵɵNgOnChangesFeature()` would set `ngInherit`, which is a side effect and also not necessary. This was pulled out to module scope so the function itself can be pure. Since it only curries another function, the call is entirely unnecessary. Updated the compiler to only generate a reference to this function, rather than a call to it, and removed the extra curry indirection.

PR Close #35769
2020-03-03 08:50:03 -08:00
zhuyujie
a756161dc2 fix(core): make subclass inherit developer-defined data (#35105)
PR Close #35105
2020-02-19 12:50:48 -08:00
Kristiyan Kostadinov
304584c291 perf(ivy): remove unused argument in hostBindings function (#34969)
We had some logic for generating and passing in the `elIndex` parameter into the `hostBindings` function, but it wasn't actually being used for anything. The only place left that had a reference to it was the `StylingBuilder` and it only stored it without referencing it again.

PR Close #34969
2020-01-27 12:49:35 -08:00