Skip to content

Commit 1690454

Browse files
authored
Merge pull request #15 from cloud-py-api/feat/ui/iframe-frontend-routing-sync
feat(ui): add iframe frontend routing sync
2 parents 444090a + 936a1a4 commit 1690454

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

ex_app/src/views/IframeView.vue

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
2727
import AlertCircleIcon from 'vue-material-design-icons/AlertCircle.vue'
2828
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
2929
30-
import { APP_API_PROXY_URL_PREFIX, EX_APP_ID } from '../constants/AppAPI.js'
30+
import {
31+
APP_API_PROXY_URL_PREFIX,
32+
APP_API_ROUTER_BASE,
33+
EX_APP_ID,
34+
EX_APP_MENU_ENTRY_NAME,
35+
} from '../constants/AppAPI.js'
3136
3237
import { getFilePickerBuilder } from '@nextcloud/dialogs'
3338
import '@nextcloud/dialogs/style.css'
@@ -42,10 +47,13 @@ export default {
4247
data() {
4348
const baseUrl = generateUrl(`${APP_API_PROXY_URL_PREFIX}/${EX_APP_ID}/`, {}, { noRewrite: true })
4449
const iframeSrcUrl = process.env.HARP_ENABLED ? baseUrl.replace('/index.php', '') : baseUrl
50+
4551
return {
4652
error: null,
4753
loading: true,
48-
iframeSrc: iframeSrcUrl,
54+
iframeBaseUrl: baseUrl,
55+
pageBaseUrl: generateUrl(`${APP_API_ROUTER_BASE}/${EX_APP_ID}/${EX_APP_MENU_ENTRY_NAME}`),
56+
iframeSrc: this.loadIframeSrcUrlRoute(baseUrl, iframeSrcUrl),
4957
}
5058
},
5159
mounted() {
@@ -63,10 +71,14 @@ export default {
6371
this.error = true
6472
this.loading = false
6573
})
74+
6675
window.addEventListener('message', (event) => {
6776
if (event.data.type === 'openNextcloudFilePicker') {
6877
this.showFilePicker(event)
6978
}
79+
if (event.data.type === 'routeChange') {
80+
this.handleIframeRouteChange(event.data.route)
81+
}
7082
})
7183
},
7284
methods: {
@@ -95,6 +107,51 @@ export default {
95107
})
96108
this.$refs.iframe.contentWindow.postMessage({ files, inputParamName }, '*')
97109
},
110+
loadIframeSrcUrlRoute(iframeSrcUrl) {
111+
const pageBaseUrl = generateUrl(`${APP_API_ROUTER_BASE}/${EX_APP_ID}/${EX_APP_MENU_ENTRY_NAME}`)
112+
const pagePathRoute = window.location.pathname
113+
.replace(pageBaseUrl, '')
114+
// fix duplicate slashes, remove starting slash
115+
const normalizedPath = pagePathRoute.replace(/^\//, '').replace(/\/\//g, '/')
116+
117+
if (iframeSrcUrl.endsWith('/')) {
118+
iframeSrcUrl = `${iframeSrcUrl}${normalizedPath}`
119+
} else {
120+
iframeSrcUrl = `${iframeSrcUrl}/${normalizedPath}`
121+
}
122+
123+
// always append ending slash if it is not present
124+
if (!iframeSrcUrl.endsWith('/')) {
125+
iframeSrcUrl += '/'
126+
}
127+
128+
return iframeSrcUrl
129+
},
130+
handleIframeRouteChange(route) {
131+
if (!route) {
132+
return
133+
}
134+
135+
const pageBaseUrl = generateUrl(`${APP_API_ROUTER_BASE}/${EX_APP_ID}/${EX_APP_MENU_ENTRY_NAME}`)
136+
// Update window route part after the root path
137+
let normalizedPath = route
138+
if (route !== '/') {
139+
normalizedPath = route.replace(/^\//, '').replace(/\/\//g, '/')
140+
if (this.pageBaseUrl.endsWith('/')) {
141+
this.pageBaseUrl = `${pageBaseUrl}${normalizedPath}`
142+
} else {
143+
this.pageBaseUrl = `${pageBaseUrl}/${normalizedPath}`
144+
}
145+
} else {
146+
this.pageBaseUrl = pageBaseUrl
147+
}
148+
149+
// replace potential duplicate slashes
150+
this.pageBaseUrl = this.pageBaseUrl.replace(/\/\//g, '/')
151+
152+
// change the window path, without history
153+
window.history.replaceState({}, '', this.pageBaseUrl)
154+
},
98155
},
99156
}
100157
</script>

0 commit comments

Comments
 (0)