Sitelet https://github.com/angular/angular/pull/37799
Skip to content

fix(elements): detect matchesSelector prototype without IIFE - #37799

Closed
CaerusKaru wants to merge 1 commit into
angular:masterfrom
CaerusKaru:adam/el
Closed

CaerusKaru wants to merge 1 commit into
angular:masterfrom
CaerusKaru:adam/el

Conversation

@CaerusKaru

@CaerusKaru CaerusKaru commented Jun 27, 2020 •

Copy link
Copy Markdown
Member

Although in SSR we patch the global prototypes with DOM globals
like Element and Node, this patch does not occur before the
matches function is called in Angular Elements. This is similar
to the behavior in @angular/upgrade.

Fixes #24551

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Issue Number: 24551

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@CaerusKaru CaerusKaru added action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release area: elements Issues related to Angular Elements labels Jun 27, 2020
@ngbot ngbot Bot modified the milestone: needsTriage Jun 27, 2020
@pullapprove
pullapprove Bot requested a review from andrewseguin June 27, 2020 21:42
@CaerusKaru
CaerusKaru requested a review from gkalpak June 27, 2020 21:42
@CaerusKaru
CaerusKaru force-pushed the adam/el branch 4 times, most recently from 11a4b48 to dad9f6e Compare June 27, 2020 22:36

@gkalpak gkalpak left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I left a couple of comments. Otherwise lgtm.

Not directly related to this PR:

It seems we have similar (but not 100% the same) code in @angular/animations' shared.ts and @angular/upgrade's downgrade_component_adapter.ts. I wonder if it would make sense to have a shared (internal) utility package for such helpers.

Also, these helpers are not 100% the same. It is hard to tell whether the differences account for slightly different needs of each package and how the helpers are used or whether we should align all implementations 😕

Comment thread packages/elements/src/utils.ts Outdated
Comment thread packages/elements/src/utils.ts Outdated
Comment thread packages/elements/src/utils.ts Outdated
@gkalpak gkalpak added the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Jul 13, 2020
@CaerusKaru CaerusKaru removed the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Jul 15, 2020
@CaerusKaru
CaerusKaru removed the request for review from andrewseguin July 15, 2020 04:20

@petebacondarwin petebacondarwin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed-for: size-tracking

Not going to block the merge. I guess 600 bytes is not a killer.

But I think it would be good to consider either (or both) of the following:

  1. Make the _matches code easier to understand
  2. Make the _matches code smaller

It is likely that these two are in opposition to each other. But I feel that as it stands we have the worst of both scenarios. I feel that it could be smaller or simpler...

Another option, as @gkalpak suggested, is to move this to a shared function, since I imagine that elements is rarely used without animations, in which case we are getting hit twice for this logic. Both of these have core as peer dependency, so it could just be moved there an exported "internally".

Comment thread packages/elements/src/utils.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess you are using {}.toString.call() because process could feasibly be null?

Comment thread packages/elements/src/utils.ts Outdated
Comment on lines 23 to 38

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This logic seems super complex. Is it to try to keep the code-size down or something else?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess it is just a copy from the animations library.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I also find this to be super complex.

@pullapprove
pullapprove Bot removed the request for review from IgorMinar July 23, 2020 03:34

@jelbourn jelbourn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be possible to add this shim exclusively to server environments rather than always baking it into the client-side lib?

@pullapprove
pullapprove Bot requested review from AndrewKushnir and jelbourn July 28, 2020 17:03
Comment thread packages/elements/src/utils.ts Outdated

@alan-agius4 alan-agius4 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we change this implementation to something like:

let _matches: (this: any, selector: string) => boolean;
function matchesSelector(el: any, selector: string): boolean {
if (!_matches) {
const elProto = <any>Element.prototype;
_matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector ||
elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector;
}
return el.nodeType === Node.ELEMENT_NODE ? _matches.call(el, selector) : false;
}

it's much simpler, and should solve the issue since it's not using an IIFE.

Although in SSR we patch the global prototypes with DOM globals
like Element and Node, this patch does not occur before the
matches function is called in Angular Elements. This is similar
to the behavior in @angular/upgrade.

Fixes angular#24551
@gkalpak gkalpak added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Oct 8, 2020
@CaerusKaru CaerusKaru added action: review The PR is still awaiting reviews from at least one requested reviewer action: presubmit The PR is in need of a google3 presubmit and removed action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews action: review The PR is still awaiting reviews from at least one requested reviewer labels Oct 8, 2020
@gkalpak gkalpak added the action: merge The PR is ready for merge by the caretaker label Oct 8, 2020
@atscott

atscott commented Oct 9, 2020

Copy link
Copy Markdown
Contributor

presubmit

@atscott atscott closed this in bf717b1 Oct 9, 2020
atscott pushed a commit that referenced this pull request Oct 9, 2020
Although in SSR we patch the global prototypes with DOM globals
like Element and Node, this patch does not occur before the
matches function is called in Angular Elements. This is similar
to the behavior in @angular/upgrade.

Fixes #24551

PR Close #37799
@CaerusKaru
CaerusKaru deleted the adam/el branch October 10, 2020 03:54
@vinothbabu

vinothbabu commented Oct 14, 2020 •

Copy link
Copy Markdown

Does this commit fix the createCustomElement issue in SSR?

@gkalpak

gkalpak commented Oct 14, 2020

Copy link
Copy Markdown
Member

What is the createCustomElement() issue? 😕

@vinothbabu

Copy link
Copy Markdown

What is the createCustomElement() issue? 😕

Angular Element is not available in SSR. (Below is the issue ticket).
#24551

@gkalpak

gkalpak commented Oct 14, 2020

Copy link
Copy Markdown
Member

Yes, this PR should have fixed #24551.

@vinothbabu

vinothbabu commented Oct 14, 2020 •

Copy link
Copy Markdown

Yes, this PR should have fixed #24551.

Wow, that's a great news. We can use custom-elements in SSR which was a road block and which release we are making it?

@gkalpak

gkalpak commented Oct 14, 2020

Copy link
Copy Markdown
Member

It will be in the next 10.1.x release (10.1.6 - assuming there are going to be more v10 releases before v11) and the next 11.x release (11.0.0-next.6).

@angular-automatic-lock-bot

Copy link
Copy Markdown

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 Nov 14, 2020
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 action: presubmit The PR is in need of a google3 presubmit area: elements Issues related to Angular Elements cla: yes target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(elements): importing createCustomElement breaks SSR

9 participants