@erst-vg/vg-design-wrapper 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/package.json +2 -2
- package/src/components/VgKalturaVideo.vue +0 -70
- package/src/components/VgVideo.vue +0 -65
- package/src/components/VgVideoToolVideo.vue +0 -70
- package/src/components/VgVimeoVideo.vue +0 -64
- package/src/styles/custom/_vgVideo.scss +0 -86
- package/src/styles/custom/_vgVideoFrame.scss +0 -9
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erst-vg/vg-design-wrapper",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"prettiercheck": "prettier --check \"**/*.{vue,ts}\" "
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
+
"@types/node": "24.9.2",
|
|
46
47
|
"axios": "1.12.2",
|
|
47
48
|
"dkfds": "npm:@erst-vg/dkfds-vite@8.0.1",
|
|
48
49
|
"lodash": "4.17.21",
|
|
@@ -56,7 +57,6 @@
|
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@stylistic/eslint-plugin": "2.6.2",
|
|
58
59
|
"@types/lodash": "4.17.7",
|
|
59
|
-
"@types/node": "24.9.2",
|
|
60
60
|
"@typescript-eslint/eslint-plugin": "8.45.0",
|
|
61
61
|
"@vitejs/plugin-vue": "5.2.3",
|
|
62
62
|
"@vitest/coverage-v8": "3.2.4",
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<iframe
|
|
4
|
-
v-if="playVideo && videoUrl"
|
|
5
|
-
:src="videoUrl"
|
|
6
|
-
:alt="alt"
|
|
7
|
-
class="video-frame"
|
|
8
|
-
title="Kaltura afspiller"
|
|
9
|
-
allow="autoplay"
|
|
10
|
-
allowfullscreen
|
|
11
|
-
webkitallowfullscreen
|
|
12
|
-
mozAllowFullScreen
|
|
13
|
-
data-testid="video-frame"
|
|
14
|
-
/>
|
|
15
|
-
<slot name="preview" :thumbnail-url="thumbnailUrl" />
|
|
16
|
-
</div>
|
|
17
|
-
</template>
|
|
18
|
-
|
|
19
|
-
<script setup lang="ts">
|
|
20
|
-
import { computed } from 'vue';
|
|
21
|
-
|
|
22
|
-
const props = defineProps({
|
|
23
|
-
src: {
|
|
24
|
-
type: String,
|
|
25
|
-
required: true
|
|
26
|
-
},
|
|
27
|
-
alt: {
|
|
28
|
-
type: String,
|
|
29
|
-
required: true
|
|
30
|
-
},
|
|
31
|
-
playVideo: {
|
|
32
|
-
type: Boolean,
|
|
33
|
-
required: true
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const videoUrl = computed(() => {
|
|
38
|
-
let link = props.src;
|
|
39
|
-
const autoPlay = 'flashvars[autoPlay]';
|
|
40
|
-
if (!link.includes(autoPlay)) {
|
|
41
|
-
link = addQuerystring(link, `${autoPlay}=true`);
|
|
42
|
-
}
|
|
43
|
-
return link;
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const thumbnailUrl = computed<string>(() => {
|
|
47
|
-
let url = '';
|
|
48
|
-
const groups = props.src.match(/https:\/\/(.*)\/p\/(\d*)\/.*?.*entry_id=([a-zA-Z0-9_]+)(?=&|$)/); // NOSONAR
|
|
49
|
-
if (groups?.length === 4) {
|
|
50
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
51
|
-
const [_, domain, partnerId, entryId] = groups;
|
|
52
|
-
url = `https://${domain}/p/${partnerId}/thumbnail/entry_id/${entryId}/width/800/quality/100`;
|
|
53
|
-
}
|
|
54
|
-
return url;
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
function addQuerystring(url: string, query: string): string {
|
|
58
|
-
const firstParamPrefix = '?';
|
|
59
|
-
const subsequentParamPrefix = '&';
|
|
60
|
-
if (query.indexOf(firstParamPrefix) === 0 || query.indexOf(subsequentParamPrefix) === 0) {
|
|
61
|
-
query = query.substring(1);
|
|
62
|
-
}
|
|
63
|
-
const qsPrefix = url.indexOf(firstParamPrefix) > 0 ? subsequentParamPrefix : firstParamPrefix;
|
|
64
|
-
return url + qsPrefix + query;
|
|
65
|
-
}
|
|
66
|
-
</script>
|
|
67
|
-
|
|
68
|
-
<style lang="scss" scoped>
|
|
69
|
-
@use '@/styles/custom/_vgVideoFrame.scss';
|
|
70
|
-
</style>
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="video">
|
|
3
|
-
<component :is="videoudbyder" :src="src" :alt="alt" :play-video="playVideo" class="video-player">
|
|
4
|
-
<template #preview="{ thumbnailUrl }">
|
|
5
|
-
<div v-if="!playVideo">
|
|
6
|
-
<button class="button-wrapper" aria-label="Afspil video" title="Afspil video" type="button" @click="playVideo = true">
|
|
7
|
-
<VgIcon icon="playVideo" />
|
|
8
|
-
<div class="video-frame" :style="thumbnailUrl && { 'background-image': 'url(' + thumbnailUrl + ')' }" />
|
|
9
|
-
</button>
|
|
10
|
-
</div>
|
|
11
|
-
</template>
|
|
12
|
-
</component>
|
|
13
|
-
<div class="cookie-banner">
|
|
14
|
-
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
15
|
-
<div v-html="cookiebanner" />
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
</template>
|
|
19
|
-
|
|
20
|
-
<script setup lang="ts">
|
|
21
|
-
import VgIcon from '@/components/VgIcon.vue';
|
|
22
|
-
import VgKalturaVideo from '@/components/VgKalturaVideo.vue';
|
|
23
|
-
import VgVideoToolVideo from '@/components/VgVideoToolVideo.vue';
|
|
24
|
-
import VgVimeoVideo from '@/components/VgVimeoVideo.vue';
|
|
25
|
-
import { computed, ref } from 'vue';
|
|
26
|
-
|
|
27
|
-
const components = {
|
|
28
|
-
VgVimeoVideo,
|
|
29
|
-
VgVideoToolVideo,
|
|
30
|
-
VgKalturaVideo
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const props = defineProps({
|
|
34
|
-
src: {
|
|
35
|
-
type: String,
|
|
36
|
-
required: true
|
|
37
|
-
},
|
|
38
|
-
alt: {
|
|
39
|
-
type: String,
|
|
40
|
-
required: true
|
|
41
|
-
},
|
|
42
|
-
cookiebanner: {
|
|
43
|
-
type: String,
|
|
44
|
-
required: true
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const playVideo = ref(false);
|
|
49
|
-
|
|
50
|
-
const videoudbyder = computed(() => {
|
|
51
|
-
if (props.src.includes('vimeo')) {
|
|
52
|
-
return components.VgVimeoVideo;
|
|
53
|
-
} else if (props.src.includes('videotool')) {
|
|
54
|
-
return components.VgVideoToolVideo;
|
|
55
|
-
} else if (props.src.includes('kaltura')) {
|
|
56
|
-
return components.VgKalturaVideo;
|
|
57
|
-
}
|
|
58
|
-
return '';
|
|
59
|
-
});
|
|
60
|
-
</script>
|
|
61
|
-
|
|
62
|
-
<style lang="scss" scoped>
|
|
63
|
-
@use '@/styles/custom/_vgVideo.scss';
|
|
64
|
-
@use '@/styles/custom/_vgVideoFrame.scss';
|
|
65
|
-
</style>
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<iframe
|
|
4
|
-
v-if="playVideo"
|
|
5
|
-
class="video-frame"
|
|
6
|
-
title="Videotool player"
|
|
7
|
-
type="text/html"
|
|
8
|
-
:alt="alt"
|
|
9
|
-
:src="src"
|
|
10
|
-
webkitallowfullscreen
|
|
11
|
-
mozallowfullscreen
|
|
12
|
-
allowfullscreen
|
|
13
|
-
allow="autoplay; fullscreen"
|
|
14
|
-
data-testid="iframe"
|
|
15
|
-
></iframe>
|
|
16
|
-
<slot name="preview" :thumbnail-url="thumbnailUrl" />
|
|
17
|
-
</div>
|
|
18
|
-
</template>
|
|
19
|
-
|
|
20
|
-
<script setup lang="ts">
|
|
21
|
-
import axios, { AxiosRequestConfig } from 'axios';
|
|
22
|
-
import { onMounted, ref } from 'vue';
|
|
23
|
-
|
|
24
|
-
const props = defineProps({
|
|
25
|
-
src: {
|
|
26
|
-
type: String,
|
|
27
|
-
required: true
|
|
28
|
-
},
|
|
29
|
-
alt: {
|
|
30
|
-
type: String,
|
|
31
|
-
required: true
|
|
32
|
-
},
|
|
33
|
-
playVideo: {
|
|
34
|
-
type: Boolean,
|
|
35
|
-
required: true
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
const thumbnailUrl = ref<string>('');
|
|
40
|
-
|
|
41
|
-
onMounted(async () => {
|
|
42
|
-
getThumbnailUrl(props.src).then(url => (thumbnailUrl.value = url));
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
async function getThumbnailUrl(pageUrl: string): Promise<string> {
|
|
46
|
-
let url = '';
|
|
47
|
-
const options: AxiosRequestConfig = {
|
|
48
|
-
method: 'GET',
|
|
49
|
-
headers: { 'content-type': 'text/html' },
|
|
50
|
-
url: pageUrl
|
|
51
|
-
};
|
|
52
|
-
try {
|
|
53
|
-
const xhr = await axios(options);
|
|
54
|
-
if (xhr) {
|
|
55
|
-
const groups = xhr.data?.match(/<meta property="og:image" content="https:(.*?)">/);
|
|
56
|
-
if (groups?.length > 0) {
|
|
57
|
-
url = groups[1];
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
} catch {
|
|
61
|
-
// eslint-disable-next-line no-console
|
|
62
|
-
console.log(`Error resolving thumbnail url from "${pageUrl}"`);
|
|
63
|
-
}
|
|
64
|
-
return url;
|
|
65
|
-
}
|
|
66
|
-
</script>
|
|
67
|
-
|
|
68
|
-
<style lang="scss" scoped>
|
|
69
|
-
@use '@/styles/custom/_vgVideoFrame.scss';
|
|
70
|
-
</style>
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<iframe
|
|
4
|
-
v-if="playVideo && videoUrl"
|
|
5
|
-
class="video-frame"
|
|
6
|
-
title="Vimeo afspiller"
|
|
7
|
-
:alt="alt"
|
|
8
|
-
:src="videoUrl"
|
|
9
|
-
webkitallowfullscreen
|
|
10
|
-
mozallowfullscreen
|
|
11
|
-
allowfullscreen
|
|
12
|
-
allow="autoplay"
|
|
13
|
-
></iframe>
|
|
14
|
-
<slot name="preview" :thumbnail-url="thumbnailUrl" />
|
|
15
|
-
</div>
|
|
16
|
-
</template>
|
|
17
|
-
|
|
18
|
-
<script setup lang="ts">
|
|
19
|
-
import axios, { AxiosPromise } from 'axios';
|
|
20
|
-
import { onMounted, ref } from 'vue';
|
|
21
|
-
|
|
22
|
-
const props = defineProps({
|
|
23
|
-
src: {
|
|
24
|
-
type: String,
|
|
25
|
-
required: true
|
|
26
|
-
},
|
|
27
|
-
alt: {
|
|
28
|
-
type: String,
|
|
29
|
-
required: true
|
|
30
|
-
},
|
|
31
|
-
playVideo: {
|
|
32
|
-
type: Boolean,
|
|
33
|
-
required: true
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const videoUrl = ref('');
|
|
38
|
-
const thumbnailUrl = ref('');
|
|
39
|
-
const baseOembedVimeoUrl = 'https://vimeo.com/api/oembed.json';
|
|
40
|
-
|
|
41
|
-
const getVimeoVideo = (link: string, params: { [key: string]: string } = {}): AxiosPromise => {
|
|
42
|
-
const urlParams = new URLSearchParams(params).toString();
|
|
43
|
-
const qs = urlParams ? `&${urlParams}` : '';
|
|
44
|
-
return axios.get(`${baseOembedVimeoUrl}?url=${encodeURIComponent(link)}${qs}`);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
onMounted((): void => {
|
|
48
|
-
getVimeoVideo(props.src, { dnt: '1', autoplay: '1' }).then(response => {
|
|
49
|
-
const thumbnailUrlResponse: string = response.data.thumbnail_url;
|
|
50
|
-
if (thumbnailUrlResponse) {
|
|
51
|
-
// Fjerner angivelse af billedeopløsning, for at få billede i fuld størrelse. Linket slutter på fx -d_123x123
|
|
52
|
-
const index = thumbnailUrlResponse.indexOf('-d_');
|
|
53
|
-
thumbnailUrl.value = index !== -1 ? thumbnailUrlResponse.slice(0, index + 2) : thumbnailUrlResponse;
|
|
54
|
-
}
|
|
55
|
-
const { html } = response.data;
|
|
56
|
-
// extract the src attribute from the iframe
|
|
57
|
-
videoUrl.value = html.match(/src="(.*?)"/)![1];
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
</script>
|
|
61
|
-
|
|
62
|
-
<style lang="scss" scoped>
|
|
63
|
-
@use '@/styles/custom/_vgVideoFrame.scss';
|
|
64
|
-
</style>
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
@use '@/styles/utility' as *;
|
|
2
|
-
|
|
3
|
-
.video {
|
|
4
|
-
.video-player {
|
|
5
|
-
position: relative;
|
|
6
|
-
overflow: hidden;
|
|
7
|
-
padding-top: 56.25%;
|
|
8
|
-
width: 100%;
|
|
9
|
-
background-color: $color-very-dark-gray;
|
|
10
|
-
|
|
11
|
-
.button-wrapper {
|
|
12
|
-
display: flex;
|
|
13
|
-
align-items: center;
|
|
14
|
-
justify-content: center;
|
|
15
|
-
height: 100%;
|
|
16
|
-
width: 100%;
|
|
17
|
-
position: absolute;
|
|
18
|
-
top: 0;
|
|
19
|
-
border: none;
|
|
20
|
-
left: 0;
|
|
21
|
-
|
|
22
|
-
&:focus {
|
|
23
|
-
.icon-svg {
|
|
24
|
-
outline: 2px solid $color-black !important;
|
|
25
|
-
border-radius: 50%;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.icon-svg {
|
|
30
|
-
color: var(--site-primary);
|
|
31
|
-
width: 72px;
|
|
32
|
-
height: 72px;
|
|
33
|
-
position: relative;
|
|
34
|
-
z-index: 3;
|
|
35
|
-
|
|
36
|
-
@include media-breakpoint-down-em(sm) {
|
|
37
|
-
width: 1.5em;
|
|
38
|
-
height: 1.5em;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
&:hover {
|
|
42
|
-
cursor: pointer;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
:deep(*) {
|
|
46
|
-
color: var(--site-primary);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.video-frame {
|
|
52
|
-
position: absolute;
|
|
53
|
-
background-size: cover;
|
|
54
|
-
background-repeat: no-repeat;
|
|
55
|
-
display: flex;
|
|
56
|
-
align-items: center;
|
|
57
|
-
justify-content: center;
|
|
58
|
-
background-color: $background-alternative;
|
|
59
|
-
cursor: pointer;
|
|
60
|
-
width: 100%;
|
|
61
|
-
|
|
62
|
-
&:before {
|
|
63
|
-
content: '';
|
|
64
|
-
position: absolute;
|
|
65
|
-
background-color: rgba($color-very-dark-blue, 0.25);
|
|
66
|
-
height: 100%;
|
|
67
|
-
width: 100%;
|
|
68
|
-
top: 0;
|
|
69
|
-
left: 0;
|
|
70
|
-
z-index: 2;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.cookie-banner {
|
|
76
|
-
width: 100%;
|
|
77
|
-
font-size: 0.875em;
|
|
78
|
-
font-style: italic;
|
|
79
|
-
color: $color-grey-1;
|
|
80
|
-
padding-top: 16px;
|
|
81
|
-
|
|
82
|
-
:deep(a) {
|
|
83
|
-
color: $color-grey-1 !important;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|