Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform-browser): Expose EventManagerPlugin in the public api #49969

Closed
wants to merge 1 commit into from

Conversation

JeanMeche
Copy link
Member

@JeanMeche JeanMeche commented Apr 22, 2023

This commit exposes the EventManagerPlugin abstract class to the public API.
It provides a documentation with a usecase and a basic implementation describing the possibilities

Rationale for opening to the public API :

  1. The EVENT_MANAGER_PLUGINS token is already public
  2. The documentation provides a usefull usecase
  3. Plugins can already be implemented by following the same API
  4. This does not increase the API surface because of 3.
  5. This topic gained some visibility in the last few days in the twitter community and seems to be not so widely known, so this helps also for the visibility ! (Also wanted to share the usescases implemented by @tinkoff/ng-event-plugins)

PR Type

What kind of change does this PR introduce?

  • Feature

Does this PR introduce a breaking change?

  • No

@JeanMeche JeanMeche changed the title refactor(platform-server): EventManager cleanup feature(platform-browser): Expose EventManagerPlugin in the public api Apr 23, 2023
@JeanMeche JeanMeche changed the title feature(platform-browser): Expose EventManagerPlugin in the public api feat(platform-browser): Expose EventManagerPlugin in the public api Apr 23, 2023
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Apr 23, 2023
@JeanMeche
Copy link
Member Author

JeanMeche commented Apr 23, 2023

Can I get the aio: preview ? 😊

@JeanMeche JeanMeche marked this pull request as ready for review April 23, 2023 16:31
@JeanMeche JeanMeche force-pushed the chore/event-maanger branch 5 times, most recently from 9a97166 to 3fcd5c7 Compare April 23, 2023 17:42
@waterplea
Copy link
Contributor

Super glad to see movement in this direction 👍

Just wanted to mention these two issues slightly impeding wide adoption of custom plugins:

#37850
#40553

@JeanMeche JeanMeche force-pushed the chore/event-maanger branch 2 times, most recently from e35bca5 to dd607de Compare April 23, 2023 20:42
export abstract class EventManagerPlugin {
abstract addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): Function;
// (undocumented)
manager: EventManager;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel like the EventManager setting this property is a particularly good API. I understand that it's attempting to prevent a situation where the Zone is different but practically speaking, I don't think this ever happens. I would rather this be exposed as an interface that does not include manager.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea, that property bothered me also !

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without that property, the example doesn't work, as well as the broader concept of unintrusive plugins that do their part and delegate further handling back to the manager which is heavily used by @tinkoff/ng-event-plugins.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They only don't work because of the way things are implemented currently. The could be refactored to work without the property being assigned by the EventManager itself.

That said, this was more of a discussion point because I don't necessarily think it's worth the churn to do this as a breaking change.

Copy link
Member Author

@JeanMeche JeanMeche Apr 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem of accessing the manager can be solved by injecting it !

export class StopEventPlugin {
  constructor(private injector: Injector) {}

  supports(event: string): boolean {
    return event.endsWith('.stop');
  }

  addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): Function {
    const eventWrapper = (event: Event) => {
      event.stopPropagation();
      handler(event);
    };

    // striping the stop modifier from the event name;
    const nonModifiedEventName = eventName.replace(/\.stop$/, '');

    const manager = this.injector.get(EventManager);
    return manager.addEventListener(element, nonModifiedEventName, eventWrapper);
  }
}

Or we could run addEventListener in an injection context in the manager :

  addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
    const plugin = this._findPluginFor(eventName);
    return runInInjectionContext(this.injector, () => plugin.addEventListener(element, eventName, handler as (event: Event) => void));
  }

What do you think ?
Should we revert the breaking change or suggest to inject the manager if it's needed ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I don't think switching from property assignment by EventManager to the entire Injector to avoid cyclic dependency is much better. Sounds like for plugins to have direct access to the manager is reasonable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like for plugins to have direct access to the manager is reasonable.

Having access to the manager isn't really the issue, but rather the awkwardness of having a public API where the some other service assigns a value to a user's publicly writable property after the service is created.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use the same approach control value accessors have and add registerManager(manager: EventManager): void?

@JeanMeche JeanMeche force-pushed the chore/event-maanger branch 6 times, most recently from 913a9d0 to c7819f6 Compare April 25, 2023 15:23
@atscott
Copy link
Contributor

atscott commented Apr 25, 2023

@JeanMeche Can you separate this in to two PRs? One that simply adds the @publicApi annotation to EventManagerPlugin and another that adds the documentation? For the public API change, you can simply cite the existing token: https://angular.io/api/platform-browser/EVENT_MANAGER_PLUGINS. The exposed type of the token should definitely be in the public API.

@JeanMeche
Copy link
Member Author

@atscott I've reduced the scope of the PR to adding EventManagerPlugin to the public API.

Do you have any clue why getFactoryOf has been added to the goldens ?

Copy link
Contributor

@dylhunn dylhunn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

@github-actions
Copy link

github-actions bot commented May 9, 2023

Deployed aio for 2c61afe to: https://ng-dev-previews-fw--pr-angular-angular-49969-8pvqqo9w.web.app

Note: As new commits are pushed to this pull request, this link is updated after the preview is rebuilt.

@dylhunn
Copy link
Contributor

dylhunn commented May 9, 2023

@josephperrott I have a tooling question for you. I was trying to start a TGP, but g3sync fails with a patch conflict (albeit a very simple one). Is it possible to update the patch for my g3sync presubmit, without actually committing the patch update?

@josephperrott
Copy link
Member

@dylhunn replying offline as this is a g3 specific item.

@dylhunn
Copy link
Contributor

dylhunn commented May 9, 2023

I will run a TGP on this CL tonight.

    The exposed type of the `EVENT_MANAGER_PLUGINS` token should be in the public API.
@dylhunn
Copy link
Contributor

dylhunn commented Aug 29, 2023

TGP passed.

@dylhunn dylhunn added action: merge The PR is ready for merge by the caretaker target: minor This PR is targeted for the next minor release and removed action: global presubmit The PR is in need of a google3 global presubmit action: review The PR is still awaiting reviews from at least one requested reviewer labels Aug 29, 2023
@dylhunn dylhunn added action: merge The PR is ready for merge by the caretaker and removed action: merge The PR is ready for merge by the caretaker labels Aug 29, 2023
@jessicajaniuk
Copy link
Contributor

This PR was merged into the repository by commit c5daa6c.

LayZeeDK pushed a commit to LayZeeDK/angular__angular that referenced this pull request Sep 20, 2023
angular#49969)

    The exposed type of the `EVENT_MANAGER_PLUGINS` token should be in the public API.

PR Close angular#49969
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 29, 2023
ChellappanRajan pushed a commit to ChellappanRajan/angular that referenced this pull request Jan 23, 2024
angular#49969)

    The exposed type of the `EVENT_MANAGER_PLUGINS` token should be in the public API.

PR Close angular#49969
@JeanMeche JeanMeche deleted the chore/event-maanger branch February 29, 2024 13:40
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker aio: preview area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants