Skip to content

Commit 2f189b9

Browse files
committed
perf(href): variable declaration
1 parent 3e9eec1 commit 2f189b9

File tree

4 files changed

+65
-56
lines changed

4 files changed

+65
-56
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-href",
3-
"version": "19.2.0",
3+
"version": "19.2.1",
44
"license": "MIT",
55
"author": "Raphael Balet",
66
"maintainers": [

projects/ngx-href/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-href",
3-
"version": "19.2.0",
3+
"version": "19.2.1",
44
"license": "MIT",
55
"author": {
66
"name": "Raphaël Balet",
Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,73 @@
1-
import { Directive, ElementRef, HostListener, Input, OnDestroy, signal } from '@angular/core'
1+
import {
2+
Directive,
3+
ElementRef,
4+
HostListener,
5+
inject,
6+
Input,
7+
OnDestroy,
8+
signal,
9+
} from '@angular/core'
210
import { Router } from '@angular/router'
11+
import { NgxHrefServiceProvider } from './href.const'
312
import { NgxHrefService } from './href.service'
413

514
@Directive({
615
selector: 'a[href], button[href]',
716
host: {
8-
'[attr.rel]': 'rel$()',
9-
'[attr.target]': 'target$()',
10-
'[attr.href]': 'href$()',
17+
'[attr.rel]': '$rel()',
18+
'[attr.target]': '$target()',
19+
'[attr.href]': '$href()',
1120
},
1221
})
1322
export class NgxHrefDirective implements OnDestroy {
14-
private _tagName: 'BUTTON' | 'A' = this._elementRef.nativeElement.tagName
23+
readonly #elementRef = inject(ElementRef)
24+
readonly #router = inject(Router)
25+
readonly #ngxHrefService = inject(NgxHrefService)
26+
readonly #config = inject(NgxHrefServiceProvider, { optional: true })
1527

16-
rel$ = signal<string>('')
17-
target$ = signal<string>('')
18-
href$ = signal<string | null>('')
28+
private _tagName: 'BUTTON' | 'A' = this.#elementRef.nativeElement.tagName
29+
private _defaultTargetAttr = this.#config?.defaultTargetAttr || '_self'
30+
31+
$rel = signal<string>('')
32+
$target = signal<string>('')
33+
$href = signal<string | null>('')
1934

2035
@HostListener('click', ['$event']) onClick(event: PointerEvent) {
21-
if (!this.href$() || !this._routeOnClick) return
36+
if (!this.$href() || !this._routeOnClick) return
2237

2338
event.preventDefault()
2439

25-
const fragments = this.href$()?.split('#')
40+
const fragments = this.$href()?.split('#')
2641
if (!fragments) return
2742

2843
if (fragments.length >= 2) {
29-
const urlFragments = this._router.url.split('#')
44+
const urlFragments = this.#router.url.split('#')
3045

31-
if (fragments[0] === urlFragments[0]) this._ngxHrefService.scrollTo(fragments[1])
46+
if (fragments[0] === urlFragments[0]) this.#ngxHrefService.scrollTo(fragments[1])
3247
else {
33-
this._router.navigate([fragments[0]], { fragment: decodeURI(fragments[1]) }).then(() => {
34-
this._ngxHrefService.scrollTo(fragments[1])
48+
this.#router.navigate([fragments[0]], { fragment: decodeURI(fragments[1]) }).then(() => {
49+
this.#ngxHrefService.scrollTo(fragments[1])
3550
})
3651
}
3752
} else {
38-
this._router.navigate([fragments[0]])
53+
this.#router.navigate([fragments[0]])
3954
}
4055
}
4156

4257
@Input() set rel(value: string) {
43-
this.rel$.set(value)
58+
this.$rel.set(value)
4459
}
4560
@Input() set target(value: string) {
46-
this.target$.set(value)
61+
this.$target.set(value)
4762
}
4863
@Input() set href(value: string) {
4964
if (!value) {
50-
this.href$.set(null)
65+
this.$href.set(null)
5166
return
5267
}
5368

5469
try {
55-
this.href$.set(value?.replace(/ /g, '') || '')
70+
this.$href.set(value?.replace(/ /g, '') || '')
5671
} catch (error) {
5772
console.error('ngx-href: Expecting a string', '\n', error)
5873
}
@@ -68,30 +83,24 @@ export class NgxHrefDirective implements OnDestroy {
6883
}
6984
}
7085

86+
private _clickListener: any = null // EventListener | null
7187
private _hrefAttr?: string | null // spam protection
7288
private _mouseenterListener: any = null // EventListener | null
73-
private _clickListener: any = null // EventListener | null
7489
private _routeOnClick = false
7590

76-
constructor(
77-
private _elementRef: ElementRef,
78-
private _router: Router,
79-
private _ngxHrefService: NgxHrefService,
80-
) {}
81-
8291
private _isLinkMailOrPhone(): boolean {
83-
if (this.href$()?.startsWith('mailto') || this.href$()?.startsWith('tel')) {
84-
if (this._ngxHrefService.avoidSpam) {
85-
this._hrefAttr = this.href$()
92+
if (this.$href()?.startsWith('mailto') || this.$href()?.startsWith('tel')) {
93+
if (this.#config?.avoidSpam) {
94+
this._hrefAttr = this.$href()
8695

87-
if (this.href$()?.startsWith('mailto')) this.href$.set('mailto:obfuscated')
88-
else this.href$.set('tel:obfuscated')
96+
if (this.$href()?.startsWith('mailto')) this.$href.set('mailto:obfuscated')
97+
else this.$href.set('tel:obfuscated')
8998

9099
this._mouseenterListener = () => {
91-
if (this._hrefAttr) this.href$.set(this._hrefAttr)
100+
if (this._hrefAttr) this.$href.set(this._hrefAttr)
92101
}
93102

94-
this._elementRef.nativeElement.addEventListener('mouseenter', this._mouseenterListener)
103+
this.#elementRef.nativeElement.addEventListener('mouseenter', this._mouseenterListener)
95104
}
96105

97106
if (this._tagName !== 'A') this._prepareOpenLink()
@@ -102,39 +111,38 @@ export class NgxHrefDirective implements OnDestroy {
102111
}
103112

104113
private _isLinkExternal(): boolean {
105-
return this.href$()?.startsWith('http') ? true : false
114+
return this.$href()?.startsWith('http') ? true : false
106115
}
107116
private _prepareOpenLink() {
108-
if (!this.rel$() && this._ngxHrefService.defaultRelAttr)
109-
this.rel$.set(this._ngxHrefService.defaultRelAttr)
110-
if (!this.target$()) this.target$.set(this._ngxHrefService.defaultTargetAttr)
117+
if (!this.$rel() && this.#config?.defaultRelAttr) this.$rel.set(this.#config.defaultRelAttr)
118+
if (!this.$target()) this.$target.set(this._defaultTargetAttr)
111119

112120
this._clickListener = (event: PointerEvent) => {
113121
event.preventDefault()
114122

115-
const hrefAttr = this._hrefAttr || this.href$()
116-
if (hrefAttr) window.open(hrefAttr, this.target$(), this.rel$())
123+
const hrefAttr = this._hrefAttr || this.$href()
124+
if (hrefAttr) window.open(hrefAttr, this.$target(), this.$rel())
117125
}
118126

119-
this._elementRef.nativeElement.addEventListener('click', this._clickListener)
127+
this.#elementRef.nativeElement.addEventListener('click', this._clickListener)
120128
}
121129

122130
private _isSamePageLink(): boolean {
123-
return this.href$() && (this.href$() as any)[0] === '#' ? true : false
131+
return this.$href() && (this.$href() as any)[0] === '#' ? true : false
124132
}
125133

126134
private _prepareScrollToLink() {
127135
this._clickListener = (event: PointerEvent) => {
128136
event.preventDefault()
129137

130-
if (this.href$()) this._ngxHrefService.scrollTo(this.href$()?.substring(1))
138+
if (this.$href()) this.#ngxHrefService.scrollTo(this.$href()?.substring(1))
131139
}
132140

133-
this._elementRef.nativeElement.addEventListener('click', this._clickListener)
141+
this.#elementRef.nativeElement.addEventListener('click', this._clickListener)
134142
}
135143

136144
ngOnDestroy(): void {
137145
if (this._mouseenterListener)
138-
this._elementRef.nativeElement.removeEventListener('mouseenter', this._mouseenterListener)
146+
this.#elementRef.nativeElement.removeEventListener('mouseenter', this._mouseenterListener)
139147
}
140148
}

projects/ngx-href/src/lib/href.service.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@ export class NgxHrefService {
1414
anchor$: BehaviorSubject<string | null> = new BehaviorSubject<string | null>(null)
1515
loadedAnchor$: BehaviorSubject<string | null> = new BehaviorSubject<string | null>(null) // Trigger the scrollTo mechanism from outside
1616

17-
avoidSpam = this.#config?.avoidSpam || false
18-
behavior = this.#config?.behavior || 'auto'
19-
block = this.#config?.block || 'start'
20-
defaultRelAttr = this.#config?.defaultRelAttr
21-
defaultTargetAttr = this.#config?.defaultTargetAttr || '_self'
22-
inline = this.#config?.inline || 'nearest'
23-
retryTimeout = this.#config?.retryTimeout || 0
17+
private _behavior = this.#config?.behavior || 'auto'
18+
private _block = this.#config?.block || 'start'
19+
private _inline = this.#config?.inline || 'nearest'
20+
private _retryTimeout = this.#config?.retryTimeout || 0
2421

2522
private _actualAnchor?: string
2623

@@ -54,13 +51,17 @@ export class NgxHrefService {
5451
const anchorRef: HTMLElement = this._renderer.selectRootElement(`#${anchor}`, true)
5552

5653
if (anchorRef) {
57-
anchorRef.scrollIntoView({ behavior: this.behavior, block: this.block, inline: this.inline })
54+
anchorRef.scrollIntoView({
55+
behavior: this._behavior,
56+
block: this._block,
57+
inline: this._inline,
58+
})
5859

5960
setTimeout(() => {
60-
anchorRef.scrollIntoView({ behavior: this.behavior })
61+
anchorRef.scrollIntoView({ behavior: this._behavior })
6162

6263
this._actualAnchor = undefined
63-
}, this.retryTimeout)
64+
}, this._retryTimeout)
6465
} else {
6566
setTimeout(() => {
6667
if (anchor !== this._actualAnchor) return

0 commit comments

Comments
 (0)