fslightbox 3.3.0 → 3.3.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/FsLightbox.js +110 -0
- package/README.md +55 -1
- package/components/helpers/renderSvg.js +17 -0
- package/components/nav/renderAndGetToolbarButton.js +11 -0
- package/components/nav/renderCloseButton.js +10 -0
- package/components/nav/renderFullscreenButton.js +42 -0
- package/components/nav/renderNav.js +17 -0
- package/components/nav/renderSlideNumber.js +33 -0
- package/components/nav/renderToolbar.js +13 -0
- package/components/renderSlideButton.js +11 -0
- package/components/renderSlideButtonContainer.js +15 -0
- package/components/renderSlideButtons.js +7 -0
- package/components/renderSlideSwipingHoverer.js +6 -0
- package/components/sources/proper-sources/renderCustom.js +15 -0
- package/components/sources/proper-sources/renderImage.js +18 -0
- package/components/sources/proper-sources/renderInvalid.js +19 -0
- package/components/sources/proper-sources/renderVideo.js +31 -0
- package/components/sources/proper-sources/renderYoutube.js +26 -0
- package/components/sources/renderSourceAnimationWrapper.js +4 -0
- package/components/sources/renderSourceMainWrapper.js +32 -0
- package/components/sources/renderSourceWrappersContainer.js +22 -0
- package/constants/classes-names.js +27 -0
- package/constants/core-constants.js +6 -0
- package/constants/css-constants.js +1 -0
- package/constants/dom-constants.js +1 -0
- package/constants/elements.js +3 -0
- package/constants/local-storage-constants.js +2 -0
- package/core/collections/fillSourcesOutersTransformersCollection.js +13 -0
- package/core/elements/setUpClassFacade.js +9 -0
- package/core/events/setUpEventsDispatcher.js +7 -0
- package/core/events/setUpGlobalEventsController.js +34 -0
- package/core/fullscreen/setUpFullscreenToggler.js +30 -0
- package/core/keyboard/KeyboardController.js +20 -0
- package/core/main-component/closing/LightboxCloseActioner.js +46 -0
- package/core/main-component/closing/setUpLightboxCloser.js +11 -0
- package/core/main-component/initializing/initializeLightbox.js +38 -0
- package/core/main-component/opening/setUpLightboxOpener.js +47 -0
- package/core/scrollbar/getInnerElementOfWidthGetter.js +5 -0
- package/core/scrollbar/getOuterElementOfWidthGetter.js +9 -0
- package/core/scrollbar/getScrollbarWidth.js +31 -0
- package/core/scrollbar/setUpScrollbarRecompensor.js +20 -0
- package/core/setUpCore.js +30 -0
- package/core/sizes/setUpWindowResizeActioner.js +35 -0
- package/core/slide/setUpSlideChangeFacade.js +23 -0
- package/core/slide/setUpSlideIndexChanger.js +60 -0
- package/core/sources/SourceLoadActioner.js +29 -0
- package/core/sources/SourceLoadHandler.js +41 -0
- package/core/sources/SourceSizer.js +36 -0
- package/core/sources/creating/CreatingSourcesBucket.js +29 -0
- package/core/sources/creating/CreatingSourcesLocalStorageManager.js +55 -0
- package/core/sources/creating/createSources.js +28 -0
- package/core/sources/pointering/down/setUpSourcesPointerDown.js +36 -0
- package/core/sources/pointering/move/SourcesPointerMove.js +16 -0
- package/core/sources/pointering/move/SourcesPointerMoveActioner.js +37 -0
- package/core/sources/pointering/up/SourcesPointerUp.js +13 -0
- package/core/sources/pointering/up/SourcesPointerUpActioner.js +38 -0
- package/core/sources/pointering/up/SourcesPointerUpActionerBucket.js +35 -0
- package/core/sources/setUpSourceDisplayFacade.js +26 -0
- package/core/sources/types/AutomaticTypeDetector.js +70 -0
- package/core/sources/types/DetectedTypeActioner.js +44 -0
- package/core/sources/types/getAutomaticTypeDetectorBucket.js +14 -0
- package/core/stage/setUpStageManager.js +60 -0
- package/core/styles/createAndAppendStyles.js +9 -0
- package/core/styles/injectStylesIfNotInDom.js +8 -0
- package/core/styles/styles-injection/styles-injection.js +5 -0
- package/core/timeouts/getQueuedAction.js +15 -0
- package/core/transforms/SourceMainWrapperTransformer.js +27 -0
- package/fslightbox.js +1 -0
- package/helpers/elements/addToElementClassIfNotContains.js +6 -0
- package/helpers/elements/removeFromElementChildIfContains.js +5 -0
- package/helpers/elements/removeFromElementClassIfContains.js +6 -0
- package/helpers/objects/assignToObject.js +10 -0
- package/helpers/source/setUpSourceClassName.js +13 -0
- package/helpers/source/setUpSourceCustomAttributes.js +5 -0
- package/helpers/state/ifOnUpdateExistsHandleItForState.js +6 -0
- package/i.js +86 -0
- package/index.js +1 -1
- package/package.json +4 -37
- package/styles.js +1 -0
- package/.env.example +0 -3
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { KeyboardController } from "../keyboard/KeyboardController";
|
|
2
|
+
import { SourcesPointerMove } from "../sources/pointering/move/SourcesPointerMove";
|
|
3
|
+
import { SourcesPointerUp } from "../sources/pointering/up/SourcesPointerUp";
|
|
4
|
+
|
|
5
|
+
export function setUpGlobalEventsController(
|
|
6
|
+
{
|
|
7
|
+
core: { globalEventsController: self, windowResizeActioner, },
|
|
8
|
+
resolve
|
|
9
|
+
}
|
|
10
|
+
) {
|
|
11
|
+
const keyboardController = resolve(KeyboardController);
|
|
12
|
+
const sourcesPointerMove = resolve(SourcesPointerMove);
|
|
13
|
+
const sourcesPointerUp = resolve(SourcesPointerUp);
|
|
14
|
+
|
|
15
|
+
self.attachListeners = () => {
|
|
16
|
+
document.addEventListener('pointermove', sourcesPointerMove.listener);
|
|
17
|
+
|
|
18
|
+
document.addEventListener('pointerup', sourcesPointerUp.listener);
|
|
19
|
+
|
|
20
|
+
addEventListener('resize', windowResizeActioner.runActions);
|
|
21
|
+
|
|
22
|
+
document.addEventListener('keydown', keyboardController.listener);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
self.removeListeners = () => {
|
|
26
|
+
document.removeEventListener('pointermove', sourcesPointerMove.listener);
|
|
27
|
+
|
|
28
|
+
document.removeEventListener('pointerup', sourcesPointerUp.listener);
|
|
29
|
+
|
|
30
|
+
removeEventListener('resize', windowResizeActioner.runActions);
|
|
31
|
+
|
|
32
|
+
document.removeEventListener('keydown', keyboardController.listener);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function setUpFullscreenToggler({ componentsServices, core: { fullscreenToggler: self } }) {
|
|
2
|
+
self.enterFullscreen = () => {
|
|
3
|
+
componentsServices.enterFullscreen();
|
|
4
|
+
|
|
5
|
+
const documentElement = document.documentElement;
|
|
6
|
+
if (documentElement.requestFullscreen) {
|
|
7
|
+
documentElement.requestFullscreen();
|
|
8
|
+
} else if (documentElement.mozRequestFullScreen) {
|
|
9
|
+
documentElement.mozRequestFullScreen();
|
|
10
|
+
} else if (documentElement.webkitRequestFullscreen) {
|
|
11
|
+
documentElement.webkitRequestFullscreen();
|
|
12
|
+
} else if (documentElement.msRequestFullscreen) {
|
|
13
|
+
documentElement.msRequestFullscreen();
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
self.exitFullscreen = () => {
|
|
18
|
+
componentsServices.exitFullscreen();
|
|
19
|
+
|
|
20
|
+
if (document.exitFullscreen) {
|
|
21
|
+
document.exitFullscreen();
|
|
22
|
+
} else if (document.mozCancelFullScreen) {
|
|
23
|
+
document.mozCancelFullScreen();
|
|
24
|
+
} else if (document.webkitExitFullscreen) {
|
|
25
|
+
document.webkitExitFullscreen();
|
|
26
|
+
} else if (document.msExitFullscreen) {
|
|
27
|
+
document.msExitFullscreen();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function KeyboardController({ core: { lightboxCloser, fullscreenToggler, slideChangeFacade } }) {
|
|
2
|
+
this.listener = (e) => {
|
|
3
|
+
switch (e.key) {
|
|
4
|
+
case 'Escape':
|
|
5
|
+
lightboxCloser.closeLightbox();
|
|
6
|
+
break;
|
|
7
|
+
case 'ArrowLeft':
|
|
8
|
+
slideChangeFacade.changeToPrevious();
|
|
9
|
+
break;
|
|
10
|
+
case 'ArrowRight':
|
|
11
|
+
slideChangeFacade.changeToNext();
|
|
12
|
+
break;
|
|
13
|
+
case 'F11':
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
// browsers does not trigger 'keydown' event when browser is already in fullscreen
|
|
16
|
+
fullscreenToggler.enterFullscreen();
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FADE_OUT_STRONG_CLASS_NAME, OPEN_CLASS_NAME } from "../../../constants/classes-names";
|
|
2
|
+
import { ANIMATION_TIME } from "../../../constants/css-constants";
|
|
3
|
+
|
|
4
|
+
export function LightboxCloseActioner(
|
|
5
|
+
{
|
|
6
|
+
core: {
|
|
7
|
+
eventsDispatcher,
|
|
8
|
+
fullscreenToggler,
|
|
9
|
+
globalEventsController,
|
|
10
|
+
scrollbarRecompensor
|
|
11
|
+
},
|
|
12
|
+
data,
|
|
13
|
+
elements,
|
|
14
|
+
props,
|
|
15
|
+
sourcePointerProps
|
|
16
|
+
}
|
|
17
|
+
) {
|
|
18
|
+
this.isLightboxFadingOut = false;
|
|
19
|
+
|
|
20
|
+
this.runActions = () => {
|
|
21
|
+
this.isLightboxFadingOut = true;
|
|
22
|
+
|
|
23
|
+
elements.container.classList.add(FADE_OUT_STRONG_CLASS_NAME);
|
|
24
|
+
|
|
25
|
+
globalEventsController.removeListeners();
|
|
26
|
+
|
|
27
|
+
if (props.exitFullscreenOnClose && data.isFullscreenOpen) {
|
|
28
|
+
fullscreenToggler.exitFullscreen();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
this.isLightboxFadingOut = false;
|
|
33
|
+
|
|
34
|
+
sourcePointerProps.isPointering = false;
|
|
35
|
+
|
|
36
|
+
elements.container.classList.remove(FADE_OUT_STRONG_CLASS_NAME);
|
|
37
|
+
document.documentElement.classList.remove(OPEN_CLASS_NAME);
|
|
38
|
+
|
|
39
|
+
scrollbarRecompensor.removeRecompense();
|
|
40
|
+
|
|
41
|
+
document.body.removeChild(elements.container);
|
|
42
|
+
|
|
43
|
+
eventsDispatcher.dispatch('onClose');
|
|
44
|
+
}, ANIMATION_TIME - 30);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LightboxCloseActioner } from "./LightboxCloseActioner";
|
|
2
|
+
|
|
3
|
+
export function setUpLightboxCloser({ core: { lightboxCloser: self }, resolve }) {
|
|
4
|
+
const lightboxCloseActioner = resolve(LightboxCloseActioner);
|
|
5
|
+
|
|
6
|
+
self.closeLightbox = () => {
|
|
7
|
+
if (!lightboxCloseActioner.isLightboxFadingOut) {
|
|
8
|
+
lightboxCloseActioner.runActions();
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FADE_IN_STRONG_CLASS_NAME,
|
|
3
|
+
FULL_DIMENSION_CLASS_NAME,
|
|
4
|
+
PREFIX
|
|
5
|
+
} from "../../../constants/classes-names";
|
|
6
|
+
import { createSources } from "../../sources/creating/createSources";
|
|
7
|
+
import { renderSourceWrappersContainer } from "../../../components/sources/renderSourceWrappersContainer";
|
|
8
|
+
import { renderNav } from "../../../components/nav/renderNav";
|
|
9
|
+
import { fillSourcesOutersTransformersCollection } from "../../collections/fillSourcesOutersTransformersCollection";
|
|
10
|
+
import { renderSlideButtons } from "../../../components/renderSlideButtons";
|
|
11
|
+
import { renderSlideSwipingHoverer } from "../../../components/renderSlideSwipingHoverer";
|
|
12
|
+
import { setUpCore } from "../../setUpCore";
|
|
13
|
+
import { getScrollbarWidth } from "../../scrollbar/getScrollbarWidth";
|
|
14
|
+
|
|
15
|
+
export function initializeLightbox(fsLightbox) {
|
|
16
|
+
const { core: { eventsDispatcher }, data, elements, props: { sources } } = fsLightbox;
|
|
17
|
+
|
|
18
|
+
data.isInitialized = true;
|
|
19
|
+
data.scrollbarWidth = getScrollbarWidth(fsLightbox);
|
|
20
|
+
|
|
21
|
+
fillSourcesOutersTransformersCollection(fsLightbox);
|
|
22
|
+
|
|
23
|
+
setUpCore(fsLightbox);
|
|
24
|
+
|
|
25
|
+
elements.container = document.createElement('div');
|
|
26
|
+
elements.container.className = `${PREFIX}container ${FULL_DIMENSION_CLASS_NAME} ${FADE_IN_STRONG_CLASS_NAME}`;
|
|
27
|
+
|
|
28
|
+
renderSlideSwipingHoverer(fsLightbox);
|
|
29
|
+
renderNav(fsLightbox);
|
|
30
|
+
renderSourceWrappersContainer(fsLightbox);
|
|
31
|
+
if (sources.length > 1) {
|
|
32
|
+
renderSlideButtons(fsLightbox);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
createSources(fsLightbox);
|
|
36
|
+
|
|
37
|
+
eventsDispatcher.dispatch('onInit');
|
|
38
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { OPEN_CLASS_NAME } from "../../../constants/classes-names";
|
|
2
|
+
import { initializeLightbox } from "../initializing/initializeLightbox";
|
|
3
|
+
|
|
4
|
+
export function setUpLightboxOpener(fsLightbox) {
|
|
5
|
+
const {
|
|
6
|
+
collections: { sourceMainWrappersTransformers },
|
|
7
|
+
componentsServices,
|
|
8
|
+
core: {
|
|
9
|
+
eventsDispatcher,
|
|
10
|
+
lightboxOpener: self,
|
|
11
|
+
globalEventsController,
|
|
12
|
+
scrollbarRecompensor,
|
|
13
|
+
sourceDisplayFacade,
|
|
14
|
+
stageManager,
|
|
15
|
+
windowResizeActioner
|
|
16
|
+
},
|
|
17
|
+
data,
|
|
18
|
+
elements,
|
|
19
|
+
stageIndexes
|
|
20
|
+
} = fsLightbox;
|
|
21
|
+
|
|
22
|
+
self.open = (index = 0) => {
|
|
23
|
+
stageIndexes.current = index;
|
|
24
|
+
|
|
25
|
+
(data.isInitialized) ?
|
|
26
|
+
eventsDispatcher.dispatch('onShow') :
|
|
27
|
+
initializeLightbox(fsLightbox);
|
|
28
|
+
|
|
29
|
+
stageManager.updateStageIndexes();
|
|
30
|
+
|
|
31
|
+
sourceDisplayFacade.displaySourcesWhichShouldBeDisplayed();
|
|
32
|
+
|
|
33
|
+
componentsServices.setSlideNumber(index + 1);
|
|
34
|
+
|
|
35
|
+
document.body.appendChild(elements.container);
|
|
36
|
+
document.documentElement.classList.add(OPEN_CLASS_NAME);
|
|
37
|
+
|
|
38
|
+
scrollbarRecompensor.addRecompense();
|
|
39
|
+
|
|
40
|
+
globalEventsController.attachListeners();
|
|
41
|
+
|
|
42
|
+
windowResizeActioner.runActions();
|
|
43
|
+
sourceMainWrappersTransformers[stageIndexes.current].zero();
|
|
44
|
+
|
|
45
|
+
eventsDispatcher.dispatch('onOpen');
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function getOuterElementOfWidthGetter() {
|
|
2
|
+
const outer = document.createElement('div');
|
|
3
|
+
const outerStyle = outer.style;
|
|
4
|
+
outerStyle.visibility = "hidden";
|
|
5
|
+
outerStyle.width = "100px";
|
|
6
|
+
outerStyle.msOverflowStyle = "scrollbar";
|
|
7
|
+
outerStyle.overflow = "scroll";
|
|
8
|
+
return outer;
|
|
9
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getOuterElementOfWidthGetter } from "./getOuterElementOfWidthGetter";
|
|
2
|
+
import { getInnerElementOfWidthGetter } from "./getInnerElementOfWidthGetter";
|
|
3
|
+
import { SCROLLBAR_WIDTH_KEY } from "../../constants/local-storage-constants";
|
|
4
|
+
|
|
5
|
+
export function getScrollbarWidth({ props: { disableLocalStorage } }) {
|
|
6
|
+
if (!disableLocalStorage) {
|
|
7
|
+
const localStorageScrollbarWidth = localStorage.getItem(SCROLLBAR_WIDTH_KEY);
|
|
8
|
+
if (localStorageScrollbarWidth) {
|
|
9
|
+
return localStorageScrollbarWidth;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const outer = getOuterElementOfWidthGetter();
|
|
14
|
+
const inner = getInnerElementOfWidthGetter();
|
|
15
|
+
|
|
16
|
+
document.body.appendChild(outer);
|
|
17
|
+
const widthNoScroll = outer.offsetWidth;
|
|
18
|
+
|
|
19
|
+
outer.appendChild(inner);
|
|
20
|
+
const widthWithScroll = inner.offsetWidth;
|
|
21
|
+
|
|
22
|
+
document.body.removeChild(outer);
|
|
23
|
+
|
|
24
|
+
const scrollbarWidth = widthNoScroll - widthWithScroll;
|
|
25
|
+
|
|
26
|
+
if (!disableLocalStorage) {
|
|
27
|
+
localStorage.setItem(SCROLLBAR_WIDTH_KEY, scrollbarWidth.toString());
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return scrollbarWidth;
|
|
31
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function setUpScrollbarRecompensor({ data, core: { scrollbarRecompensor: self } }) {
|
|
2
|
+
self.addRecompense = () => {
|
|
3
|
+
(document.readyState === "complete") ?
|
|
4
|
+
ifBodyIsHigherThanWindowAddRecompenseToScrollbar() :
|
|
5
|
+
addEventListener('load', () => {
|
|
6
|
+
ifBodyIsHigherThanWindowAddRecompenseToScrollbar();
|
|
7
|
+
self.addRecompense = ifBodyIsHigherThanWindowAddRecompenseToScrollbar;
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function ifBodyIsHigherThanWindowAddRecompenseToScrollbar() {
|
|
12
|
+
if (document.body.offsetHeight > innerHeight) {
|
|
13
|
+
document.body.style.marginRight = data.scrollbarWidth + 'px';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
self.removeRecompense = () => {
|
|
18
|
+
document.body.style.removeProperty('margin-right');
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { setUpLightboxOpener } from "./main-component/opening/setUpLightboxOpener";
|
|
2
|
+
import { setUpClassFacade } from "./elements/setUpClassFacade";
|
|
3
|
+
import { setUpEventsDispatcher } from "./events/setUpEventsDispatcher";
|
|
4
|
+
import { setUpFullscreenToggler } from "./fullscreen/setUpFullscreenToggler";
|
|
5
|
+
import { setUpLightboxCloser } from "./main-component/closing/setUpLightboxCloser";
|
|
6
|
+
import { setUpWindowResizeActioner } from "./sizes/setUpWindowResizeActioner";
|
|
7
|
+
import { setUpScrollbarRecompensor } from "./scrollbar/setUpScrollbarRecompensor";
|
|
8
|
+
import { setUpSlideIndexChanger } from "./slide/setUpSlideIndexChanger";
|
|
9
|
+
import { setUpGlobalEventsController } from "./events/setUpGlobalEventsController";
|
|
10
|
+
import { setUpSlideChangeFacade } from "./slide/setUpSlideChangeFacade";
|
|
11
|
+
import { setUpSourceDisplayFacade } from "./sources/setUpSourceDisplayFacade";
|
|
12
|
+
import { setUpStageManager } from "./stage/setUpStageManager";
|
|
13
|
+
import { setUpSourcesPointerDown } from "./sources/pointering/down/setUpSourcesPointerDown";
|
|
14
|
+
|
|
15
|
+
export function setUpCore(fsLightbox) {
|
|
16
|
+
setUpClassFacade(fsLightbox);
|
|
17
|
+
setUpEventsDispatcher(fsLightbox);
|
|
18
|
+
setUpFullscreenToggler(fsLightbox);
|
|
19
|
+
setUpGlobalEventsController(fsLightbox);
|
|
20
|
+
setUpLightboxCloser(fsLightbox);
|
|
21
|
+
setUpLightboxOpener(fsLightbox);
|
|
22
|
+
setUpScrollbarRecompensor(fsLightbox);
|
|
23
|
+
setUpSlideChangeFacade(fsLightbox);
|
|
24
|
+
setUpSlideIndexChanger(fsLightbox);
|
|
25
|
+
setUpSourcesPointerDown(fsLightbox);
|
|
26
|
+
setUpSourceDisplayFacade(fsLightbox);
|
|
27
|
+
setUpStageManager(fsLightbox);
|
|
28
|
+
setUpWindowResizeActioner(fsLightbox);
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { removeFromElementClassIfContains } from "../../helpers/elements/removeFromElementClassIfContains";
|
|
2
|
+
import { TRANSFORM_TRANSITION_CLASS_NAME } from "../../constants/classes-names";
|
|
3
|
+
|
|
4
|
+
export function setUpWindowResizeActioner(
|
|
5
|
+
{
|
|
6
|
+
collections: { sourceMainWrappersTransformers, sourceSizers },
|
|
7
|
+
core: { windowResizeActioner: self },
|
|
8
|
+
data,
|
|
9
|
+
elements: { sourceMainWrappers },
|
|
10
|
+
props,
|
|
11
|
+
stageIndexes
|
|
12
|
+
}
|
|
13
|
+
) {
|
|
14
|
+
self.runActions = () => {
|
|
15
|
+
// decreasing max source dimensions for better UX
|
|
16
|
+
(innerWidth < 992) ?
|
|
17
|
+
data.maxSourceWidth = innerWidth :
|
|
18
|
+
data.maxSourceWidth = 0.9 * innerWidth;
|
|
19
|
+
data.maxSourceHeight = 0.9 * innerHeight;
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < props.sources.length; i++) {
|
|
22
|
+
removeFromElementClassIfContains(sourceMainWrappers[i], TRANSFORM_TRANSITION_CLASS_NAME);
|
|
23
|
+
|
|
24
|
+
if (i !== stageIndexes.current) {
|
|
25
|
+
sourceMainWrappersTransformers[i].negative();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// if source is Invalid or if lightbox is initialized there are no sourceSizers
|
|
29
|
+
// so we need to check if it exists
|
|
30
|
+
if (sourceSizers[i]) {
|
|
31
|
+
sourceSizers[i].adjustSize();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function setUpSlideChangeFacade(
|
|
2
|
+
{
|
|
3
|
+
core: {
|
|
4
|
+
slideChangeFacade: self,
|
|
5
|
+
slideIndexChanger,
|
|
6
|
+
stageManager
|
|
7
|
+
},
|
|
8
|
+
props: { sources }
|
|
9
|
+
}
|
|
10
|
+
) {
|
|
11
|
+
if (sources.length > 1) {
|
|
12
|
+
self.changeToPrevious = () => {
|
|
13
|
+
slideIndexChanger.jumpTo(stageManager.getPreviousSlideIndex());
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
self.changeToNext = () => {
|
|
17
|
+
slideIndexChanger.jumpTo(stageManager.getNextSlideIndex());
|
|
18
|
+
};
|
|
19
|
+
} else {
|
|
20
|
+
self.changeToPrevious = () => {};
|
|
21
|
+
self.changeToNext = () => {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ANIMATION_TIME } from "../../constants/css-constants";
|
|
2
|
+
import { SOURCE_ANIMATION_WRAPPERS, SOURCE_MAIN_WRAPPERS } from "../../constants/elements";
|
|
3
|
+
import {
|
|
4
|
+
FADE_IN_CLASS_NAME, FADE_IN_STRONG_CLASS_NAME,
|
|
5
|
+
FADE_OUT_CLASS_NAME,
|
|
6
|
+
TRANSFORM_TRANSITION_CLASS_NAME,
|
|
7
|
+
} from "../../constants/classes-names";
|
|
8
|
+
import { removeFromElementClassIfContains } from "../../helpers/elements/removeFromElementClassIfContains";
|
|
9
|
+
import { getQueuedAction } from "../timeouts/getQueuedAction";
|
|
10
|
+
|
|
11
|
+
export function setUpSlideIndexChanger(
|
|
12
|
+
{
|
|
13
|
+
collections: { sourceMainWrappersTransformers },
|
|
14
|
+
componentsServices,
|
|
15
|
+
core: { classFacade, slideIndexChanger: self, sourceDisplayFacade, stageManager },
|
|
16
|
+
elements: { sourceAnimationWrappers },
|
|
17
|
+
stageIndexes
|
|
18
|
+
}
|
|
19
|
+
) {
|
|
20
|
+
const runQueuedRemoveFadeOut = getQueuedAction(() => {
|
|
21
|
+
classFacade.removeFromEachElementClassIfContains(SOURCE_ANIMATION_WRAPPERS, FADE_OUT_CLASS_NAME);
|
|
22
|
+
}, ANIMATION_TIME);
|
|
23
|
+
|
|
24
|
+
self.changeTo = (i) => {
|
|
25
|
+
stageIndexes.current = i;
|
|
26
|
+
|
|
27
|
+
stageManager.updateStageIndexes();
|
|
28
|
+
|
|
29
|
+
componentsServices.setSlideNumber(i + 1);
|
|
30
|
+
|
|
31
|
+
sourceDisplayFacade.displaySourcesWhichShouldBeDisplayed();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
self.jumpTo = (i) => {
|
|
35
|
+
let previousI = stageIndexes.current;
|
|
36
|
+
self.changeTo(i);
|
|
37
|
+
|
|
38
|
+
classFacade.removeFromEachElementClassIfContains(SOURCE_MAIN_WRAPPERS, TRANSFORM_TRANSITION_CLASS_NAME);
|
|
39
|
+
|
|
40
|
+
removeFromElementClassIfContains(sourceAnimationWrappers[previousI], FADE_IN_STRONG_CLASS_NAME);
|
|
41
|
+
removeFromElementClassIfContains(sourceAnimationWrappers[previousI], FADE_IN_CLASS_NAME);
|
|
42
|
+
sourceAnimationWrappers[previousI].classList.add(FADE_OUT_CLASS_NAME);
|
|
43
|
+
|
|
44
|
+
removeFromElementClassIfContains(sourceAnimationWrappers[i], FADE_IN_STRONG_CLASS_NAME);
|
|
45
|
+
removeFromElementClassIfContains(sourceAnimationWrappers[i], FADE_OUT_CLASS_NAME);
|
|
46
|
+
sourceAnimationWrappers[i].classList.add(FADE_IN_CLASS_NAME);
|
|
47
|
+
|
|
48
|
+
// we need to remove fade out from all sources because if someone used slide swiping during animation timeout
|
|
49
|
+
// we cannot detect what slide will be
|
|
50
|
+
runQueuedRemoveFadeOut();
|
|
51
|
+
|
|
52
|
+
sourceMainWrappersTransformers[i].zero();
|
|
53
|
+
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
if (previousI !== stageIndexes.current) {
|
|
56
|
+
sourceMainWrappersTransformers[previousI].negative();
|
|
57
|
+
}
|
|
58
|
+
}, ANIMATION_TIME - 30);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SourceSizer } from "./SourceSizer";
|
|
2
|
+
import { FADE_IN_STRONG_CLASS_NAME, OPACITY_1_CLASS_NAME } from "../../constants/classes-names";
|
|
3
|
+
|
|
4
|
+
export function SourceLoadActioner(
|
|
5
|
+
{
|
|
6
|
+
collections: { sourceSizers },
|
|
7
|
+
elements: { sourceAnimationWrappers, sourceMainWrappers, sources },
|
|
8
|
+
resolve
|
|
9
|
+
}, i
|
|
10
|
+
) {
|
|
11
|
+
this.runActions = (defaultWidth, defaultHeight) => {
|
|
12
|
+
sources[i].classList.add(OPACITY_1_CLASS_NAME);
|
|
13
|
+
sourceAnimationWrappers[i].classList.add(FADE_IN_STRONG_CLASS_NAME);
|
|
14
|
+
sourceMainWrappers[i].removeChild(sourceMainWrappers[i].firstChild);
|
|
15
|
+
|
|
16
|
+
runNormalLoadActions(defaultWidth, defaultHeight);
|
|
17
|
+
this.runActions = runNormalLoadActions;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Next loads after initial occur only while using 'srcset' so need to recreate SourceSizer.
|
|
22
|
+
*
|
|
23
|
+
* Note: Reopening lightbox does not trigger image load.
|
|
24
|
+
*/
|
|
25
|
+
function runNormalLoadActions(defaultWidth, defaultHeight) {
|
|
26
|
+
sourceSizers[i] = resolve(SourceSizer, [i, defaultWidth, defaultHeight]);
|
|
27
|
+
sourceSizers[i].adjustSize();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SourceLoadActioner } from "./SourceLoadActioner";
|
|
2
|
+
|
|
3
|
+
export function SourceLoadHandler({ elements: { sources }, props, resolve, }, i) {
|
|
4
|
+
const sourceLoadActioner = resolve(SourceLoadActioner, [i]);
|
|
5
|
+
|
|
6
|
+
let wasVideoLoadCalled;
|
|
7
|
+
|
|
8
|
+
this.handleImageLoad = ({ target: { naturalWidth, naturalHeight } }) => {
|
|
9
|
+
sourceLoadActioner.runActions(naturalWidth, naturalHeight);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
this.handleVideoLoad = ({ target: { videoWidth, videoHeight } }) => {
|
|
13
|
+
wasVideoLoadCalled = true;
|
|
14
|
+
sourceLoadActioner.runActions(videoWidth, videoHeight);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
this.handleNotMetaDatedVideoLoad = () => {
|
|
18
|
+
if (!wasVideoLoadCalled) {
|
|
19
|
+
this.handleYoutubeLoad();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
this.handleYoutubeLoad = () => {
|
|
24
|
+
let width = 1920;
|
|
25
|
+
let height = 1080;
|
|
26
|
+
|
|
27
|
+
if (props.maxYoutubeDimensions) {
|
|
28
|
+
width = props.maxYoutubeDimensions.width;
|
|
29
|
+
height = props.maxYoutubeDimensions.height;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
sourceLoadActioner.runActions(width, height);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
this.handleCustomLoad = () => {
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
const source = sources[i];
|
|
38
|
+
sourceLoadActioner.runActions(source.offsetWidth, source.offsetHeight);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function SourceSizer({ data, elements: { sources } }, i, defaultWidth, defaultHeight) {
|
|
2
|
+
const ratio = defaultWidth / defaultHeight;
|
|
3
|
+
let newHeight = 0;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This method takes care of setting sources dimensions.
|
|
7
|
+
* Unfortunately wa cannot only set max width and max height and allow the sources to scale themselves,
|
|
8
|
+
* due tu Youtube source which dimensions needs to be set in advance.
|
|
9
|
+
* In this case we are calculating dimensions mathematically.
|
|
10
|
+
*/
|
|
11
|
+
this.adjustSize = () => {
|
|
12
|
+
newHeight = data.maxSourceWidth / ratio;
|
|
13
|
+
|
|
14
|
+
// wider than higher
|
|
15
|
+
if (newHeight < data.maxSourceHeight) {
|
|
16
|
+
if (defaultWidth < data.maxSourceWidth) {
|
|
17
|
+
newHeight = defaultHeight;
|
|
18
|
+
}
|
|
19
|
+
return updateDimensions();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// higher than wider
|
|
23
|
+
if (defaultHeight > data.maxSourceHeight) {
|
|
24
|
+
newHeight = data.maxSourceHeight;
|
|
25
|
+
} else {
|
|
26
|
+
newHeight = defaultHeight;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
updateDimensions();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const updateDimensions = () => {
|
|
33
|
+
sources[i].style.width = newHeight * ratio + 'px';
|
|
34
|
+
sources[i].style.height = newHeight + 'px';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AutomaticTypeDetector } from "../types/AutomaticTypeDetector";
|
|
2
|
+
|
|
3
|
+
export function CreatingSourcesBucket(
|
|
4
|
+
{
|
|
5
|
+
props: { types, type, sources }, resolve,
|
|
6
|
+
}, localStorageManager, detectedTypeActioner
|
|
7
|
+
) {
|
|
8
|
+
this.getTypeSetByClientForIndex = (i) => {
|
|
9
|
+
let typeSetManuallyByClient;
|
|
10
|
+
|
|
11
|
+
if (types && types[i]) {
|
|
12
|
+
typeSetManuallyByClient = types[i];
|
|
13
|
+
} else if (type) {
|
|
14
|
+
typeSetManuallyByClient = type;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return typeSetManuallyByClient;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
this.retrieveTypeWithXhrForIndex = (i) => {
|
|
21
|
+
// we need to copy index because xhr will for sure come later than next loop iteration
|
|
22
|
+
const automaticTypeDetector = resolve(AutomaticTypeDetector);
|
|
23
|
+
automaticTypeDetector.setUrlToCheck(sources[i]);
|
|
24
|
+
automaticTypeDetector.getSourceType((sourceType) => {
|
|
25
|
+
localStorageManager.handleReceivedSourceTypeForUrl(sourceType, sources[i]);
|
|
26
|
+
detectedTypeActioner.runActionsForSourceTypeAndIndex(sourceType, i)
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SOURCES_TYPES_KEY } from "../../../constants/local-storage-constants";
|
|
2
|
+
import { assignToObject } from "../../../helpers/objects/assignToObject";
|
|
3
|
+
|
|
4
|
+
export function CreatingSourcesLocalStorageManager({ props }) {
|
|
5
|
+
const NEW_TYPE_SHOULD_BE_ADDED_HERE = false;
|
|
6
|
+
let decodedSourceTypes;
|
|
7
|
+
let newSourceTypesToDetect = 0;
|
|
8
|
+
const newTypes = {};
|
|
9
|
+
|
|
10
|
+
this.getSourceTypeFromLocalStorageByUrl = (url) => {
|
|
11
|
+
if (!decodedSourceTypes[url]) {
|
|
12
|
+
return addNewUrlToDetect(url);
|
|
13
|
+
}
|
|
14
|
+
return decodedSourceTypes[url];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
this.handleReceivedSourceTypeForUrl = (sourceType, url) => {
|
|
18
|
+
if (newTypes[url] === NEW_TYPE_SHOULD_BE_ADDED_HERE) {
|
|
19
|
+
newSourceTypesToDetect--;
|
|
20
|
+
|
|
21
|
+
// not storing invalid types
|
|
22
|
+
if (sourceType !== 'invalid') {
|
|
23
|
+
newTypes[url] = sourceType;
|
|
24
|
+
} else {
|
|
25
|
+
delete newTypes[url];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (newSourceTypesToDetect === 0) {
|
|
29
|
+
assignToObject(decodedSourceTypes, newTypes);
|
|
30
|
+
localStorage.setItem(SOURCES_TYPES_KEY, JSON.stringify(decodedSourceTypes));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const addNewUrlToDetect = (url) => {
|
|
36
|
+
newSourceTypesToDetect++;
|
|
37
|
+
newTypes[url] = NEW_TYPE_SHOULD_BE_ADDED_HERE;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (!props.disableLocalStorage) {
|
|
41
|
+
decodedSourceTypes = JSON.parse(localStorage.getItem(SOURCES_TYPES_KEY));
|
|
42
|
+
// we are checking if detected source types contains at certain key source type
|
|
43
|
+
// when localStorage will be empty we can overwrite this method because we are sure
|
|
44
|
+
// that at every index will be no source type
|
|
45
|
+
if (!decodedSourceTypes) {
|
|
46
|
+
// in ifAllNewTypesAreDetectedStoreAllTypesToLocalStorage we are assigning to
|
|
47
|
+
// decodedSourceTypes new Types so we need to make it an object to avoid errors
|
|
48
|
+
decodedSourceTypes = {};
|
|
49
|
+
this.getSourceTypeFromLocalStorageByUrl = addNewUrlToDetect;
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
this.getSourceTypeFromLocalStorageByUrl = function () {};
|
|
53
|
+
this.handleReceivedSourceTypeForUrl = function () {};
|
|
54
|
+
}
|
|
55
|
+
}
|