From f9dd249a2172658ff30ef81b86222946346bc21f Mon Sep 17 00:00:00 2001 From: Pascal Barth Date: Thu, 4 Jul 2024 13:54:10 +0200 Subject: [PATCH 1/6] PB-704 : remove embed shortlink generation the old viewer was letting the param go unchanged/unshorten, and this will ease the update of the iframe code snippet (no need to trigger a shortlink for every little change in the preview) --- .../menu/components/share/MenuShareEmbed.vue | 16 +++++---------- .../components/share/MenuShareSection.vue | 3 +-- src/store/modules/share.store.js | 20 ------------------- 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/src/modules/menu/components/share/MenuShareEmbed.vue b/src/modules/menu/components/share/MenuShareEmbed.vue index c1af4bea1..9c2fea3a9 100644 --- a/src/modules/menu/components/share/MenuShareEmbed.vue +++ b/src/modules/menu/components/share/MenuShareEmbed.vue @@ -9,12 +9,13 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' // importing directly the vue component, see https://github.com/ivanvermeyen/vue-collapse-transition/issues/5 import CollapseTransition from '@ivanv/vue-collapse-transition/src/CollapseTransition.vue' -import { computed, nextTick, ref, toRefs } from 'vue' +import { computed, nextTick, ref } from 'vue' import MenuShareInputCopyButton from '@/modules/menu/components/share/MenuShareInputCopyButton.vue' import ModalWithBackdrop from '@/utils/components/ModalWithBackdrop.vue' import { useTippyTooltip } from '@/utils/composables/useTippyTooltip' import log from '@/utils/logging' +import { transformUrlMapToEmbed } from '@/utils/utils' /** * Different pre-defined sizes that an iFrame can take @@ -45,14 +46,6 @@ const EmbedSizes = { useTippyTooltip('.menu-share-embed [data-tippy-content]') -const props = defineProps({ - shortLink: { - type: String, - default: null, - }, -}) -const { shortLink } = toRefs(props) - const embedInput = ref(null) const showEmbedSharing = ref(false) const showPreviewModal = ref(false) @@ -64,6 +57,7 @@ const customSize = ref({ }) const copied = ref(false) +const embedSource = ref(transformUrlMapToEmbed(window.location.href)) const embedPreviewModalWidth = computed(() => { // Uses the iframe's width as maximal width for the entire modal window let style = { 'max-width': iFrameWidth.value } @@ -96,7 +90,7 @@ const iFrameStyle = computed( ) const iFrameLink = computed( () => - `` + `` ) const buttonIcon = computed(() => { if (copied.value) { @@ -270,7 +264,7 @@ async function copyValue() { diff --git a/src/modules/menu/components/share/MenuShareSection.vue b/src/modules/menu/components/share/MenuShareSection.vue index d9f8290de..7f5c5d573 100644 --- a/src/modules/menu/components/share/MenuShareSection.vue +++ b/src/modules/menu/components/share/MenuShareSection.vue @@ -19,7 +19,7 @@ :small="compact" /> - + @@ -55,7 +55,6 @@ export default { computed: { ...mapState({ shortLink: (state) => state.share.shortLink, - embeddedShortLink: (state) => state.share.embeddedShortLink, isSectionShown: (state) => state.share.isMenuSectionShown, isTrackingGeolocation: (state) => state.geolocation.active && state.geolocation.tracking, diff --git a/src/store/modules/share.store.js b/src/store/modules/share.store.js index 0ce4f17d5..24a0cedf9 100644 --- a/src/store/modules/share.store.js +++ b/src/store/modules/share.store.js @@ -1,6 +1,5 @@ import { createShortLink } from '@/api/shortlink.api' import log from '@/utils/logging' -import { transformUrlMapToEmbed } from '@/utils/utils' export default { state: { @@ -12,11 +11,6 @@ export default { * @type String */ shortLink: null, - /** - * Same thing as shortLink, but with the flag embed=true send to the backend before - * shortening - */ - embeddedShortLink: null, /** * The state of the shortlink share menu section. As we need to be able to change this * whenever the user moves the map, and it should only be done within mutations. @@ -37,16 +31,6 @@ export default { log.error('Error while creating short link for', window.location.href, err) commit('setShortLink', { shortLink: window.location.href, dispatcher }) } - const embedUrl = transformUrlMapToEmbed(window.location.href) - try { - const embeddedShortLink = await createShortLink(embedUrl) - if (embeddedShortLink) { - commit('setEmbeddedShortLink', { shortLink: embeddedShortLink, dispatcher }) - } - } catch (err) { - log.error('Error while creating embedded short link for', embedUrl, err) - commit('setEmbeddedShortLink', { shortLink: embedUrl, dispatcher }) - } }, closeShareMenuAndRemoveShortLinks({ commit, dispatch }, { dispatcher }) { commit('setIsMenuSectionShown', { show: false, dispatcher }) @@ -57,16 +41,12 @@ export default { }, clearShortLinks({ commit }, { dispatcher }) { commit('setShortLink', { shortLink: null, dispatcher }) - commit('setEmbeddedShortLink', { shortLink: null, dispatcher }) }, }, mutations: { setShortLink(state, { shortLink }) { state.shortLink = shortLink }, - setEmbeddedShortLink(state, { shortLink }) { - state.embeddedShortLink = shortLink - }, setIsMenuSectionShown(state, { show }) { state.isMenuSectionShown = show }, From 431ae78af76ddfba597d5b9e4efcff8a7318512a Mon Sep 17 00:00:00 2001 From: Pascal Barth Date: Thu, 4 Jul 2024 13:54:51 +0200 Subject: [PATCH 2/6] PB-704 : cleanup old i18n use --- .../menu/components/share/MenuShareEmbed.vue | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/modules/menu/components/share/MenuShareEmbed.vue b/src/modules/menu/components/share/MenuShareEmbed.vue index 9c2fea3a9..efc41242f 100644 --- a/src/modules/menu/components/share/MenuShareEmbed.vue +++ b/src/modules/menu/components/share/MenuShareEmbed.vue @@ -10,6 +10,7 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' // importing directly the vue component, see https://github.com/ivanvermeyen/vue-collapse-transition/issues/5 import CollapseTransition from '@ivanv/vue-collapse-transition/src/CollapseTransition.vue' import { computed, nextTick, ref } from 'vue' +import { useI18n } from 'vue-i18n' import MenuShareInputCopyButton from '@/modules/menu/components/share/MenuShareInputCopyButton.vue' import ModalWithBackdrop from '@/utils/components/ModalWithBackdrop.vue' @@ -57,6 +58,8 @@ const customSize = ref({ }) const copied = ref(false) +const { t } = useI18n() + const embedSource = ref(transformUrlMapToEmbed(window.location.href)) const embedPreviewModalWidth = computed(() => { // Uses the iframe's width as maximal width for the entire modal window @@ -143,7 +146,7 @@ async function copyValue() { :class="{ 'text-primary': showEmbedSharing }" :icon="`caret-${showEmbedSharing ? 'down' : 'right'}`" /> - {{ $t('share_more') }} + {{ t('share_more') }}
@@ -176,17 +179,17 @@ async function copyValue() { data-cy="menu-share-embed-preview-button" @click="togglePreviewModal" > - {{ $t('show_more_options') }} + {{ t('show_more_options') }}
-
+
@@ -204,7 +207,7 @@ async function copyValue() { class="embed-preview-modal-size-selector-option" :data-cy="`menu-share-embed-iframe-size-${size.i18nKey.toLowerCase()}`" > - {{ $t(size.i18nKey) }} + {{ t(size.i18nKey) }}
@@ -243,7 +246,7 @@ async function copyValue() { data-cy="menu-share-embed-iframe-full-width" />
@@ -262,15 +265,14 @@ async function copyValue() {
-
+
From fdbbc8619823fa744e005f36e26d8e5787d8c971 Mon Sep 17 00:00:00 2001 From: Pascal Barth Date: Thu, 4 Jul 2024 13:56:05 +0200 Subject: [PATCH 3/6] PB-704 : add new change event triggered to iframe parent it will be triggered when route query changes, as it is not possible with VueJS to get the current SRC attribute of an iframe (it always returns the value that was set with :src, without updating it...) This way we can receive the new state of the iframe and update the code snippet accordingly --- src/api/iframeFeatureEvent.api.js | 30 ++++++++++++++++++- .../menu/components/share/MenuShareEmbed.vue | 12 ++++++++ src/views/EmbedView.vue | 7 ++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/api/iframeFeatureEvent.api.js b/src/api/iframeFeatureEvent.api.js index 5f14753ac..979ffd6ed 100644 --- a/src/api/iframeFeatureEvent.api.js +++ b/src/api/iframeFeatureEvent.api.js @@ -1,5 +1,7 @@ import log from '@/utils/logging.js' +const targetWindow = parent ?? window.parent ?? window.opener ?? window.top + /** * Sends information to the iFrame's parent about features, through the use of the postMessage * HTML/Javascript API. @@ -7,9 +9,9 @@ import log from '@/utils/logging.js' * @param {LayerFeature[]} features List of features for which we want to send information to the * iFrame's parent * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage + * @see https://codepen.io/geoadmin/pen/yOBzqM?editors=0010 */ export function sendFeatureInformationToIFrameParent(features) { - const targetWindow = parent ?? window.parent ?? window.opener ?? window.top if (!targetWindow) { log.debug( 'Embed view loaded as root document of a browser tab, cannot communicate with opener/parent' @@ -43,3 +45,29 @@ export function sendFeatureInformationToIFrameParent(features) { // so let's not implement this format in the new viewer and see what happens. }) } + +/** + * Is used to notify the parent the state of the app has changed. While embedding with VueJS, it's + * not possible to watch the iFrame src attribute, so an event is required to be notified of a + * children change. + * + * This is mainly used so that the iframe generator (menu share -> embed) can change the iframe + * snippet if the user decide to move / zoom the map while looking at the preview + */ +export function sendChangeEventToParent() { + if (!targetWindow) { + log.debug( + 'Embed view loaded as root document of a browser tab, cannot communicate with opener/parent' + ) + return + } + targetWindow.postMessage( + { + type: 'gaChange', + payload: { + newUrl: window.location.href, + }, + }, + '*' + ) +} diff --git a/src/modules/menu/components/share/MenuShareEmbed.vue b/src/modules/menu/components/share/MenuShareEmbed.vue index efc41242f..d4827a267 100644 --- a/src/modules/menu/components/share/MenuShareEmbed.vue +++ b/src/modules/menu/components/share/MenuShareEmbed.vue @@ -117,6 +117,18 @@ function toggleEmbedSharing() { function togglePreviewModal() { showPreviewModal.value = !showPreviewModal.value + if (showPreviewModal.value) { + window.addEventListener('message', onPreviewChange) + } else { + window.removeEventListener('message', onPreviewChange) + } +} + +function onPreviewChange(e) { + if (e?.data?.type === 'gaChange') { + // see iframeFeatureEvent.api.js -> sendChangeEventToParent + embedSource.value = e.data.payload.newUrl + } } async function copyValue() { diff --git a/src/views/EmbedView.vue b/src/views/EmbedView.vue index 68c6990aa..d6042bdba 100644 --- a/src/views/EmbedView.vue +++ b/src/views/EmbedView.vue @@ -1,7 +1,9 @@