@shower/core 3.3.0 → 3.4.0
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/LICENSE.md +5 -17
- package/README.md +7 -3
- package/dist/index.js +860 -0
- package/lib/default-options.js +11 -11
- package/lib/{start.js → index.js} +5 -5
- package/lib/modules/a11y.js +31 -29
- package/lib/modules/fullscreen.js +22 -0
- package/lib/modules/install.js +26 -24
- package/lib/modules/keys.js +96 -96
- package/lib/modules/location.js +51 -51
- package/lib/modules/mouse.js +39 -39
- package/lib/modules/next.js +39 -39
- package/lib/modules/parse-timing.js +28 -0
- package/lib/modules/progress.js +16 -16
- package/lib/modules/timer.js +25 -25
- package/lib/modules/title.js +15 -15
- package/lib/modules/touch.js +30 -30
- package/lib/modules/view.js +52 -52
- package/lib/shower.js +164 -164
- package/lib/slide.js +94 -94
- package/lib/utils.js +14 -14
- package/package.json +38 -61
- package/CHANGELOG.md +0 -13
- package/dist/shower.js +0 -836
- package/lib/modules/parse-timing.mjs +0 -28
package/lib/modules/next.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
export default (shower) => {
|
|
2
|
-
|
|
2
|
+
const { stepSelector, activeSlideClass, visitedSlideClass } = shower.options;
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
let innerSteps;
|
|
5
|
+
let activeIndex;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const isActive = (step) => step.classList.contains(activeSlideClass);
|
|
8
|
+
const isVisited = (step) => step.classList.contains(visitedSlideClass);
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const setInnerStepsState = () => {
|
|
11
|
+
if (shower.isListMode) return;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const slide = shower.activeSlide;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
innerSteps = [...slide.element.querySelectorAll(stepSelector)];
|
|
16
|
+
activeIndex =
|
|
17
|
+
innerSteps.length && innerSteps.every(isVisited)
|
|
18
|
+
? innerSteps.length
|
|
19
|
+
: innerSteps.filter(isActive).length - 1;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
slide.state.innerStepCount = innerSteps.length;
|
|
22
|
+
};
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
shower.addEventListener('start', setInnerStepsState);
|
|
25
|
+
shower.addEventListener('modechange', setInnerStepsState);
|
|
26
|
+
shower.addEventListener('slidechange', setInnerStepsState);
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
shower.addEventListener('next', (event) => {
|
|
29
|
+
if (shower.isListMode || event.defaultPrevented || !event.cancelable) return;
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
activeIndex++;
|
|
32
|
+
innerSteps.forEach((step, index) => {
|
|
33
|
+
step.classList.toggle(visitedSlideClass, index < activeIndex);
|
|
34
|
+
step.classList.toggle(activeSlideClass, index === activeIndex);
|
|
35
|
+
});
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
if (activeIndex < innerSteps.length) {
|
|
38
|
+
event.preventDefault();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
shower.addEventListener('prev', (event) => {
|
|
43
|
+
if (shower.isListMode || event.defaultPrevented || !event.cancelable) return;
|
|
44
|
+
if (activeIndex === -1 || activeIndex === innerSteps.length) return;
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
activeIndex--;
|
|
47
|
+
innerSteps.forEach((step, index) => {
|
|
48
|
+
step.classList.toggle(visitedSlideClass, index < activeIndex + 1);
|
|
49
|
+
step.classList.toggle(activeSlideClass, index === activeIndex);
|
|
50
|
+
});
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
});
|
|
54
54
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const units = ['s', 'm', 'h'];
|
|
2
|
+
const hasUnits = (timing) => {
|
|
3
|
+
return units.some((unit) => timing.includes(unit));
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
const parseUnits = (timing) => {
|
|
7
|
+
return units.map((unit) => timing.match(`(\\S+)${unit}`)).map((match) => match && match[1]);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const parseColons = (timing) => {
|
|
11
|
+
return `::${timing}`.split(':').reverse();
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const SEC_IN_MIN = 60;
|
|
15
|
+
const SEC_IN_HOUR = SEC_IN_MIN * 60;
|
|
16
|
+
|
|
17
|
+
export default (timing) => {
|
|
18
|
+
if (!timing) return 0;
|
|
19
|
+
|
|
20
|
+
const parsed = hasUnits(timing) ? parseUnits(timing) : parseColons(timing);
|
|
21
|
+
|
|
22
|
+
let [sec, min, hour] = parsed.map(Number);
|
|
23
|
+
|
|
24
|
+
sec += min * SEC_IN_MIN;
|
|
25
|
+
sec += hour * SEC_IN_HOUR;
|
|
26
|
+
|
|
27
|
+
return Math.max(sec * 1000, 0);
|
|
28
|
+
};
|
package/lib/modules/progress.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
export default (shower) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const { progressSelector } = shower.options;
|
|
3
|
+
const bar = shower.container.querySelector(progressSelector);
|
|
4
|
+
if (!bar) return;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
bar.setAttribute('role', 'progressbar');
|
|
7
|
+
bar.setAttribute('aria-valuemin', 0);
|
|
8
|
+
bar.setAttribute('aria-valuemax', 100);
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const updateProgress = () => {
|
|
11
|
+
const index = shower.activeSlideIndex;
|
|
12
|
+
const { length } = shower.slides;
|
|
13
|
+
const progress = (index / (length - 1)) * 100;
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
bar.style.width = `${progress}%`;
|
|
16
|
+
bar.setAttribute('aria-valuenow', progress);
|
|
17
|
+
bar.setAttribute('aria-valuetext', `Slideshow progress: ${progress}%`);
|
|
18
|
+
};
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
shower.addEventListener('start', updateProgress);
|
|
21
|
+
shower.addEventListener('slidechange', updateProgress);
|
|
22
22
|
};
|
package/lib/modules/timer.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import parseTiming from './parse-timing';
|
|
1
|
+
import parseTiming from './parse-timing.js';
|
|
2
2
|
|
|
3
3
|
export default (shower) => {
|
|
4
|
-
|
|
4
|
+
let id;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const resetTimer = () => {
|
|
7
|
+
clearTimeout(id);
|
|
8
|
+
if (shower.isListMode) return;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const slide = shower.activeSlide;
|
|
11
|
+
const { visitCount, innerStepCount } = slide.state;
|
|
12
|
+
if (visitCount > 1) return;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const timing = parseTiming(slide.element.dataset.timing);
|
|
15
|
+
if (!timing) return;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
if (innerStepCount) {
|
|
18
|
+
const stepTiming = timing / (innerStepCount + 1);
|
|
19
|
+
id = setInterval(() => shower.next(), stepTiming);
|
|
20
|
+
} else {
|
|
21
|
+
id = setTimeout(() => shower.next(), timing);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
shower.addEventListener('start', resetTimer);
|
|
26
|
+
shower.addEventListener('modechange', resetTimer);
|
|
27
|
+
shower.addEventListener('slidechange', resetTimer);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
shower.container.addEventListener('keydown', (event) => {
|
|
30
|
+
if (!event.defaultPrevented) {
|
|
31
|
+
clearTimeout(id);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
34
|
};
|
package/lib/modules/title.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
const mdash = '\u2014';
|
|
2
2
|
|
|
3
3
|
export default (shower) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
const { title } = document;
|
|
5
|
+
const updateTitle = () => {
|
|
6
|
+
if (shower.isFullMode) {
|
|
7
|
+
const slide = shower.activeSlide;
|
|
8
|
+
const slideTitle = slide.title;
|
|
9
|
+
if (slideTitle) {
|
|
10
|
+
document.title = `${slideTitle} ${mdash} ${title}`;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
document.title = title;
|
|
16
|
+
};
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
shower.addEventListener('start', updateTitle);
|
|
19
|
+
shower.addEventListener('modechange', updateTitle);
|
|
20
|
+
shower.addEventListener('slidechange', updateTitle);
|
|
21
21
|
};
|
package/lib/modules/touch.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
export default (shower) => {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
let exitFullScreen = false;
|
|
3
|
+
let clickable = false;
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
5
|
+
document.addEventListener('touchstart', (event) => {
|
|
6
|
+
if (event.touches.length === 1) {
|
|
7
|
+
const touch = event.touches[0];
|
|
8
|
+
const x = touch.clientX;
|
|
9
|
+
const { target } = touch;
|
|
10
|
+
clickable = target.tabIndex !== -1;
|
|
11
|
+
if (!clickable) {
|
|
12
|
+
if (shower.isFullMode) {
|
|
13
|
+
if (event.cancelable) event.preventDefault();
|
|
14
|
+
if (window.innerWidth / 2 < x) {
|
|
15
|
+
shower.next();
|
|
16
|
+
} else {
|
|
17
|
+
shower.prev();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
} else if (event.touches.length === 3) {
|
|
22
|
+
exitFullScreen = true;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
shower.container.addEventListener('touchend', (event) => {
|
|
27
|
+
if (exitFullScreen) {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
exitFullScreen = false;
|
|
30
|
+
shower.exitFullMode();
|
|
31
|
+
} else if (event.touches.length === 1 && !clickable && shower.isFullMode)
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
});
|
|
34
34
|
};
|
package/lib/modules/view.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
export default (shower) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
2
|
+
const { container } = shower;
|
|
3
|
+
const { fullModeClass, listModeClass } = shower.options;
|
|
4
|
+
|
|
5
|
+
if (container.classList.contains(fullModeClass)) {
|
|
6
|
+
shower.enterFullMode();
|
|
7
|
+
} else {
|
|
8
|
+
container.classList.add(listModeClass);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const updateScale = () => {
|
|
12
|
+
const firstSlide = shower.slides[0];
|
|
13
|
+
if (!firstSlide) return;
|
|
14
|
+
|
|
15
|
+
const { innerWidth, innerHeight } = window;
|
|
16
|
+
const { offsetWidth, offsetHeight } = firstSlide.element;
|
|
17
|
+
|
|
18
|
+
const listScale = 1 / (offsetWidth / innerWidth);
|
|
19
|
+
const fullScale = 1 / Math.max(offsetWidth / innerWidth, offsetHeight / innerHeight);
|
|
20
|
+
|
|
21
|
+
container.style.setProperty('--shower-list-scale', listScale);
|
|
22
|
+
container.style.setProperty('--shower-full-scale', fullScale);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const updateModeView = () => {
|
|
26
|
+
if (shower.isFullMode) {
|
|
27
|
+
container.classList.remove(listModeClass);
|
|
28
|
+
container.classList.add(fullModeClass);
|
|
29
|
+
} else {
|
|
30
|
+
container.classList.remove(fullModeClass);
|
|
31
|
+
container.classList.add(listModeClass);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
updateScale();
|
|
35
|
+
|
|
36
|
+
if (shower.isFullMode) return;
|
|
37
|
+
|
|
38
|
+
const slide = shower.activeSlide;
|
|
39
|
+
if (slide) {
|
|
40
|
+
slide.element.scrollIntoView({ block: 'center' });
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
shower.addEventListener('start', updateModeView);
|
|
45
|
+
shower.addEventListener('modechange', updateModeView);
|
|
46
|
+
shower.addEventListener('slidechange', () => {
|
|
47
|
+
if (shower.isFullMode) return;
|
|
48
|
+
|
|
49
|
+
const slide = shower.activeSlide;
|
|
50
|
+
slide.element.scrollIntoView({ block: 'nearest' });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
window.addEventListener('resize', updateScale);
|
|
54
54
|
};
|