fslightbox 3.3.3 → 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/c/elements/setUpClassFacade.js +9 -0
- package/c/events/setUpEventsDispatcher.js +7 -0
- package/c/events/setUpGlobalEventsController.js +39 -0
- package/c/keyboard/KeyboardController.js +26 -0
- package/c/main-component/closing/LightboxCloseActioner.js +46 -0
- package/c/main-component/closing/setUpLightboxCloser.js +11 -0
- package/c/scrollbar/gsw.js +1 -0
- package/c/scrollbar/setUpScrollbarRecompensor.js +20 -0
- package/c/setUpCore.js +30 -0
- package/c/sfs.js +1 -0
- package/c/sizes/setUpWindowResizeActioner.js +38 -0
- package/c/slide/setUpSlideChangeFacade.js +23 -0
- package/c/slide/setUpSlideIndexChanger.js +89 -0
- package/c/so.js +1 -0
- package/c/sources/SourceLoadActioner.js +32 -0
- package/c/sources/SourceLoadHandler.js +41 -0
- package/c/sources/SourceSizer.js +36 -0
- package/c/sources/creating/CreatingSourcesBucket.js +29 -0
- package/c/sources/creating/CreatingSourcesLocalStorageManager.js +55 -0
- package/c/sources/creating/createSources.js +28 -0
- package/c/sources/pointering/down/setUpSourcesPointerDown.js +38 -0
- package/c/sources/pointering/move/SourcesPointerMove.js +16 -0
- package/c/sources/pointering/move/SourcesPointerMoveActioner.js +34 -0
- package/c/sources/pointering/up/SourcesPointerUp.js +13 -0
- package/c/sources/pointering/up/SourcesPointerUpActioner.js +38 -0
- package/c/sources/pointering/up/SourcesPointerUpActionerBucket.js +1 -0
- package/c/sources/setUpSourceDisplayFacade.js +26 -0
- package/c/sources/types/AutomaticTypeDetector.js +70 -0
- package/c/sources/types/DetectedTypeActioner.js +44 -0
- package/c/sources/types/getAutomaticTypeDetectorBucket.js +14 -0
- package/c/stage/setUpStageManager.js +57 -0
- package/c/stage/ssws.js +2 -0
- package/c/styles/createAndAppendStyles.js +9 -0
- package/c/styles/injectStylesIfNotInDom.js +8 -0
- package/c/styles/styles-injection/styles-injection.js +5 -0
- package/c/timeouts/getQueuedAction.js +15 -0
- package/cm/h/renderSvg.js +17 -0
- package/cm/nav/renderAndGetToolbarButton.js +11 -0
- package/cm/nav/renderCloseButton.js +10 -0
- package/cm/nav/renderFullscreenButton.js +43 -0
- package/cm/nav/renderNav.js +17 -0
- package/cm/nav/renderSlideNumber.js +29 -0
- package/cm/nav/renderToolbar.js +13 -0
- package/cm/renderSlideButton.js +11 -0
- package/cm/renderSlideButtonContainer.js +15 -0
- package/cm/renderSlideButtons.js +7 -0
- package/cm/renderSlideSwipingHoverer.js +6 -0
- package/cm/sources/proper-sources/renderCustom.js +15 -0
- package/cm/sources/proper-sources/renderImage.js +18 -0
- package/cm/sources/proper-sources/renderInvalid.js +18 -0
- package/cm/sources/proper-sources/renderVideo.js +31 -0
- package/cm/sources/proper-sources/renderYoutube.js +26 -0
- package/cm/sources/renderSourceWrappersContainer.js +18 -0
- package/cm/sources/saw.js +1 -0
- package/cm/sources/smw.js +1 -0
- package/cn/classes-names.js +27 -0
- package/cn/core-constants.js +6 -0
- package/cn/css-constants.js +1 -0
- package/cn/dom-constants.js +1 -0
- package/cn/elements.js +3 -0
- package/cn/local-storage-constants.js +2 -0
- package/h/elements/addToElementClassIfNotContains.js +6 -0
- package/h/elements/removeFromElementChildIfContains.js +5 -0
- package/h/elements/removeFromElementClassIfContains.js +6 -0
- package/h/objects/assignToObject.js +10 -0
- package/h/source/setUpSourceClassName.js +13 -0
- package/h/source/setUpSourceCustomAttributes.js +5 -0
- package/h/state/ifOnUpdateExistsHandleItForState.js +6 -0
- package/index.js +1 -1
- package/package.json +7 -6
- package/s.js +1 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { removeFromElementClassIfContains } from "../../h/elements/removeFromElementClassIfContains";
|
|
2
|
+
|
|
3
|
+
export function setUpClassFacade({ core: { classFacade: self }, elements }) {
|
|
4
|
+
self.removeFromEachElementClassIfContains = (elementsArrayName, className) => {
|
|
5
|
+
for (let i = 0; i < elements[elementsArrayName].length; i++) {
|
|
6
|
+
removeFromElementClassIfContains(elements[elementsArrayName][i], className);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
fs,
|
|
9
|
+
resolve
|
|
10
|
+
}
|
|
11
|
+
) {
|
|
12
|
+
const keyboardController = resolve(KeyboardController);
|
|
13
|
+
const sourcesPointerMove = resolve(SourcesPointerMove);
|
|
14
|
+
const sourcesPointerUp = resolve(SourcesPointerUp);
|
|
15
|
+
|
|
16
|
+
self.attachListeners = () => {
|
|
17
|
+
document.addEventListener('pointermove', sourcesPointerMove.listener);
|
|
18
|
+
|
|
19
|
+
document.addEventListener('pointerup', sourcesPointerUp.listener);
|
|
20
|
+
|
|
21
|
+
addEventListener('resize', windowResizeActioner.runActions);
|
|
22
|
+
|
|
23
|
+
document.addEventListener('keydown', keyboardController.listener);
|
|
24
|
+
|
|
25
|
+
fs.l();
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
self.removeListeners = () => {
|
|
29
|
+
document.removeEventListener('pointermove', sourcesPointerMove.listener);
|
|
30
|
+
|
|
31
|
+
document.removeEventListener('pointerup', sourcesPointerUp.listener);
|
|
32
|
+
|
|
33
|
+
removeEventListener('resize', windowResizeActioner.runActions);
|
|
34
|
+
|
|
35
|
+
document.removeEventListener('keydown', keyboardController.listener);
|
|
36
|
+
|
|
37
|
+
fs.q();
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function KeyboardController(
|
|
2
|
+
{
|
|
3
|
+
core: {
|
|
4
|
+
lightboxCloser,
|
|
5
|
+
slideChangeFacade
|
|
6
|
+
},
|
|
7
|
+
fs
|
|
8
|
+
}
|
|
9
|
+
) {
|
|
10
|
+
this.listener = (e) => {
|
|
11
|
+
switch (e.key) {
|
|
12
|
+
case 'Escape':
|
|
13
|
+
lightboxCloser.closeLightbox();
|
|
14
|
+
break;
|
|
15
|
+
case 'ArrowLeft':
|
|
16
|
+
slideChangeFacade.changeToPrevious();
|
|
17
|
+
break;
|
|
18
|
+
case 'ArrowRight':
|
|
19
|
+
slideChangeFacade.changeToNext();
|
|
20
|
+
break;
|
|
21
|
+
case 'F11':
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
fs.t();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FADE_OUT_STRONG_CLASS_NAME, OPEN_CLASS_NAME } from "../../../cn/classes-names";
|
|
2
|
+
import { ANIMATION_TIME } from "../../../cn/css-constants";
|
|
3
|
+
|
|
4
|
+
export function LightboxCloseActioner(
|
|
5
|
+
{
|
|
6
|
+
core: {
|
|
7
|
+
eventsDispatcher,
|
|
8
|
+
globalEventsController,
|
|
9
|
+
scrollbarRecompensor
|
|
10
|
+
},
|
|
11
|
+
data,
|
|
12
|
+
elements,
|
|
13
|
+
fs,
|
|
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.ifs) {
|
|
28
|
+
fs.x();
|
|
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 @@
|
|
|
1
|
+
export function gsw(){var e1=document.createElement("div"),s=e1.style,e2=document.createElement("div");s.visibility="hidden";s.width="100px";s.msOverflowStyle="scrollbar";s.overflow="scroll";e2.style.width='100%';document.body.appendChild(e1);var w1=e1.offsetWidth;e1.appendChild(e2);var w2=e2.offsetWidth;return w1-w2;}
|
|
@@ -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
|
+
}
|
package/c/setUpCore.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { setUpClassFacade } from "./elements/setUpClassFacade";
|
|
2
|
+
import { setUpEventsDispatcher } from "./events/setUpEventsDispatcher";
|
|
3
|
+
import{sfs}from"./sfs";
|
|
4
|
+
import { setUpGlobalEventsController } from "./events/setUpGlobalEventsController";
|
|
5
|
+
import { setUpLightboxCloser } from "./main-component/closing/setUpLightboxCloser";
|
|
6
|
+
import { setUpScrollbarRecompensor } from "./scrollbar/setUpScrollbarRecompensor";
|
|
7
|
+
import { setUpSlideIndexChanger } from "./slide/setUpSlideIndexChanger";
|
|
8
|
+
import { setUpSlideChangeFacade } from "./slide/setUpSlideChangeFacade";
|
|
9
|
+
import { setUpSourceDisplayFacade } from "./sources/setUpSourceDisplayFacade";
|
|
10
|
+
import { setUpStageManager } from "./stage/setUpStageManager";
|
|
11
|
+
import{ssws}from"./stage/ssws";
|
|
12
|
+
import { setUpSourcesPointerDown } from "./sources/pointering/down/setUpSourcesPointerDown";
|
|
13
|
+
import { setUpWindowResizeActioner } from "./sizes/setUpWindowResizeActioner";
|
|
14
|
+
|
|
15
|
+
export function setUpCore(fsLightbox) {
|
|
16
|
+
setUpClassFacade(fsLightbox);
|
|
17
|
+
setUpEventsDispatcher(fsLightbox);
|
|
18
|
+
sfs(fsLightbox);
|
|
19
|
+
setUpGlobalEventsController(fsLightbox);
|
|
20
|
+
setUpLightboxCloser(fsLightbox);
|
|
21
|
+
setUpScrollbarRecompensor(fsLightbox);
|
|
22
|
+
setUpSlideChangeFacade(fsLightbox);
|
|
23
|
+
setUpSlideIndexChanger(fsLightbox);
|
|
24
|
+
setUpSourcesPointerDown(fsLightbox);
|
|
25
|
+
setUpSourceDisplayFacade(fsLightbox);
|
|
26
|
+
setUpStageManager(fsLightbox);
|
|
27
|
+
ssws(fsLightbox);
|
|
28
|
+
setUpWindowResizeActioner(fsLightbox);
|
|
29
|
+
}
|
|
30
|
+
|
package/c/sfs.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function sfs({componentsServices,data,fs:self}){var FS_CHANGE_EVENTS_NAMES=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"];self.o=()=>{componentsServices.ofs();var documentElement=document.documentElement;if(documentElement.requestFullscreen){documentElement.requestFullscreen();}else if(documentElement.mozRequestFullScreen){documentElement.mozRequestFullScreen();}else if(documentElement.webkitRequestFullscreen){documentElement.webkitRequestFullscreen();}else if(documentElement.msRequestFullscreen){documentElement.msRequestFullscreen();}};self.x=()=>{componentsServices.xfs();if(document.exitFullscreen){document.exitFullscreen();}else if(document.mozCancelFullScreen){document.mozCancelFullScreen();}else if(document.webkitExitFullscreen){document.webkitExitFullscreen();}else if(document.msExitFullscreen){document.msExitFullscreen();}};self.t=function(){data.ifs?self.x():self.o()};self.l=function(){m("addEventListener");};self.q=function(){m("removeEventListener")};function m(listen_method_name){for(var i=0;i<FS_CHANGE_EVENTS_NAMES.length;i++){document[listen_method_name](FS_CHANGE_EVENTS_NAMES[i],l)}}function l(){document.fullscreenElement||document.webkitIsFullScreen||document.mozFullScreen||document.msFullscreenElement?componentsServices.ofs():componentsServices.xfs();}}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { removeFromElementClassIfContains } from "../../h/elements/removeFromElementClassIfContains";
|
|
2
|
+
import { TRANSFORM_TRANSITION_CLASS_NAME } from "../../cn/classes-names";
|
|
3
|
+
|
|
4
|
+
export function setUpWindowResizeActioner(
|
|
5
|
+
{
|
|
6
|
+
collections: { sourceSizers },
|
|
7
|
+
core: { windowResizeActioner: self },
|
|
8
|
+
data,
|
|
9
|
+
elements: { smw },
|
|
10
|
+
stageIndexes
|
|
11
|
+
}
|
|
12
|
+
) {
|
|
13
|
+
self.runActions = () => {
|
|
14
|
+
// decreasing max source dimensions for better UX
|
|
15
|
+
(innerWidth < 992) ?
|
|
16
|
+
data.maxSourceWidth = innerWidth :
|
|
17
|
+
data.maxSourceWidth = 0.9 * innerWidth;
|
|
18
|
+
data.maxSourceHeight = 0.9 * innerHeight;
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < smw.length; i++) {
|
|
21
|
+
smw[i].d();
|
|
22
|
+
|
|
23
|
+
// if source is Invalid or if lightbox is initialized there are no sourceSizers
|
|
24
|
+
// so we need to check if it exists
|
|
25
|
+
if (sourceSizers[i]) {
|
|
26
|
+
sourceSizers[i].adjustSize();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var pi=stageIndexes.previous,ni=stageIndexes.next;
|
|
31
|
+
if (pi !== undefined) {
|
|
32
|
+
smw[pi].ne();
|
|
33
|
+
}
|
|
34
|
+
if (ni !== undefined) {
|
|
35
|
+
smw[ni].p();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -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,89 @@
|
|
|
1
|
+
import { ANIMATION_TIME } from "../../cn/css-constants";
|
|
2
|
+
import { SOURCE_ANIMATION_WRAPPER } from "../../cn/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 "../../cn/classes-names";
|
|
8
|
+
import { removeFromElementClassIfContains } from "../../h/elements/removeFromElementClassIfContains";
|
|
9
|
+
import { getQueuedAction } from "../timeouts/getQueuedAction";
|
|
10
|
+
|
|
11
|
+
export function setUpSlideIndexChanger(
|
|
12
|
+
{
|
|
13
|
+
componentsServices,
|
|
14
|
+
core: { slideIndexChanger: self, sourceDisplayFacade, stageManager },
|
|
15
|
+
elements: { smw, sourceAnimationWrappers },
|
|
16
|
+
isl,
|
|
17
|
+
stageIndexes,
|
|
18
|
+
sws
|
|
19
|
+
}
|
|
20
|
+
) {
|
|
21
|
+
self.changeTo = (i) => {
|
|
22
|
+
stageIndexes.current = i;
|
|
23
|
+
|
|
24
|
+
stageManager.updateStageIndexes();
|
|
25
|
+
|
|
26
|
+
componentsServices.setSlideNumber(i + 1);
|
|
27
|
+
|
|
28
|
+
sourceDisplayFacade.displaySourcesWhichShouldBeDisplayed();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
self.jumpTo = (i) => {
|
|
32
|
+
var opi=stageIndexes.previous,oi=stageIndexes.current,oni=stageIndexes.next,ipl=isl[oi],icl=isl[i];
|
|
33
|
+
self.changeTo(i);
|
|
34
|
+
|
|
35
|
+
for (var j = 0; j < smw.length; j++) {
|
|
36
|
+
smw[j].d();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
sws.d(oi);
|
|
40
|
+
sws.c();
|
|
41
|
+
|
|
42
|
+
requestAnimationFrame(function(){
|
|
43
|
+
requestAnimationFrame(function(){
|
|
44
|
+
var pi=stageIndexes.previous,ni=stageIndexes.next;
|
|
45
|
+
|
|
46
|
+
// The checking whether the source is loaded was done before reflow because if source would load after a slide change but before a reflow, inexpected animation may be added—in the case of a current source, a slide change animation would be added instead of initial animation after a load.
|
|
47
|
+
if (ipl) {
|
|
48
|
+
sourceAnimationWrappers[oi]
|
|
49
|
+
.classList.add(FADE_OUT_CLASS_NAME);
|
|
50
|
+
}
|
|
51
|
+
if (icl) {
|
|
52
|
+
sourceAnimationWrappers[stageIndexes.current]
|
|
53
|
+
.classList.add(FADE_IN_CLASS_NAME);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
sws.a();
|
|
57
|
+
|
|
58
|
+
if (pi !== undefined && pi !== oi) {
|
|
59
|
+
smw[pi].ne();
|
|
60
|
+
}
|
|
61
|
+
smw[stageIndexes.current].n();
|
|
62
|
+
if (ni !== undefined && ni !== oi) {
|
|
63
|
+
smw[ni].p();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
sws.b(opi);
|
|
67
|
+
sws.b(oni);
|
|
68
|
+
|
|
69
|
+
// If source is not loaded, then there are no animations, therefore no postponed transform.
|
|
70
|
+
if (isl[oi]) {
|
|
71
|
+
setTimeout(hoss, ANIMATION_TIME - 40);
|
|
72
|
+
} else {
|
|
73
|
+
hoss();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function hoss() {
|
|
77
|
+
if (!stageManager.i(oi)) {
|
|
78
|
+
smw[oi].h();
|
|
79
|
+
smw[oi].n();
|
|
80
|
+
} else if (oi === stageIndexes.previous) {
|
|
81
|
+
smw[oi].ne();
|
|
82
|
+
} else if (oi === stageIndexes.next) {
|
|
83
|
+
smw[oi].p();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
}
|
package/c/so.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{PREFIX,OPEN_CLASS_NAME,FULL_DIMENSION_CLASS_NAME,FADE_IN_STRONG_CLASS_NAME}from"../cn/classes-names";import{setUpStageManager}from"./stage/setUpStageManager";import{createSources}from"./sources/creating/createSources";import{renderSourceWrappersContainer}from"../cm/sources/renderSourceWrappersContainer";import{renderNav}from"../cm/nav/renderNav";import{renderSlideButtons}from"../cm/renderSlideButtons";import{renderSlideSwipingHoverer}from"../cm/renderSlideSwipingHoverer";import{setUpCore}from"./setUpCore";import{gsw}from"./scrollbar/gsw";export function so(o){var{componentsServices,core:{eventsDispatcher,globalEventsController,scrollbarRecompensor,sourceDisplayFacade,stageManager,windowResizeActioner},data,elements,props,stageIndexes,sws}=o;o.open=(i=0)=>{var opi=stageIndexes.previous,oci=stageIndexes.current,oni=stageIndexes.next;stageIndexes.current=i;if(!data.i){setUpStageManager(o)}stageManager.updateStageIndexes();if(data.i){sws.c();sws.a();sws.b(opi);sws.b(oci);sws.b(oni);eventsDispatcher.dispatch("onShow")}else{ini()}stageManager.updateStageIndexes();sourceDisplayFacade.displaySourcesWhichShouldBeDisplayed();componentsServices.setSlideNumber(i+1);document.body.appendChild(elements.container);document.documentElement.classList.add(OPEN_CLASS_NAME);scrollbarRecompensor.addRecompense();globalEventsController.attachListeners();windowResizeActioner.runActions();elements.smw[stageIndexes.current].n();eventsDispatcher.dispatch("onOpen")};function ini(){data.i=true;data.scrollbarWidth=gsw(o);setUpCore(o);elements.container=document.createElement("div");elements.container.className=`${PREFIX}container ${FULL_DIMENSION_CLASS_NAME} ${FADE_IN_STRONG_CLASS_NAME}`;renderSlideSwipingHoverer(o);renderNav(o);renderSourceWrappersContainer(o);if(o.props.sources.length>1){renderSlideButtons(o);}createSources(o);eventsDispatcher.dispatch("onInit")}}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { SourceSizer } from "./SourceSizer";
|
|
2
|
+
import { FADE_IN_STRONG_CLASS_NAME, OPACITY_1_CLASS_NAME } from "../../cn/classes-names";
|
|
3
|
+
|
|
4
|
+
export function SourceLoadActioner(
|
|
5
|
+
{
|
|
6
|
+
collections: { sourceSizers },
|
|
7
|
+
elements: { sourceAnimationWrappers, sources },
|
|
8
|
+
isl,
|
|
9
|
+
resolve
|
|
10
|
+
}, i
|
|
11
|
+
) {
|
|
12
|
+
this.runActions = (defaultWidth, defaultHeight) => {
|
|
13
|
+
isl[i]=true;
|
|
14
|
+
sources[i].classList.add(OPACITY_1_CLASS_NAME);
|
|
15
|
+
sourceAnimationWrappers[i].classList.add(FADE_IN_STRONG_CLASS_NAME);
|
|
16
|
+
sourceAnimationWrappers[i]
|
|
17
|
+
.removeChild(sourceAnimationWrappers[i].firstChild);
|
|
18
|
+
|
|
19
|
+
runNormalLoadActions(defaultWidth, defaultHeight);
|
|
20
|
+
this.runActions = runNormalLoadActions;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Next loads after initial occur only while using 'srcset' so need to recreate SourceSizer.
|
|
25
|
+
*
|
|
26
|
+
* Note: Reopening lightbox does not trigger image load.
|
|
27
|
+
*/
|
|
28
|
+
function runNormalLoadActions(defaultWidth, defaultHeight) {
|
|
29
|
+
sourceSizers[i] = resolve(SourceSizer, [i, defaultWidth, defaultHeight]);
|
|
30
|
+
sourceSizers[i].adjustSize();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -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 "../../../cn/local-storage-constants";
|
|
2
|
+
import { assignToObject } from "../../../h/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
|
+
try{localStorage.setItem(SOURCES_TYPES_KEY, JSON.stringify(decodedSourceTypes));}catch{}
|
|
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
|
+
try{decodedSourceTypes = JSON.parse(localStorage.getItem(SOURCES_TYPES_KEY));}catch{}
|
|
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
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CreatingSourcesLocalStorageManager } from "./CreatingSourcesLocalStorageManager";
|
|
2
|
+
import { DetectedTypeActioner } from "../types/DetectedTypeActioner";
|
|
3
|
+
import { CreatingSourcesBucket } from "./CreatingSourcesBucket";
|
|
4
|
+
import { CUSTOM_TYPE } from "../../../cn/core-constants";
|
|
5
|
+
|
|
6
|
+
export function createSources({ props: { sources }, resolve }) {
|
|
7
|
+
const localStorageManager = resolve(CreatingSourcesLocalStorageManager);
|
|
8
|
+
const detectedTypeActioner = resolve(DetectedTypeActioner);
|
|
9
|
+
const creatingSourcesBucket = resolve(CreatingSourcesBucket, [localStorageManager, detectedTypeActioner]);
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < sources.length; i++) {
|
|
12
|
+
if (typeof sources[i] !== "string") {
|
|
13
|
+
detectedTypeActioner.runActionsForSourceTypeAndIndex(CUSTOM_TYPE, i);
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const typeSetManuallyByClient = creatingSourcesBucket.getTypeSetByClientForIndex(i);
|
|
18
|
+
if (typeSetManuallyByClient) {
|
|
19
|
+
detectedTypeActioner.runActionsForSourceTypeAndIndex(typeSetManuallyByClient, i);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const sourceTypeRetrievedWithoutXhr = localStorageManager.getSourceTypeFromLocalStorageByUrl(sources[i]);
|
|
24
|
+
(sourceTypeRetrievedWithoutXhr) ?
|
|
25
|
+
detectedTypeActioner.runActionsForSourceTypeAndIndex(sourceTypeRetrievedWithoutXhr, i) :
|
|
26
|
+
creatingSourcesBucket.retrieveTypeWithXhrForIndex(i);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SOURCE_MAIN_WRAPPERS } from "../../../../cn/elements";
|
|
2
|
+
import { TRANSFORM_TRANSITION_CLASS_NAME } from "../../../../cn/classes-names";
|
|
3
|
+
|
|
4
|
+
export function setUpSourcesPointerDown(
|
|
5
|
+
{
|
|
6
|
+
core: { classFacade, sourcesPointerDown: self },
|
|
7
|
+
elements: { smw, sources },
|
|
8
|
+
sourcePointerProps,
|
|
9
|
+
stageIndexes
|
|
10
|
+
}
|
|
11
|
+
) {
|
|
12
|
+
self.listener = (e) => {
|
|
13
|
+
/**
|
|
14
|
+
* Preventing default to disable image 'copying' behavior on Firefox desktop browser.
|
|
15
|
+
* Cannot prevent default on video click because video would become unclickable in IE11.
|
|
16
|
+
*/
|
|
17
|
+
if (e.target.tagName !== 'VIDEO') {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
sourcePointerProps.isPointering = true;
|
|
22
|
+
|
|
23
|
+
sourcePointerProps.downScreenX = e.screenX;
|
|
24
|
+
|
|
25
|
+
sourcePointerProps.swipedX = 0;
|
|
26
|
+
|
|
27
|
+
const currentElement = sources[stageIndexes.current];
|
|
28
|
+
(currentElement && currentElement.contains(e.target)) ?
|
|
29
|
+
sourcePointerProps.isSourceDownEventTarget = true :
|
|
30
|
+
sourcePointerProps.isSourceDownEventTarget = false;
|
|
31
|
+
|
|
32
|
+
for (var i=0;i<smw.length;i++) {
|
|
33
|
+
smw[i].d();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SourcesPointerMoveActioner } from "./SourcesPointerMoveActioner";
|
|
2
|
+
|
|
3
|
+
export function SourcesPointerMove({ props: { sources }, resolve, sourcePointerProps }) {
|
|
4
|
+
const sourcesPointerMoveActioner = resolve(SourcesPointerMoveActioner);
|
|
5
|
+
|
|
6
|
+
(sources.length === 1) ?
|
|
7
|
+
this.listener = () => {
|
|
8
|
+
// if there is only one slide we need to simulate swipe to prevent lightbox from closing
|
|
9
|
+
sourcePointerProps.swipedX = 1;
|
|
10
|
+
} :
|
|
11
|
+
this.listener = (e) => {
|
|
12
|
+
if (sourcePointerProps.isPointering) {
|
|
13
|
+
sourcesPointerMoveActioner.runActionsForEvent(e);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|