@@ -97,6 +97,33 @@ const handleExternalNavigation = (iframeLoadEvent, pluginHref) => {
9797 }
9898}
9999
100+ /**
101+ * Equivalent URLs:
102+ * <appRoot>/
103+ * <appRoot>/index.html
104+ * <appRoot>/index.html?redirect=false
105+ *
106+ * newUrl is expected to come from pluginHref,
107+ * and will always have /index.html?redirect=false
108+ */
109+ const isBaseEquivalent = ( currentUrlOrig , newUrlOrig ) => {
110+ // Copy before mutating
111+ const [ currentUrl , newUrl ] = [ new URL ( currentUrlOrig ) , new URL ( newUrlOrig ) ]
112+ newUrl . searchParams . sort ( )
113+ // If redirect is not already false in the search set that
114+ currentUrl . searchParams . set ( 'redirect' , 'false' )
115+ currentUrl . searchParams . sort ( )
116+ // If pathname doesn't end in html, add that
117+ if ( currentUrl . pathname . endsWith ( '/' ) ) {
118+ currentUrl . pathname = currentUrl . pathname + 'index.html'
119+ }
120+
121+ const [ newBase ] = newUrl . href . split ( '#' )
122+ const [ currentBase ] = currentUrl . href . split ( '#' )
123+
124+ return newBase === currentBase
125+ }
126+
100127const failedLoadErrorMessage =
101128 'The requested page is not accessible by the DHIS2 global shell, ' +
102129 'and the URL is therefore inaccessible to be printed here. ' +
@@ -179,10 +206,24 @@ export const PluginLoader = ({ appsInfoQuery }) => {
179206 return
180207 }
181208
209+ if ( ! iframeRef . current ) {
210+ return
211+ }
212+
213+ const newUrl = new URL ( pluginHref )
214+ const currentLocationUrl = new URL (
215+ iframeRef . current . contentWindow . location
216+ )
182217 // For further updates, replace iframe window location
183- if ( iframeRef . current ) {
218+ if ( ! isBaseEquivalent ( currentLocationUrl , newUrl ) ) {
219+ // If 'base' has changed, replace whole location
184220 iframeRef . current . contentWindow . location . replace ( pluginHref )
221+ } else if ( newUrl . hash !== currentLocationUrl . hash ) {
222+ // If 'base' is functionally equivalent, update just hash,
223+ // if it has changed. Tested and preserves location state
224+ iframeRef . current . contentWindow . location . hash = newUrl . hash
185225 }
226+ // Otherwise, URLs are identical; don't need to update
186227 } , [ pluginHref ] )
187228
188229 if ( error ) {
0 commit comments