From 952fd8662c3f24a1fb5304f6de17ba82fc6e37ea Mon Sep 17 00:00:00 2001 From: Adam Plumer Date: Wed, 7 Oct 2020 20:38:46 -0500 Subject: [PATCH] fix(elements): detect matchesSelector prototype without IIFE (#37799) 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 --- packages/elements/src/utils.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/elements/src/utils.ts b/packages/elements/src/utils.ts index 773120fd11..9bddaa70dc 100644 --- a/packages/elements/src/utils.ts +++ b/packages/elements/src/utils.ts @@ -7,12 +7,6 @@ */ import {ComponentFactoryResolver, Injector, Type} from '@angular/core'; -const matches = (() => { - const elProto = Element.prototype as any; - return elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector || - elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector; -})(); - /** * Provide methods for scheduling the execution of a callback. */ @@ -96,11 +90,20 @@ export function kebabToCamelCase(input: string): string { return input.replace(/-([a-z\d])/g, (_, char) => char.toUpperCase()); } +let _matches: (this: any, selector: string) => boolean; + /** * Check whether an `Element` matches a CSS selector. + * NOTE: this is duplicated from @angular/upgrade, and can + * be consolidated in the future */ -export function matchesSelector(element: Element, selector: string): boolean { - return matches.call(element, selector); +export function matchesSelector(el: any, selector: string): boolean { + if (!_matches) { + const elProto = 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; } /**