@internetstiftelsen/styleguide 2.24.30-beta.0.1 → 2.24.30-beta.0.3
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/dist/organisms/video-guide/VideoGuidePlayback.js +250 -0
- package/dist/organisms/video-guide/VideoGuideSubtitles.js +67 -0
- package/dist/organisms/video-guide/VideoGuideTimeline.js +100 -0
- package/dist/organisms/video-guide/getCurrentCueIndex.js +13 -0
- package/dist/organisms/video-guide/video-guide.js +73 -239
- package/package.json +1 -1
- package/src/assets/video/guidad-tur-nar-internet-kom-chapters.vtt +22 -0
- package/src/assets/video/guidad-tur-nar-internet-kom-metadata.vtt +89 -0
- package/src/assets/video/guidad-tur-nar-internet-kom-till-svenska-hem-undertexter.vtt +474 -0
- package/src/organisms/timeline/_timeline.scss +1 -0
- package/src/organisms/video-guide/VideoGuidePlayback.js +213 -0
- package/src/organisms/video-guide/VideoGuideSubtitles.js +43 -0
- package/src/organisms/video-guide/VideoGuideTimeline.js +76 -0
- package/src/organisms/video-guide/_video-guide.scss +13 -3
- package/src/organisms/video-guide/getCurrentCueIndex.js +6 -0
- package/src/organisms/video-guide/video-guide.config.js +3 -3
- package/src/organisms/video-guide/video-guide.js +48 -244
- package/src/assets/video/chapters.vtt +0 -25
- package/src/assets/video/metadata.vtt +0 -28
- package/src/assets/video/movie-webm.webm +0 -0
- package/src/assets/video/videoplayer.vtt +0 -25
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export default class VideoGuideSubtitles {
|
|
2
|
+
constructor(element, video) {
|
|
3
|
+
this.element = element;
|
|
4
|
+
this.video = video;
|
|
5
|
+
this.subtitlesBtn = element.querySelector('.js-subtitles-btn');
|
|
6
|
+
this.subtitlesContainer = element.querySelector('.js-subtitles-container');
|
|
7
|
+
|
|
8
|
+
this.init();
|
|
9
|
+
this.attach();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
init() {
|
|
13
|
+
this.subtitles = this.video.textTracks.getTrackById('video-subtitles');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
attach() {
|
|
17
|
+
this.subtitlesBtn.addEventListener('click', this.toggleSubtitles);
|
|
18
|
+
this.subtitles.addEventListener('cuechange', this.onCueChange);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
clearSubtitles() {
|
|
22
|
+
this.subtitlesContainer.innerHTML = '';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
onEnded = () => {
|
|
26
|
+
this.clearSubtitles();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
onCueChange = () => {
|
|
30
|
+
const { activeCues } = this.subtitles;
|
|
31
|
+
|
|
32
|
+
if (activeCues.length > 0) {
|
|
33
|
+
this.subtitlesContainer.innerHTML = `<span>${activeCues[0].text}</span>`;
|
|
34
|
+
} else {
|
|
35
|
+
this.clearSubtitles();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
toggleSubtitles = () => {
|
|
40
|
+
this.subtitlesBtn.classList.toggle('is-active');
|
|
41
|
+
this.subtitlesContainer.classList.toggle('is-visible');
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export default class VideoGuideTimeline {
|
|
2
|
+
constructor(element, video) {
|
|
3
|
+
this.element = element;
|
|
4
|
+
this.video = video;
|
|
5
|
+
this.container = element.querySelector('.js-timeline-posts');
|
|
6
|
+
this.posts = Array.from(element.querySelectorAll('.js-timeline-post'));
|
|
7
|
+
this.toggleBtn = element.querySelector('.js-show-timelineposts');
|
|
8
|
+
this.headlineTpl = element.querySelector('[data-video-headline-tpl]');
|
|
9
|
+
this.headlineCache = {};
|
|
10
|
+
|
|
11
|
+
this.init();
|
|
12
|
+
this.attach();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
init() {
|
|
16
|
+
this.meta = this.video.textTracks.getTrackById('video-metadata');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
attach() {
|
|
20
|
+
this.meta.addEventListener('cuechange', this.onCueChange);
|
|
21
|
+
|
|
22
|
+
if (this.toggleBtn) {
|
|
23
|
+
this.toggleBtn.addEventListener('click', this.togglePosts);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
togglePosts = () => {
|
|
28
|
+
this.toggleBtn.classList.toggle('is-toggeled');
|
|
29
|
+
this.container.classList.toggle('is-visible');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
createImageHeadline(activeCue, post) {
|
|
33
|
+
if (activeCue.text in this.headlineCache) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let element = post.querySelector('[data-video-headline-tpl]');
|
|
38
|
+
|
|
39
|
+
if (post.querySelector('[data-video-headline-tpl]')) {
|
|
40
|
+
this.headlineCache[activeCue.text] = element;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
element = this.headlineTpl.cloneNode(true);
|
|
45
|
+
const prevHeadline = element.querySelector('h1');
|
|
46
|
+
const headline = document.createElement('h2');
|
|
47
|
+
|
|
48
|
+
headline.className = prevHeadline.className;
|
|
49
|
+
headline.innerHTML = activeCue.id;
|
|
50
|
+
|
|
51
|
+
prevHeadline.parentNode.replaceChild(headline, prevHeadline);
|
|
52
|
+
post.appendChild(element);
|
|
53
|
+
|
|
54
|
+
this.headlineCache[activeCue.text] = element;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
onCueChange = () => {
|
|
58
|
+
const { activeCues } = this.meta;
|
|
59
|
+
|
|
60
|
+
if (activeCues.length > 0) {
|
|
61
|
+
const activeCue = activeCues[0];
|
|
62
|
+
|
|
63
|
+
this.posts.forEach((post) => {
|
|
64
|
+
if (post.dataset.id === activeCue.text) {
|
|
65
|
+
post.classList.add('is-current');
|
|
66
|
+
|
|
67
|
+
if (post.classList.contains('js-timeline-image') && activeCue.id) {
|
|
68
|
+
this.createImageHeadline(activeCue, post);
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
post.classList.remove('is-current');
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
bottom: 0;
|
|
43
43
|
z-index: 1;
|
|
44
44
|
justify-content: center;
|
|
45
|
-
opacity: 0;
|
|
46
45
|
transition: opacity 0.25s ease-out;
|
|
47
46
|
margin: 0;
|
|
48
47
|
padding: 0;
|
|
@@ -52,6 +51,10 @@
|
|
|
52
51
|
opacity: 1;
|
|
53
52
|
}
|
|
54
53
|
|
|
54
|
+
&.is-current ~ & {
|
|
55
|
+
opacity: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
55
58
|
img {
|
|
56
59
|
border-radius: 0;
|
|
57
60
|
object-fit: cover;
|
|
@@ -381,6 +384,7 @@
|
|
|
381
384
|
|
|
382
385
|
@include e(buttons) {
|
|
383
386
|
display: flex;
|
|
387
|
+
align-items: center;
|
|
384
388
|
}
|
|
385
389
|
|
|
386
390
|
@include e(button) {
|
|
@@ -393,7 +397,7 @@
|
|
|
393
397
|
|
|
394
398
|
&:disabled,
|
|
395
399
|
&:disabled:focus,
|
|
396
|
-
&:not([class*="play"]):not([class*="subtitles"]):not([
|
|
400
|
+
&:not([class*="play"]):not([class*="subtitles"]):not([class*="chapter"]),
|
|
397
401
|
&:disabled:focus-visible {
|
|
398
402
|
pointer-events: none;
|
|
399
403
|
cursor: not-allowed;
|
|
@@ -418,6 +422,12 @@
|
|
|
418
422
|
}
|
|
419
423
|
}
|
|
420
424
|
|
|
425
|
+
@include e(countdown) {
|
|
426
|
+
font-size: $size-medium-plus;
|
|
427
|
+
padding-left: rhythm(1);
|
|
428
|
+
padding-right: rhythm(1);
|
|
429
|
+
}
|
|
430
|
+
|
|
421
431
|
@include e(play-icon) {
|
|
422
432
|
width: $icon-size-large * 1.5;
|
|
423
433
|
height: $icon-size-large * 1.5;
|
|
@@ -505,4 +515,4 @@
|
|
|
505
515
|
font-size: initial;
|
|
506
516
|
}
|
|
507
517
|
}
|
|
508
|
-
}
|
|
518
|
+
}
|
|
@@ -2,8 +2,8 @@ module.exports = {
|
|
|
2
2
|
status: 'prototype',
|
|
3
3
|
|
|
4
4
|
context: {
|
|
5
|
-
videoSrc: '/
|
|
6
|
-
videoSrc2: '/
|
|
5
|
+
videoSrc: 'https://ny.internetmuseum.se/app/uploads/2023/01/guidad-tur-nar-internet-kom-till-svenska-hem.mp4',
|
|
6
|
+
videoSrc2: 'https://ny.internetmuseum.se/app/uploads/2023/01/guidad-tur-nar-internet-kom-till-svenska-hem-vp9-chrome.webm',
|
|
7
7
|
|
|
8
8
|
variants: [
|
|
9
9
|
{
|
|
@@ -14,4 +14,4 @@ module.exports = {
|
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|
|
17
|
-
}
|
|
17
|
+
}
|
|
@@ -1,264 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const metadataTrack = (trackMetadataElement === null) ? '' : trackMetadataElement.track;
|
|
14
|
-
const forwardsButton = document.querySelector('.js-next-chapter');
|
|
15
|
-
const backwardsButton = document.querySelector('.js-previous-chapter');
|
|
16
|
-
const timelinePosts = document.querySelectorAll('.js-timeline-post');
|
|
17
|
-
const navigationButton = document.querySelector('.js-show-timelineposts');
|
|
18
|
-
const timeLinePosts = document.querySelector('.js-timeline-posts');
|
|
19
|
-
let currentChapter = 0;
|
|
20
|
-
let manualStep = false;
|
|
1
|
+
import VideoGuideSubtitles from './VideoGuideSubtitles';
|
|
2
|
+
import VideoGuideTimeline from './VideoGuideTimeline';
|
|
3
|
+
import VideoGuidePlayback from './VideoGuidePlayback';
|
|
4
|
+
|
|
5
|
+
class VideoGuide {
|
|
6
|
+
constructor(element) {
|
|
7
|
+
this.element = element;
|
|
8
|
+
this.video = element.querySelector('.js-video-guide');
|
|
9
|
+
this.abortBtn = element.querySelector('.js-abort-guide');
|
|
10
|
+
this.playback = null;
|
|
11
|
+
this.subtitles = null;
|
|
12
|
+
this.timeline = null;
|
|
21
13
|
|
|
22
|
-
// Set
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const currentGuideImage = video.dataset.featuredImage;
|
|
27
|
-
sessionStorage.setItem('InmsCurrentTime', video.currentTime);
|
|
28
|
-
sessionStorage.setItem('InmsDuration', video.duration); // Get totalt duration of video
|
|
29
|
-
sessionStorage.setItem('InmsCurrentGuideURL', currentGuideURL);
|
|
30
|
-
sessionStorage.setItem('InmsCurrentGuideImage', currentGuideImage);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Has src attributes been set already?
|
|
35
|
-
if (video) {
|
|
36
|
-
// Store current time in on page reload
|
|
37
|
-
window.addEventListener('visibilitychange', saveState);
|
|
38
|
-
window.addEventListener('beforeunload', saveState);
|
|
14
|
+
// Set all track elements to hidden mode to allow scripting
|
|
15
|
+
[].forEach.call(this.video.textTracks, (txtTrack) => {
|
|
16
|
+
txtTrack.mode = 'hidden';
|
|
17
|
+
});
|
|
39
18
|
|
|
40
|
-
|
|
41
|
-
if (sessionStorage.getItem('InmsCurrentTime')) {
|
|
42
|
-
const videoCurrentTime = sessionStorage.getItem('InmsCurrentTime');
|
|
19
|
+
this.attach();
|
|
43
20
|
|
|
44
|
-
if
|
|
45
|
-
|
|
21
|
+
// loadedmetadata might not be fired if the video is already loaded
|
|
22
|
+
if (this.video.readyState >= 1) {
|
|
23
|
+
this.onLoadedMetadata();
|
|
46
24
|
}
|
|
47
25
|
}
|
|
48
26
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
27
|
+
attach() {
|
|
28
|
+
this.video.addEventListener('loadedmetadata', this.onLoadedMetadata);
|
|
29
|
+
this.video.addEventListener('play', this.onPlay);
|
|
30
|
+
this.video.addEventListener('pause', this.onPause);
|
|
31
|
+
this.video.addEventListener('ended', this.onEnded);
|
|
32
|
+
this.video.addEventListener('timeupdate', this.onTimeUpdate);
|
|
33
|
+
this.abortBtn.addEventListener('click', this.onAbort);
|
|
55
34
|
}
|
|
56
35
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
video.play();
|
|
62
|
-
pauseIcon.classList.remove('is-hidden');
|
|
63
|
-
playIcon.classList.add('is-hidden');
|
|
64
|
-
manualStep = false;
|
|
65
|
-
} else {
|
|
66
|
-
video.pause();
|
|
67
|
-
pauseIcon.classList.add('is-hidden');
|
|
68
|
-
playIcon.classList.remove('is-hidden');
|
|
69
|
-
manualStep = true;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
video.addEventListener('playing', () => {
|
|
74
|
-
pauseIcon.classList.remove('is-hidden');
|
|
75
|
-
playIcon.classList.add('is-hidden');
|
|
76
|
-
manualStep = false;
|
|
77
|
-
});
|
|
36
|
+
onLoadedMetadata = () => {
|
|
37
|
+
this.playback = new VideoGuidePlayback(this.element, this.video);
|
|
38
|
+
this.subtitles = new VideoGuideSubtitles(this.element, this.video);
|
|
39
|
+
this.timeline = new VideoGuideTimeline(this.element, this.video);
|
|
78
40
|
|
|
79
|
-
video.
|
|
80
|
-
pauseIcon.classList.add('is-hidden');
|
|
81
|
-
playIcon.classList.remove('is-hidden');
|
|
82
|
-
video.currentTime = 0;
|
|
83
|
-
currentChapter = 1;
|
|
84
|
-
manualStep = false;
|
|
85
|
-
forwardsButton.removeAttribute('disabled');
|
|
86
|
-
subtitlesContainer.innerHTML = '';
|
|
87
|
-
sessionStorage.removeItem('InmsCurrentTime');
|
|
88
|
-
sessionStorage.removeItem('InmsDuration');
|
|
89
|
-
sessionStorage.removeItem('InmsCurrentGuideURL');
|
|
90
|
-
sessionStorage.removeItem('InmsCurrentGuideImage');
|
|
91
|
-
});
|
|
41
|
+
this.video.classList.remove('is-loading');
|
|
92
42
|
}
|
|
93
43
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
video.currentTime = 0;
|
|
100
|
-
forwardsButton.removeAttribute('disabled');
|
|
101
|
-
currentChapter = 1;
|
|
102
|
-
manualStep = false;
|
|
103
|
-
sessionStorage.removeItem('InmsCurrentTime');
|
|
104
|
-
sessionStorage.removeItem('InmsDuration');
|
|
105
|
-
sessionStorage.removeItem('InmsCurrentGuideURL');
|
|
106
|
-
sessionStorage.removeItem('InmsCurrentGuideImage');
|
|
107
|
-
window.location.href = urlTarget;
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (navigationButton) {
|
|
112
|
-
navigationButton.addEventListener('click', () => {
|
|
113
|
-
navigationButton.classList.toggle('is-toggeled');
|
|
114
|
-
timeLinePosts.classList.toggle('is-visible');
|
|
44
|
+
dispatchEvent = (eventName) => {
|
|
45
|
+
[this.playback, this.subtitles, this.timeline].forEach((instance) => {
|
|
46
|
+
if (instance && eventName in instance) {
|
|
47
|
+
instance[eventName]();
|
|
48
|
+
}
|
|
115
49
|
});
|
|
116
50
|
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function displayChapters() {
|
|
120
|
-
if (chapterTrackElement && trackMetadataElement) {
|
|
121
|
-
// Set all track elements to hidden mode to allow scripting
|
|
122
|
-
[].forEach.call(video.textTracks, (txtTrack) => {
|
|
123
|
-
txtTrack.mode = 'hidden';
|
|
124
|
-
});
|
|
125
51
|
|
|
126
|
-
|
|
127
|
-
video.addEventListener('loadedmetadata', () => {
|
|
128
|
-
// Loop through chapters and create chapter list
|
|
129
|
-
// Let data load
|
|
130
|
-
setTimeout(() => {
|
|
131
|
-
video.classList.remove('is-loading');
|
|
52
|
+
onPlay = () => this.dispatchEvent('onPlay');
|
|
132
53
|
|
|
133
|
-
|
|
134
|
-
if (!sessionStorage.getItem('InmsCurrentTime')) {
|
|
135
|
-
forwardsButton.setAttribute('data-id', chapterTrack.cues[0].endTime);
|
|
136
|
-
}
|
|
137
|
-
}, 100);
|
|
138
|
-
});
|
|
54
|
+
onPause = () => this.dispatchEvent('onPause');
|
|
139
55
|
|
|
140
|
-
|
|
141
|
-
const dataId = forwardsButton.dataset.id;
|
|
142
|
-
let currentTime = parseInt(dataId, 10);
|
|
143
|
-
manualStep = true;
|
|
144
|
-
currentTime += 1;
|
|
145
|
-
video.currentTime = currentTime;
|
|
146
|
-
currentChapter += 1;
|
|
147
|
-
});
|
|
56
|
+
onEnded = () => this.dispatchEvent('onEnded');
|
|
148
57
|
|
|
149
|
-
|
|
150
|
-
const dataId = backwardsButton.dataset.id;
|
|
151
|
-
let lastTime = parseInt(dataId, 10);
|
|
152
|
-
lastTime -= 1;
|
|
153
|
-
video.currentTime = lastTime;
|
|
154
|
-
forwardsButton.removeAttribute('disabled');
|
|
155
|
-
manualStep = true;
|
|
156
|
-
currentChapter -= 1;
|
|
58
|
+
onTimeUpdate = () => this.dispatchEvent('onTimeUpdate');
|
|
157
59
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
chapterTrack.addEventListener('cuechange', () => {
|
|
164
|
-
// Fire this whenever the chapters changes
|
|
165
|
-
const myCues = chapterTrack.activeCues;
|
|
166
|
-
if (myCues.length > 0) {
|
|
167
|
-
const currentLocation = chapterTrack.activeCues[0].startTime;
|
|
168
|
-
const nextLocation = chapterTrack.activeCues[0].endTime;
|
|
169
|
-
const cueMatch = chapterTrack.activeCues[0].text;
|
|
170
|
-
const matchingCueArray = document.querySelectorAll(`[rel="${currentLocation}"]`);
|
|
171
|
-
|
|
172
|
-
// Set Forward and backwards buttons timestamps
|
|
173
|
-
forwardsButton.setAttribute('data-id', nextLocation);
|
|
174
|
-
backwardsButton.setAttribute('data-id', currentLocation);
|
|
175
|
-
|
|
176
|
-
// Add chapter stepping even when video is played
|
|
177
|
-
if (manualStep === false) {
|
|
178
|
-
currentChapter += 1;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Disable forwardsbutton when on last chapter
|
|
182
|
-
if (currentChapter >= chapterTrack.cues.length) {
|
|
183
|
-
forwardsButton.setAttribute('disabled', 'disabled');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Handle current and watched items
|
|
187
|
-
[].forEach.call(matchingCueArray, (matchingCue) => {
|
|
188
|
-
const thisChapter = matchingCue;
|
|
189
|
-
if (thisChapter.innerHTML === cueMatch) {
|
|
190
|
-
const chapter = thisChapter;
|
|
191
|
-
|
|
192
|
-
if (chapter === thisChapter) {
|
|
193
|
-
// get the chapter <li> elements based on the currentLocation
|
|
194
|
-
const locations = [].slice.call(chapter.closest('figure')
|
|
195
|
-
.querySelectorAll('.js-chapters li'));
|
|
196
|
-
|
|
197
|
-
[].forEach.call(locations, (location) => {
|
|
198
|
-
// remove current classes from all items on page refresh
|
|
199
|
-
location.classList.remove('is-current-item');
|
|
200
|
-
location.querySelector('a').classList.remove('is-current');
|
|
201
|
-
});
|
|
202
|
-
chapter.parentNode.classList.add('is-current-item');
|
|
203
|
-
chapter.classList.add('is-current');
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}, false);
|
|
209
|
-
|
|
210
|
-
// Get timeline post IDs from metadata.vtt
|
|
211
|
-
metadataTrack.addEventListener('cuechange', () => {
|
|
212
|
-
const metadataCues = metadataTrack.activeCues;
|
|
213
|
-
const chapterCues = chapterTrack.activeCues[0];
|
|
214
|
-
|
|
215
|
-
if (metadataCues.length > 0) {
|
|
216
|
-
const metadataCueMatch = metadataTrack.activeCues[0].text;
|
|
217
|
-
|
|
218
|
-
[].forEach.call(timelinePosts, (timelinePost) => {
|
|
219
|
-
timelinePost.classList.remove('is-current');
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
const idSelectors = document.querySelectorAll(`[data-id="${metadataCueMatch}"]`);
|
|
223
|
-
|
|
224
|
-
[].forEach.call(idSelectors, (idSelector) => {
|
|
225
|
-
idSelector.classList.add('is-current');
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
if (chapterCues) {
|
|
229
|
-
const chapterStartTime = chapterCues.startTime;
|
|
230
|
-
|
|
231
|
-
// Let stuff load
|
|
232
|
-
let listElement;
|
|
233
|
-
let timeOut = null;
|
|
234
|
-
|
|
235
|
-
setTimeout(() => { listElement = document.getElementById(chapterStartTime); }, 100);
|
|
236
|
-
|
|
237
|
-
timeOut = function wait(condition, callback) {
|
|
238
|
-
if (typeof condition() !== 'undefined' && listElement) {
|
|
239
|
-
listElement.classList.add('is-current-item');
|
|
240
|
-
} else {
|
|
241
|
-
setTimeout(() => {
|
|
242
|
-
wait(condition, callback);
|
|
243
|
-
}, 0);
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
timeOut(() => listElement, () => { });
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}, false);
|
|
250
|
-
|
|
251
|
-
// Get subtitles cues from subtitles.vtt
|
|
252
|
-
subtitlesTrack.addEventListener('cuechange', () => {
|
|
253
|
-
const subtitlesCues = subtitlesTrack.activeCues;
|
|
254
|
-
|
|
255
|
-
if (subtitlesCues.length > 0) {
|
|
256
|
-
const subtitlesCuesMatch = subtitlesTrack.activeCues[0].text;
|
|
257
|
-
subtitlesContainer.innerHTML = `<span>${subtitlesCuesMatch}</span>`;
|
|
258
|
-
}
|
|
259
|
-
}, false);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
60
|
+
onAbort = () => {
|
|
61
|
+
this.dispatchEvent('onAbort');
|
|
62
|
+
window.location.href = this.abortBtn.href;
|
|
63
|
+
};
|
|
262
64
|
}
|
|
263
65
|
|
|
264
|
-
|
|
66
|
+
const elements = document.querySelectorAll('[data-video-guide]');
|
|
67
|
+
|
|
68
|
+
elements.forEach((element) => new VideoGuide(element));
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
WEBVTT
|
|
2
|
-
|
|
3
|
-
00:00:00.000 --> 00:00:39.000
|
|
4
|
-
Kapitel 1 / 8: Introduktion
|
|
5
|
-
|
|
6
|
-
00:00:39.000 --> 00:01:51.500
|
|
7
|
-
Kapitel 2 / 8: Idén om internet
|
|
8
|
-
|
|
9
|
-
00:01:51.500 --> 00:02:53.000
|
|
10
|
-
Kapitel 3 / 8: Arpanet blir till
|
|
11
|
-
|
|
12
|
-
00:02:53.000 --> 00:03:27.000
|
|
13
|
-
Kapitel 4 / 8: TCP/IP uppfinns
|
|
14
|
-
|
|
15
|
-
00:03:27.000 --> 00:03:56.500
|
|
16
|
-
Kapitel 5 / 8: Sveriges första internetnod
|
|
17
|
-
|
|
18
|
-
00:03:56.500 --> 00:04:34.000
|
|
19
|
-
Kapitel 6 / 8: Toppdomänen .se registreras
|
|
20
|
-
|
|
21
|
-
00:04:34.000 --> 00:05:17.000
|
|
22
|
-
Kapitel 7 / 8: World Wide Web
|
|
23
|
-
|
|
24
|
-
00:05:17.000 --> 00:06:28.000
|
|
25
|
-
Kapitel 8 / 8: Mosaic - den grafiska webbläsaren
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
WEBVTT
|
|
2
|
-
|
|
3
|
-
00:00:00.000 --> 00:00:25.000
|
|
4
|
-
89108
|
|
5
|
-
|
|
6
|
-
00:00:25.000 --> 00:00:39.000
|
|
7
|
-
91027
|
|
8
|
-
|
|
9
|
-
00:00:39.000 --> 00:01:51.500
|
|
10
|
-
81345
|
|
11
|
-
|
|
12
|
-
00:01:51.500 --> 00:02:23.000
|
|
13
|
-
76810
|
|
14
|
-
|
|
15
|
-
00:02:23.000 --> 00:03:27.000
|
|
16
|
-
86454
|
|
17
|
-
|
|
18
|
-
00:03:27.000 --> 00:03:56.500
|
|
19
|
-
80127
|
|
20
|
-
|
|
21
|
-
00:03:56.500 --> 00:04:34.000
|
|
22
|
-
76325
|
|
23
|
-
|
|
24
|
-
00:04:34.000 --> 00:05:17.000
|
|
25
|
-
76280
|
|
26
|
-
|
|
27
|
-
00:05:17.000 --> 00:06:28.000
|
|
28
|
-
80725
|
|
Binary file
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
WEBVTT
|
|
2
|
-
|
|
3
|
-
1
|
|
4
|
-
00:00:00.500 --> 00:00:02.000
|
|
5
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
|
6
|
-
|
|
7
|
-
2
|
|
8
|
-
00:00:02.100 --> 00:00:03.000
|
|
9
|
-
Phasellus eget lorem dui
|
|
10
|
-
|
|
11
|
-
3
|
|
12
|
-
00:00:03.100 --> 00:00:04.500
|
|
13
|
-
Morbi ac nisi ac purus maximus semper a vitae diam fusce sit amet libero non tortor
|
|
14
|
-
|
|
15
|
-
4
|
|
16
|
-
00:00:04.600 --> 00:00:05.500
|
|
17
|
-
Ut scelerisque sagittis justo vitae viverra
|
|
18
|
-
|
|
19
|
-
5
|
|
20
|
-
00:00:05.600 --> 00:00:06.500
|
|
21
|
-
unc blandit justo sed odio tempus ultrices. Pellentesque sollicitudin justo.
|
|
22
|
-
|
|
23
|
-
6
|
|
24
|
-
00:00:06.100 --> 00:00:08.000
|
|
25
|
-
Etiam ut volutpat tortor. Nunc iaculis luctus sapien.
|