@@ -97,6 +97,7 @@ class TcIntegrationLayout extends Component<TcIntegrationLayoutProps> {
97
97
98
98
window . addEventListener ( 'online' , this . updateOnlineStatus ) ;
99
99
window . addEventListener ( 'offline' , this . updateOnlineStatus ) ;
100
+ window . addEventListener ( 'click' , this . externalLinkHandler ) ;
100
101
}
101
102
102
103
componentDidUpdate ( prevProps : TcIntegrationLayoutProps ) {
@@ -112,6 +113,41 @@ class TcIntegrationLayout extends Component<TcIntegrationLayoutProps> {
112
113
window . removeEventListener ( 'offline' , this . updateOnlineStatus ) ;
113
114
}
114
115
116
+ externalLinkHandler = ( event : MouseEvent ) => {
117
+ // prettier is the worst
118
+
119
+ // if we're not clicking an anchor tag, there's nothing to do
120
+ const eventTarget = event . target as HTMLElement ;
121
+ if ( eventTarget ?. localName !== 'a' ) {
122
+ return ;
123
+ }
124
+
125
+ // if the target of the click isn't external, there's nothing to do
126
+ const target = eventTarget as HTMLAnchorElement ;
127
+ const url = new URL ( target . href ) ;
128
+ if ( url . host === window . location . host ) {
129
+ return ;
130
+ }
131
+
132
+ // stop the click so we can alter it
133
+ event . stopPropagation ( ) ;
134
+ event . preventDefault ( ) ;
135
+
136
+ // if this is a freecodecamp lesson, change its domain and path
137
+ if ( url . host === 'learn.freecodecamp.org' ) {
138
+ url . host = window . location . host ;
139
+ // TODO: it would be nice to not require that the FCC
140
+ // app knows about the paths in the platform UI, but
141
+ // creating a way to share this info would be complex and
142
+ // time consuming, so we can handle it when we get another
143
+ // provider.
144
+ url . pathname = `learn/freecodecamp/${ url . pathname } ` ;
145
+ }
146
+
147
+ // now open the url in a new tab
148
+ window . open ( url , '_blank' ) ;
149
+ } ;
150
+
115
151
updateOnlineStatus = ( ) => {
116
152
const { onlineStatusChange } = this . props ;
117
153
const isOnline =
0 commit comments