1
- import { Directive , ElementRef , HostBinding , HostListener , Input , OnDestroy } from '@angular/core'
1
+ import { Directive , ElementRef , HostListener , Input , OnDestroy , signal } from '@angular/core'
2
2
import { Router } from '@angular/router'
3
3
import { NgxHrefService } from './href.service'
4
4
5
5
@Directive ( {
6
6
standalone : true ,
7
7
selector : 'a[href], button[href]' ,
8
+ host : {
9
+ '[attr.rel]' : 'rel$()' ,
10
+ '[attr.target]' : 'target$()' ,
11
+ '[attr.href]' : 'href$()' ,
12
+ } ,
8
13
} )
9
14
export class NgxHrefDirective implements OnDestroy {
10
15
private _tagName : 'BUTTON' | 'A' = this . _elementRef . nativeElement . tagName
11
16
12
- @ HostBinding ( 'attr. rel' ) relAttr ?: string
13
- @ HostBinding ( 'attr. target' ) targetAttr ?: string
14
- @ HostBinding ( 'attr. href' ) hrefAttr : string | null = ''
17
+ rel$ = signal < string > ( '' )
18
+ target$ = signal < string > ( '' )
19
+ href$ = signal < string | null > ( '' )
15
20
16
21
@HostListener ( 'click' , [ '$event' ] ) onClick ( event : PointerEvent ) {
17
- if ( ! this . hrefAttr || ! this . _routeOnClick ) return
22
+ if ( ! this . href$ ( ) || ! this . _routeOnClick ) return
18
23
19
24
event . preventDefault ( )
20
25
21
- const fragments = this . hrefAttr . split ( '#' )
26
+ const fragments = this . href$ ( ) ?. split ( '#' )
27
+ if ( ! fragments ) return
22
28
23
29
if ( fragments . length >= 2 ) {
24
30
const urlFragments = this . _router . url . split ( '#' )
@@ -35,19 +41,19 @@ export class NgxHrefDirective implements OnDestroy {
35
41
}
36
42
37
43
@Input ( ) set rel ( value : string ) {
38
- this . relAttr = value
44
+ this . rel$ . set ( value )
39
45
}
40
46
@Input ( ) set target ( value : string ) {
41
- this . targetAttr = value
47
+ this . target$ . set ( value )
42
48
}
43
49
@Input ( ) set href ( value : string ) {
44
50
if ( ! value ) {
45
- this . hrefAttr = null
51
+ this . href$ . set ( null )
46
52
return
47
53
}
48
54
49
55
try {
50
- this . hrefAttr = value ?. replace ( / / g, '' ) || ''
56
+ this . href$ . set ( value ?. replace ( / / g, '' ) || '' )
51
57
} catch ( error ) {
52
58
console . error ( 'ngx-href: Expecting a string' , '\n' , error )
53
59
}
@@ -63,7 +69,7 @@ export class NgxHrefDirective implements OnDestroy {
63
69
}
64
70
}
65
71
66
- private _hrefAttr ?: string // spam protection
72
+ private _hrefAttr ?: string | null // spam protection
67
73
private _mouseenterListener : any = null // EventListener | null
68
74
private _clickListener : any = null // EventListener | null
69
75
private _routeOnClick = false
@@ -75,15 +81,15 @@ export class NgxHrefDirective implements OnDestroy {
75
81
) { }
76
82
77
83
private _isLinkMailOrPhone ( ) : boolean {
78
- if ( this . hrefAttr ?. startsWith ( 'mailto' ) || this . hrefAttr ?. startsWith ( 'tel' ) ) {
84
+ if ( this . href$ ( ) ?. startsWith ( 'mailto' ) || this . href$ ( ) ?. startsWith ( 'tel' ) ) {
79
85
if ( this . _ngxHrefService . avoidSpam ) {
80
- this . _hrefAttr = this . hrefAttr
86
+ this . _hrefAttr = this . href$ ( )
81
87
82
- if ( this . hrefAttr ?. startsWith ( 'mailto' ) ) this . hrefAttr = 'mailto:obfuscated'
83
- else this . hrefAttr = 'tel:obfuscated'
88
+ if ( this . href$ ( ) ?. startsWith ( 'mailto' ) ) this . href$ . set ( 'mailto:obfuscated' )
89
+ else this . href$ . set ( 'tel:obfuscated' )
84
90
85
91
this . _mouseenterListener = ( ) => {
86
- if ( this . _hrefAttr ) this . hrefAttr = this . _hrefAttr
92
+ if ( this . _hrefAttr ) this . href$ . set ( this . _hrefAttr )
87
93
}
88
94
89
95
this . _elementRef . nativeElement . addEventListener ( 'mouseenter' , this . _mouseenterListener )
@@ -97,32 +103,32 @@ export class NgxHrefDirective implements OnDestroy {
97
103
}
98
104
99
105
private _isLinkExternal ( ) : boolean {
100
- return this . hrefAttr ?. startsWith ( 'http' ) ? true : false
106
+ return this . href$ ( ) ?. startsWith ( 'http' ) ? true : false
101
107
}
102
108
private _prepareOpenLink ( ) {
103
- if ( ! this . relAttr && this . _ngxHrefService . defaultRelAttr )
104
- this . relAttr = this . _ngxHrefService . defaultRelAttr
105
- if ( ! this . targetAttr ) this . targetAttr = this . _ngxHrefService . defaultTargetAttr
109
+ if ( ! this . rel$ ( ) && this . _ngxHrefService . defaultRelAttr )
110
+ this . rel$ . set ( this . _ngxHrefService . defaultRelAttr )
111
+ if ( ! this . target$ ( ) ) this . target$ . set ( this . _ngxHrefService . defaultTargetAttr )
106
112
107
113
this . _clickListener = ( event : PointerEvent ) => {
108
114
event . preventDefault ( )
109
115
110
- const hrefAttr = this . _hrefAttr || this . hrefAttr
111
- if ( hrefAttr ) window . open ( hrefAttr , this . targetAttr , this . relAttr )
116
+ const hrefAttr = this . _hrefAttr || this . href$ ( )
117
+ if ( hrefAttr ) window . open ( hrefAttr , this . target$ ( ) , this . rel$ ( ) )
112
118
}
113
119
114
120
this . _elementRef . nativeElement . addEventListener ( 'click' , this . _clickListener )
115
121
}
116
122
117
123
private _isSamePageLink ( ) : boolean {
118
- return this . hrefAttr && this . hrefAttr [ 0 ] === '#' ? true : false
124
+ return this . href$ ( ) && ( this . href$ ( ) as any ) [ 0 ] === '#' ? true : false
119
125
}
120
126
121
127
private _prepareScrollToLink ( ) {
122
128
this . _clickListener = ( event : PointerEvent ) => {
123
129
event . preventDefault ( )
124
130
125
- if ( this . hrefAttr ) this . _ngxHrefService . scrollTo ( this . hrefAttr . substring ( 1 ) )
131
+ if ( this . href$ ( ) ) this . _ngxHrefService . scrollTo ( this . href$ ( ) ? .substring ( 1 ) )
126
132
}
127
133
128
134
this . _elementRef . nativeElement . addEventListener ( 'click' , this . _clickListener )
0 commit comments