Skip to content

Commit 9b7b9ba

Browse files
crisbetoleonsenft
authored andcommitted
refactor(core): update internal utility
Updates the `getClosestComponentName` function to add support for a predicate function, based on internal requirements.
1 parent 7ec399e commit 9b7b9ba

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

packages/core/src/internal/get_closest_component_name.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@ import {getTNode} from '../render3/util/view_utils';
1717
* Warning! this function will return minified names if the name of the component is minified. The
1818
* consumer of the function is responsible for resolving the minified name to its original name.
1919
* @param node Node from which to start the search.
20+
* @param predicate Predicate function that can be used to decide which nodes should be skipped over
21+
* during the search. Return true if the search should stop or false to keep going up the tree.
2022
*/
21-
export function getClosestComponentName(node: Node): string | null {
23+
export function getClosestComponentName(
24+
node: Node,
25+
predicate?: (current: HTMLElement, componentName: string) => boolean,
26+
): string | null {
2227
let currentNode = node as Node | null;
2328

2429
while (currentNode) {
@@ -40,7 +45,7 @@ export function getClosestComponentName(node: Node): string | null {
4045

4146
// Note: the name may be an empty string if the class name is
4247
// dropped due to minification. In such cases keep going up the tree.
43-
if (name !== null) {
48+
if (name !== null && (!predicate || predicate(currentNode as HTMLElement, name))) {
4449
return name;
4550
} else {
4651
break;

packages/core/test/acceptance/internal_spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,26 @@ describe('internal utilities', () => {
143143
);
144144
ref.destroy();
145145
});
146+
147+
it('should be able to skip over components', () => {
148+
@Component({
149+
selector: 'comp',
150+
template: '<div class="target"></div>',
151+
})
152+
class Comp {}
153+
154+
@Component({
155+
template: `<section><comp /></section>`,
156+
imports: [Comp],
157+
})
158+
class App {}
159+
160+
const fixture = TestBed.createComponent(App);
161+
fixture.detectChanges();
162+
const target = fixture.nativeElement.querySelector('.target');
163+
164+
expect(getClosestComponentName(target)).toBe('Comp');
165+
expect(getClosestComponentName(target, (el) => el.tagName !== 'COMP')).toBe('App');
166+
});
146167
});
147168
});

0 commit comments

Comments
 (0)