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'
2
10
import { Router } from '@angular/router'
11
+ import { NgxHrefServiceProvider } from './href.const'
3
12
import { NgxHrefService } from './href.service'
4
13
5
14
@Directive ( {
6
15
selector : 'a[href], button[href]' ,
7
16
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 ()' ,
11
20
} ,
12
21
} )
13
22
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 } )
15
27
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 > ( '' )
19
34
20
35
@HostListener ( 'click' , [ '$event' ] ) onClick ( event : PointerEvent ) {
21
- if ( ! this . href$ ( ) || ! this . _routeOnClick ) return
36
+ if ( ! this . $href ( ) || ! this . _routeOnClick ) return
22
37
23
38
event . preventDefault ( )
24
39
25
- const fragments = this . href$ ( ) ?. split ( '#' )
40
+ const fragments = this . $href ( ) ?. split ( '#' )
26
41
if ( ! fragments ) return
27
42
28
43
if ( fragments . length >= 2 ) {
29
- const urlFragments = this . _router . url . split ( '#' )
44
+ const urlFragments = this . #router . url . split ( '#' )
30
45
31
- if ( fragments [ 0 ] === urlFragments [ 0 ] ) this . _ngxHrefService . scrollTo ( fragments [ 1 ] )
46
+ if ( fragments [ 0 ] === urlFragments [ 0 ] ) this . #ngxHrefService . scrollTo ( fragments [ 1 ] )
32
47
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 ] )
35
50
} )
36
51
}
37
52
} else {
38
- this . _router . navigate ( [ fragments [ 0 ] ] )
53
+ this . #router . navigate ( [ fragments [ 0 ] ] )
39
54
}
40
55
}
41
56
42
57
@Input ( ) set rel ( value : string ) {
43
- this . rel$ . set ( value )
58
+ this . $rel . set ( value )
44
59
}
45
60
@Input ( ) set target ( value : string ) {
46
- this . target$ . set ( value )
61
+ this . $target . set ( value )
47
62
}
48
63
@Input ( ) set href ( value : string ) {
49
64
if ( ! value ) {
50
- this . href$ . set ( null )
65
+ this . $href . set ( null )
51
66
return
52
67
}
53
68
54
69
try {
55
- this . href$ . set ( value ?. replace ( / / g, '' ) || '' )
70
+ this . $href . set ( value ?. replace ( / / g, '' ) || '' )
56
71
} catch ( error ) {
57
72
console . error ( 'ngx-href: Expecting a string' , '\n' , error )
58
73
}
@@ -68,30 +83,24 @@ export class NgxHrefDirective implements OnDestroy {
68
83
}
69
84
}
70
85
86
+ private _clickListener : any = null // EventListener | null
71
87
private _hrefAttr ?: string | null // spam protection
72
88
private _mouseenterListener : any = null // EventListener | null
73
- private _clickListener : any = null // EventListener | null
74
89
private _routeOnClick = false
75
90
76
- constructor (
77
- private _elementRef : ElementRef ,
78
- private _router : Router ,
79
- private _ngxHrefService : NgxHrefService ,
80
- ) { }
81
-
82
91
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 ( )
86
95
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' )
89
98
90
99
this . _mouseenterListener = ( ) => {
91
- if ( this . _hrefAttr ) this . href$ . set ( this . _hrefAttr )
100
+ if ( this . _hrefAttr ) this . $href . set ( this . _hrefAttr )
92
101
}
93
102
94
- this . _elementRef . nativeElement . addEventListener ( 'mouseenter' , this . _mouseenterListener )
103
+ this . #elementRef . nativeElement . addEventListener ( 'mouseenter' , this . _mouseenterListener )
95
104
}
96
105
97
106
if ( this . _tagName !== 'A' ) this . _prepareOpenLink ( )
@@ -102,39 +111,38 @@ export class NgxHrefDirective implements OnDestroy {
102
111
}
103
112
104
113
private _isLinkExternal ( ) : boolean {
105
- return this . href$ ( ) ?. startsWith ( 'http' ) ? true : false
114
+ return this . $href ( ) ?. startsWith ( 'http' ) ? true : false
106
115
}
107
116
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 )
111
119
112
120
this . _clickListener = ( event : PointerEvent ) => {
113
121
event . preventDefault ( )
114
122
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 ( ) )
117
125
}
118
126
119
- this . _elementRef . nativeElement . addEventListener ( 'click' , this . _clickListener )
127
+ this . #elementRef . nativeElement . addEventListener ( 'click' , this . _clickListener )
120
128
}
121
129
122
130
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
124
132
}
125
133
126
134
private _prepareScrollToLink ( ) {
127
135
this . _clickListener = ( event : PointerEvent ) => {
128
136
event . preventDefault ( )
129
137
130
- if ( this . href$ ( ) ) this . _ngxHrefService . scrollTo ( this . href$ ( ) ?. substring ( 1 ) )
138
+ if ( this . $href ( ) ) this . #ngxHrefService . scrollTo ( this . $href ( ) ?. substring ( 1 ) )
131
139
}
132
140
133
- this . _elementRef . nativeElement . addEventListener ( 'click' , this . _clickListener )
141
+ this . #elementRef . nativeElement . addEventListener ( 'click' , this . _clickListener )
134
142
}
135
143
136
144
ngOnDestroy ( ) : void {
137
145
if ( this . _mouseenterListener )
138
- this . _elementRef . nativeElement . removeEventListener ( 'mouseenter' , this . _mouseenterListener )
146
+ this . #elementRef . nativeElement . removeEventListener ( 'mouseenter' , this . _mouseenterListener )
139
147
}
140
148
}
0 commit comments