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