lightgallery 2.9.0 → 3.0.0-beta.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/LICENSE +690 -0
- package/README.md +31 -21
- package/dist/README.md +229 -0
- package/{css → dist/css}/lg-autoplay.css +7 -4
- package/{css → dist/css}/lg-autoplay.css.map +1 -1
- package/{css → dist/css}/lg-comments.css +0 -6
- package/{css → dist/css}/lg-comments.css.map +1 -1
- package/dist/css/lg-fullscreen.css +11 -0
- package/dist/css/lg-fullscreen.css.map +1 -0
- package/dist/css/lg-justified.css +37 -0
- package/dist/css/lg-justified.css.map +1 -0
- package/{css → dist/css}/lg-pager.css.map +1 -1
- package/{css → dist/css}/lg-rotate.css +0 -16
- package/{css → dist/css}/lg-rotate.css.map +1 -1
- package/dist/css/lg-rtl.css +94 -0
- package/dist/css/lg-rtl.css.map +1 -0
- package/{css → dist/css}/lg-share.css +4 -32
- package/dist/css/lg-share.css.map +1 -0
- package/{css → dist/css}/lg-thumbnail.css +7 -3
- package/dist/css/lg-thumbnail.css.map +1 -0
- package/{css → dist/css}/lg-transitions.css +10 -0
- package/dist/css/lg-transitions.css.map +1 -0
- package/{css → dist/css}/lg-zoom.css +20 -9
- package/dist/css/lg-zoom.css.map +1 -0
- package/{css → dist/css}/lightgallery-bundle.css +150 -118
- package/dist/css/lightgallery-bundle.css.map +1 -0
- package/dist/css/lightgallery-bundle.min.css +1 -0
- package/{css → dist/css}/lightgallery-core.css +49 -7
- package/dist/css/lightgallery-core.css.map +1 -0
- package/{css → dist/css}/lightgallery.css +105 -44
- package/dist/css/lightgallery.css.map +1 -0
- package/dist/lightgallery.es5.js +3848 -0
- package/dist/lightgallery.es5.js.map +1 -0
- package/dist/lightgallery.min.js +1 -0
- package/dist/lightgallery.umd.js +3851 -0
- package/dist/lightgallery.umd.js.map +1 -0
- package/dist/package.json +33 -0
- package/dist/plugins/autoplay/lg-autoplay.es5.js +193 -0
- package/dist/plugins/autoplay/lg-autoplay.es5.js.map +1 -0
- package/dist/plugins/autoplay/lg-autoplay.min.js +1 -0
- package/dist/plugins/autoplay/lg-autoplay.umd.js +196 -0
- package/dist/plugins/autoplay/lg-autoplay.umd.js.map +1 -0
- package/dist/plugins/autoplay/package.json +7 -0
- package/dist/plugins/comment/lg-comment.es5.js +136 -0
- package/dist/plugins/comment/lg-comment.es5.js.map +1 -0
- package/dist/plugins/comment/lg-comment.min.js +1 -0
- package/dist/plugins/comment/lg-comment.umd.js +139 -0
- package/dist/plugins/comment/lg-comment.umd.js.map +1 -0
- package/dist/plugins/comment/package.json +7 -0
- package/dist/plugins/fullscreen/lg-fullscreen.es5.js +114 -0
- package/dist/plugins/fullscreen/lg-fullscreen.es5.js.map +1 -0
- package/dist/plugins/fullscreen/lg-fullscreen.min.js +1 -0
- package/dist/plugins/fullscreen/lg-fullscreen.umd.js +117 -0
- package/dist/plugins/fullscreen/lg-fullscreen.umd.js.map +1 -0
- package/dist/plugins/fullscreen/package.json +7 -0
- package/dist/plugins/hash/lg-hash.es5.js +207 -0
- package/dist/plugins/hash/lg-hash.es5.js.map +1 -0
- package/dist/plugins/hash/lg-hash.min.js +1 -0
- package/dist/plugins/hash/lg-hash.umd.js +210 -0
- package/dist/plugins/hash/lg-hash.umd.js.map +1 -0
- package/dist/plugins/hash/package.json +7 -0
- package/dist/plugins/justified/lg-justified.es5.js +415 -0
- package/dist/plugins/justified/lg-justified.es5.js.map +1 -0
- package/dist/plugins/justified/lg-justified.min.js +1 -0
- package/dist/plugins/justified/lg-justified.umd.js +418 -0
- package/dist/plugins/justified/lg-justified.umd.js.map +1 -0
- package/dist/plugins/justified/package.json +7 -0
- package/dist/plugins/mediumZoom/lg-medium-zoom.es5.js +95 -0
- package/dist/plugins/mediumZoom/lg-medium-zoom.es5.js.map +1 -0
- package/dist/plugins/mediumZoom/lg-medium-zoom.min.js +1 -0
- package/dist/plugins/mediumZoom/lg-medium-zoom.umd.js +98 -0
- package/dist/plugins/mediumZoom/lg-medium-zoom.umd.js.map +1 -0
- package/dist/plugins/mediumZoom/package.json +7 -0
- package/dist/plugins/originCrop/lg-origin-crop.es5.js +622 -0
- package/dist/plugins/originCrop/lg-origin-crop.es5.js.map +1 -0
- package/dist/plugins/originCrop/lg-origin-crop.min.js +1 -0
- package/dist/plugins/originCrop/lg-origin-crop.umd.js +625 -0
- package/dist/plugins/originCrop/lg-origin-crop.umd.js.map +1 -0
- package/dist/plugins/pager/lg-pager.es5.js +96 -0
- package/dist/plugins/pager/lg-pager.es5.js.map +1 -0
- package/dist/plugins/pager/lg-pager.min.js +1 -0
- package/dist/plugins/pager/lg-pager.umd.js +99 -0
- package/dist/plugins/pager/lg-pager.umd.js.map +1 -0
- package/dist/plugins/pager/package.json +7 -0
- package/dist/plugins/relativeCaption/lg-relative-caption.es5.js +98 -0
- package/dist/plugins/relativeCaption/lg-relative-caption.es5.js.map +1 -0
- package/dist/plugins/relativeCaption/lg-relative-caption.min.js +1 -0
- package/dist/plugins/relativeCaption/lg-relative-caption.umd.js +101 -0
- package/dist/plugins/relativeCaption/lg-relative-caption.umd.js.map +1 -0
- package/dist/plugins/relativeCaption/package.json +7 -0
- package/dist/plugins/rotate/lg-rotate.es5.js +226 -0
- package/dist/plugins/rotate/lg-rotate.es5.js.map +1 -0
- package/dist/plugins/rotate/lg-rotate.min.js +1 -0
- package/dist/plugins/rotate/lg-rotate.umd.js +229 -0
- package/dist/plugins/rotate/lg-rotate.umd.js.map +1 -0
- package/dist/plugins/rotate/package.json +7 -0
- package/dist/plugins/share/lg-share.es5.js +309 -0
- package/dist/plugins/share/lg-share.es5.js.map +1 -0
- package/dist/plugins/share/lg-share.min.js +1 -0
- package/dist/plugins/share/lg-share.umd.js +312 -0
- package/dist/plugins/share/lg-share.umd.js.map +1 -0
- package/dist/plugins/share/package.json +7 -0
- package/dist/plugins/thumbnail/lg-thumbnail.es5.js +792 -0
- package/dist/plugins/thumbnail/lg-thumbnail.es5.js.map +1 -0
- package/dist/plugins/thumbnail/lg-thumbnail.min.js +1 -0
- package/dist/plugins/thumbnail/lg-thumbnail.umd.js +795 -0
- package/dist/plugins/thumbnail/lg-thumbnail.umd.js.map +1 -0
- package/dist/plugins/thumbnail/package.json +7 -0
- package/dist/plugins/video/lg-video.es5.js +518 -0
- package/dist/plugins/video/lg-video.es5.js.map +1 -0
- package/dist/plugins/video/lg-video.min.js +1 -0
- package/dist/plugins/video/lg-video.umd.js +521 -0
- package/dist/plugins/video/lg-video.umd.js.map +1 -0
- package/dist/plugins/video/package.json +7 -0
- package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.es5.js +72 -0
- package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.es5.js.map +1 -0
- package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.min.js +1 -0
- package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.umd.js +75 -0
- package/dist/plugins/vimeoThumbnail/lg-vimeo-thumbnail.umd.js.map +1 -0
- package/dist/plugins/vimeoThumbnail/package.json +7 -0
- package/dist/plugins/zoom/lg-zoom.es5.js +1412 -0
- package/dist/plugins/zoom/lg-zoom.es5.js.map +1 -0
- package/dist/plugins/zoom/lg-zoom.min.js +1 -0
- package/dist/plugins/zoom/lg-zoom.umd.js +1415 -0
- package/dist/plugins/zoom/lg-zoom.umd.js.map +1 -0
- package/dist/plugins/zoom/package.json +7 -0
- package/{scss → dist/scss}/_lg-theme-default.scss +68 -18
- package/{scss → dist/scss}/_lg-variables.scss +0 -1
- package/{scss → dist/scss}/lg-autoplay.scss +10 -4
- package/{scss → dist/scss}/lg-comments.scss +0 -8
- package/dist/scss/lg-fullscreen.scss +15 -0
- package/dist/scss/lg-justified.scss +63 -0
- package/{scss → dist/scss}/lg-rotate.scss +0 -24
- package/dist/scss/lg-rtl.scss +145 -0
- package/{scss → dist/scss}/lg-share.scss +6 -33
- package/{scss → dist/scss}/lg-thumbnail.scss +16 -5
- package/{scss → dist/scss}/lg-zoom.scss +46 -9
- package/{scss → dist/scss}/lightgallery-bundle.scss +0 -1
- package/{scss → dist/scss}/lightgallery-core.scss +73 -6
- package/{scss → dist/scss}/lightgallery.scss +0 -1
- package/{scss → dist/scss}/transitions/_lg-scale-up.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-slide-circular-vertical.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-slide-circular.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-soft-zoom.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-zoom-in-big.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-zoom-in-out.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-zoom-in.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-zoom-out-big.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-zoom-out-in.scss +6 -0
- package/{scss → dist/scss}/transitions/_lg-zoom-out.scss +6 -0
- package/{index.d.ts → dist/types/index.d.ts} +8 -4
- package/{lg-events.d.ts → dist/types/lg-events.d.ts} +300 -300
- package/dist/types/lg-icons.d.ts +27 -0
- package/{lg-plugin.d.ts → dist/types/lg-plugin.d.ts} +7 -7
- package/{lg-settings.d.ts → dist/types/lg-settings.d.ts} +555 -425
- package/dist/types/lg-spring-runner.d.ts +14 -0
- package/dist/types/lg-toolbar-overflow.d.ts +36 -0
- package/{lg-utils.d.ts → dist/types/lg-utils.d.ts} +236 -228
- package/{lgQuery.d.ts → dist/types/lgQuery.d.ts} +56 -56
- package/{lightgallery.d.ts → dist/types/lightgallery.d.ts} +385 -305
- package/{plugins → dist/types/plugins}/autoplay/lg-autoplay-settings.d.ts +41 -38
- package/{plugins → dist/types/plugins}/autoplay/lg-autoplay.d.ts +22 -22
- package/{plugins → dist/types/plugins}/comment/lg-comment-settings.d.ts +36 -33
- package/{plugins → dist/types/plugins}/comment/lg-comment.d.ts +25 -25
- package/{plugins → dist/types/plugins}/fullscreen/lg-fullscreen-settings.d.ts +17 -14
- package/{plugins → dist/types/plugins}/fullscreen/lg-fullscreen.d.ts +16 -16
- package/dist/types/plugins/hash/lg-hash-settings.d.ts +28 -0
- package/{plugins → dist/types/plugins}/hash/lg-hash.d.ts +25 -23
- package/dist/types/plugins/justified/lg-justified-settings.d.ts +42 -0
- package/dist/types/plugins/justified/lg-justified.d.ts +55 -0
- package/{plugins → dist/types/plugins}/mediumZoom/lg-medium-zoom-settings.d.ts +16 -16
- package/{plugins → dist/types/plugins}/mediumZoom/lg-medium-zoom.d.ts +12 -12
- package/dist/types/plugins/originCrop/lg-origin-crop-settings.d.ts +12 -0
- package/dist/types/plugins/originCrop/lg-origin-crop.d.ts +79 -0
- package/{plugins → dist/types/plugins}/pager/lg-pager-settings.d.ts +7 -7
- package/{plugins → dist/types/plugins}/pager/lg-pager.d.ts +13 -13
- package/{plugins → dist/types/plugins}/relativeCaption/lg-relative-caption-settings.d.ts +7 -7
- package/{plugins → dist/types/plugins}/relativeCaption/lg-relative-caption.d.ts +14 -14
- package/{plugins → dist/types/plugins}/rotate/lg-rotate-settings.d.ts +47 -45
- package/{plugins → dist/types/plugins}/rotate/lg-rotate.d.ts +25 -24
- package/{plugins → dist/types/plugins}/share/lg-fb-share-utils.d.ts +2 -2
- package/{plugins → dist/types/plugins}/share/lg-pinterest-share-utils.d.ts +2 -2
- package/{plugins → dist/types/plugins}/share/lg-share-settings.d.ts +71 -56
- package/dist/types/plugins/share/lg-share.d.ts +33 -0
- package/dist/types/plugins/share/lg-twitter-share-utils.d.ts +4 -0
- package/{plugins → dist/types/plugins}/share/types.d.ts +6 -6
- package/{plugins → dist/types/plugins}/thumbnail/lg-thumbnail-settings.d.ts +85 -70
- package/dist/types/plugins/thumbnail/lg-thumbnail.d.ts +88 -0
- package/{plugins → dist/types/plugins}/video/lg-video-settings.d.ts +94 -71
- package/{plugins → dist/types/plugins}/video/lg-video.d.ts +116 -104
- package/{plugins → dist/types/plugins}/video/types.d.ts +8 -8
- package/{plugins → dist/types/plugins}/vimeoThumbnail/lg-vimeo-thumbnail-settings.d.ts +11 -11
- package/{plugins → dist/types/plugins}/vimeoThumbnail/lg-vimeo-thumbnail.d.ts +14 -14
- package/{plugins → dist/types/plugins}/zoom/lg-zoom-settings.d.ts +54 -51
- package/{plugins → dist/types/plugins}/zoom/lg-zoom.d.ts +145 -108
- package/{types.d.ts → dist/types/types.d.ts} +40 -40
- package/package.json +237 -8
- package/angular/10/README.md +0 -24
- package/angular/10/bundles/lightgallery-angular-10.umd.js +0 -289
- package/angular/10/bundles/lightgallery-angular-10.umd.js.map +0 -1
- package/angular/10/bundles/lightgallery-angular-10.umd.min.js +0 -2
- package/angular/10/bundles/lightgallery-angular-10.umd.min.js.map +0 -1
- package/angular/10/esm2015/lib/lightgallery-angular.component.js +0 -225
- package/angular/10/esm2015/lib/lightgallery-angular.module.js +0 -17
- package/angular/10/esm2015/lib/lightgallery-angular.service.js +0 -14
- package/angular/10/esm2015/lightgallery-angular-10.js +0 -5
- package/angular/10/esm2015/public-api.js +0 -7
- package/angular/10/fesm2015/lightgallery-angular-10.js +0 -261
- package/angular/10/fesm2015/lightgallery-angular-10.js.map +0 -1
- package/angular/10/lib/lightgallery-angular.component.d.ts +0 -39
- package/angular/10/lib/lightgallery-angular.component.d.ts.map +0 -1
- package/angular/10/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/10/lib/lightgallery-angular.module.d.ts.map +0 -1
- package/angular/10/lib/lightgallery-angular.service.d.ts +0 -7
- package/angular/10/lib/lightgallery-angular.service.d.ts.map +0 -1
- package/angular/10/lightgallery-angular-10.d.ts +0 -6
- package/angular/10/lightgallery-angular-10.d.ts.map +0 -1
- package/angular/10/package.json +0 -21
- package/angular/10/public-api.d.ts +0 -4
- package/angular/10/public-api.d.ts.map +0 -1
- package/angular/11/README.md +0 -24
- package/angular/11/bundles/lightgallery-angular-11.umd.js +0 -290
- package/angular/11/bundles/lightgallery-angular-11.umd.js.map +0 -1
- package/angular/11/bundles/lightgallery-angular-11.umd.min.js +0 -2
- package/angular/11/bundles/lightgallery-angular-11.umd.min.js.map +0 -1
- package/angular/11/esm2015/lib/lightgallery-angular.component.js +0 -225
- package/angular/11/esm2015/lib/lightgallery-angular.module.js +0 -18
- package/angular/11/esm2015/lib/lightgallery-angular.service.js +0 -14
- package/angular/11/esm2015/lightgallery-angular-11.js +0 -5
- package/angular/11/esm2015/public-api.js +0 -7
- package/angular/11/fesm2015/lightgallery-angular-11.js +0 -262
- package/angular/11/fesm2015/lightgallery-angular-11.js.map +0 -1
- package/angular/11/lib/lightgallery-angular.component.d.ts +0 -39
- package/angular/11/lib/lightgallery-angular.component.d.ts.map +0 -1
- package/angular/11/lib/lightgallery-angular.module.d.ts +0 -8
- package/angular/11/lib/lightgallery-angular.module.d.ts.map +0 -1
- package/angular/11/lib/lightgallery-angular.service.d.ts +0 -7
- package/angular/11/lib/lightgallery-angular.service.d.ts.map +0 -1
- package/angular/11/lightgallery-angular-11.d.ts +0 -6
- package/angular/11/lightgallery-angular-11.d.ts.map +0 -1
- package/angular/11/package.json +0 -21
- package/angular/11/public-api.d.ts +0 -4
- package/angular/11/public-api.d.ts.map +0 -1
- package/angular/12/README.md +0 -24
- package/angular/12/bundles/lightgallery-angular-12.umd.js +0 -296
- package/angular/12/bundles/lightgallery-angular-12.umd.js.map +0 -1
- package/angular/12/esm2015/lib/lightgallery-angular.component.js +0 -221
- package/angular/12/esm2015/lib/lightgallery-angular.module.js +0 -17
- package/angular/12/esm2015/lib/lightgallery-angular.service.js +0 -14
- package/angular/12/esm2015/lightgallery-angular-12.js +0 -5
- package/angular/12/esm2015/public-api.js +0 -7
- package/angular/12/fesm2015/lightgallery-angular-12.js +0 -258
- package/angular/12/fesm2015/lightgallery-angular-12.js.map +0 -1
- package/angular/12/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/12/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/12/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/12/lightgallery-angular-12.d.ts +0 -5
- package/angular/12/package.json +0 -18
- package/angular/12/public-api.d.ts +0 -3
- package/angular/13/README.md +0 -24
- package/angular/13/esm2020/lib/lightgallery-angular.component.mjs +0 -221
- package/angular/13/esm2020/lib/lightgallery-angular.module.mjs +0 -17
- package/angular/13/esm2020/lib/lightgallery-angular.service.mjs +0 -14
- package/angular/13/esm2020/lightgallery-angular-13.mjs +0 -5
- package/angular/13/esm2020/public-api.mjs +0 -7
- package/angular/13/fesm2015/lightgallery-angular-13.mjs +0 -258
- package/angular/13/fesm2015/lightgallery-angular-13.mjs.map +0 -1
- package/angular/13/fesm2020/lightgallery-angular-13.mjs +0 -258
- package/angular/13/fesm2020/lightgallery-angular-13.mjs.map +0 -1
- package/angular/13/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/13/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/13/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/13/lightgallery-angular-13.d.ts +0 -5
- package/angular/13/package.json +0 -31
- package/angular/13/public-api.d.ts +0 -3
- package/angular/14/README.md +0 -24
- package/angular/14/esm2020/lib/lightgallery-angular.component.mjs +0 -217
- package/angular/14/esm2020/lib/lightgallery-angular.module.mjs +0 -17
- package/angular/14/esm2020/lib/lightgallery-angular.service.mjs +0 -14
- package/angular/14/esm2020/lightgallery-angular-14.mjs +0 -5
- package/angular/14/esm2020/public-api.mjs +0 -7
- package/angular/14/fesm2015/lightgallery-angular-14.mjs +0 -254
- package/angular/14/fesm2015/lightgallery-angular-14.mjs.map +0 -1
- package/angular/14/fesm2020/lightgallery-angular-14.mjs +0 -254
- package/angular/14/fesm2020/lightgallery-angular-14.mjs.map +0 -1
- package/angular/14/index.d.ts +0 -5
- package/angular/14/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/14/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/14/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/14/package.json +0 -31
- package/angular/14/public-api.d.ts +0 -3
- package/angular/15/README.md +0 -24
- package/angular/15/esm2022/lib/lightgallery-angular.component.mjs +0 -218
- package/angular/15/esm2022/lib/lightgallery-angular.module.mjs +0 -18
- package/angular/15/esm2022/lib/lightgallery-angular.service.mjs +0 -15
- package/angular/15/esm2022/lightgallery-angular-15.mjs +0 -5
- package/angular/15/esm2022/public-api.mjs +0 -7
- package/angular/15/fesm2022/lightgallery-angular-15.mjs +0 -254
- package/angular/15/fesm2022/lightgallery-angular-15.mjs.map +0 -1
- package/angular/15/index.d.ts +0 -5
- package/angular/15/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/15/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/15/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/15/package.json +0 -25
- package/angular/15/public-api.d.ts +0 -3
- package/angular/16/README.md +0 -24
- package/angular/16/esm2022/lib/lightgallery-angular.component.mjs +0 -218
- package/angular/16/esm2022/lib/lightgallery-angular.module.mjs +0 -18
- package/angular/16/esm2022/lib/lightgallery-angular.service.mjs +0 -15
- package/angular/16/esm2022/lightgallery-angular-16.mjs +0 -5
- package/angular/16/esm2022/public-api.mjs +0 -7
- package/angular/16/fesm2022/lightgallery-angular-16.mjs +0 -254
- package/angular/16/fesm2022/lightgallery-angular-16.mjs.map +0 -1
- package/angular/16/index.d.ts +0 -5
- package/angular/16/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/16/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/16/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/16/package.json +0 -25
- package/angular/16/public-api.d.ts +0 -3
- package/angular/9/README.md +0 -24
- package/angular/9/bundles/lightgallery-angular-9.umd.js +0 -271
- package/angular/9/bundles/lightgallery-angular-9.umd.js.map +0 -1
- package/angular/9/bundles/lightgallery-angular-9.umd.min.js +0 -2
- package/angular/9/bundles/lightgallery-angular-9.umd.min.js.map +0 -1
- package/angular/9/esm2015/lib/lightgallery-angular.component.js +0 -225
- package/angular/9/esm2015/lib/lightgallery-angular.module.js +0 -17
- package/angular/9/esm2015/lib/lightgallery-angular.service.js +0 -14
- package/angular/9/esm2015/lightgallery-angular-9.js +0 -5
- package/angular/9/esm2015/public-api.js +0 -7
- package/angular/9/esm5/lib/lightgallery-angular.component.js +0 -228
- package/angular/9/esm5/lib/lightgallery-angular.module.js +0 -21
- package/angular/9/esm5/lib/lightgallery-angular.service.js +0 -17
- package/angular/9/esm5/lightgallery-angular-9.js +0 -5
- package/angular/9/esm5/public-api.js +0 -7
- package/angular/9/fesm2015/lightgallery-angular-9.js +0 -261
- package/angular/9/fesm2015/lightgallery-angular-9.js.map +0 -1
- package/angular/9/fesm5/lightgallery-angular-9.js +0 -268
- package/angular/9/fesm5/lightgallery-angular-9.js.map +0 -1
- package/angular/9/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/9/lib/lightgallery-angular.module.d.ts +0 -6
- package/angular/9/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/9/lightgallery-angular-9.d.ts +0 -5
- package/angular/9/package.json +0 -23
- package/angular/9/public-api.d.ts +0 -3
- package/angular/README.md +0 -24
- package/angular/esm2022/lib/lightgallery-angular.component.mjs +0 -218
- package/angular/esm2022/lib/lightgallery-angular.module.mjs +0 -18
- package/angular/esm2022/lib/lightgallery-angular.service.mjs +0 -15
- package/angular/esm2022/lightgallery-angular.mjs +0 -5
- package/angular/esm2022/public-api.mjs +0 -7
- package/angular/fesm2022/lightgallery-angular.mjs +0 -254
- package/angular/fesm2022/lightgallery-angular.mjs.map +0 -1
- package/angular/index.d.ts +0 -5
- package/angular/lib/lightgallery-angular.component.d.ts +0 -38
- package/angular/lib/lightgallery-angular.module.d.ts +0 -7
- package/angular/lib/lightgallery-angular.service.d.ts +0 -6
- package/angular/package.json +0 -25
- package/angular/public-api.d.ts +0 -3
- package/css/lg-fullscreen.css +0 -8
- package/css/lg-fullscreen.css.map +0 -1
- package/css/lg-share.css.map +0 -1
- package/css/lg-thumbnail.css.map +0 -1
- package/css/lg-transitions.css.map +0 -1
- package/css/lg-zoom.css.map +0 -1
- package/css/lightgallery-bundle.css.map +0 -1
- package/css/lightgallery-bundle.min.css +0 -1
- package/css/lightgallery-core.css.map +0 -1
- package/css/lightgallery.css.map +0 -1
- package/fonts/lg.svg +0 -54
- package/fonts/lg.ttf +0 -0
- package/fonts/lg.woff +0 -0
- package/fonts/lg.woff2 +0 -0
- package/lib/index.js +0 -8
- package/lib/index.js.map +0 -1
- package/lib/lg-events.js +0 -37
- package/lib/lg-events.js.map +0 -1
- package/lib/lg-plugin.js +0 -13
- package/lib/lg-plugin.js.map +0 -1
- package/lib/lg-settings.js +0 -83
- package/lib/lg-settings.js.map +0 -1
- package/lib/lg-utils.js +0 -328
- package/lib/lg-utils.js.map +0 -1
- package/lib/lgQuery.js +0 -385
- package/lib/lgQuery.js.map +0 -1
- package/lib/lightgallery.js +0 -1949
- package/lib/lightgallery.js.map +0 -1
- package/lib/plugins/autoplay/lg-autoplay-settings.js +0 -16
- package/lib/plugins/autoplay/lg-autoplay-settings.js.map +0 -1
- package/lib/plugins/autoplay/lg-autoplay.js +0 -184
- package/lib/plugins/autoplay/lg-autoplay.js.map +0 -1
- package/lib/plugins/comment/lg-comment-settings.js +0 -17
- package/lib/plugins/comment/lg-comment-settings.js.map +0 -1
- package/lib/plugins/comment/lg-comment.js +0 -140
- package/lib/plugins/comment/lg-comment.js.map +0 -1
- package/lib/plugins/fullscreen/lg-fullscreen-settings.js +0 -10
- package/lib/plugins/fullscreen/lg-fullscreen-settings.js.map +0 -1
- package/lib/plugins/fullscreen/lg-fullscreen.js +0 -108
- package/lib/plugins/fullscreen/lg-fullscreen.js.map +0 -1
- package/lib/plugins/hash/lg-hash-settings.js +0 -9
- package/lib/plugins/hash/lg-hash-settings.js.map +0 -1
- package/lib/plugins/hash/lg-hash.js +0 -139
- package/lib/plugins/hash/lg-hash.js.map +0 -1
- package/lib/plugins/mediumZoom/lg-medium-zoom-settings.js +0 -9
- package/lib/plugins/mediumZoom/lg-medium-zoom-settings.js.map +0 -1
- package/lib/plugins/mediumZoom/lg-medium-zoom.js +0 -73
- package/lib/plugins/mediumZoom/lg-medium-zoom.js.map +0 -1
- package/lib/plugins/pager/lg-pager-settings.js +0 -7
- package/lib/plugins/pager/lg-pager-settings.js.map +0 -1
- package/lib/plugins/pager/lg-pager.js +0 -82
- package/lib/plugins/pager/lg-pager.js.map +0 -1
- package/lib/plugins/relativeCaption/lg-relative-caption-settings.js +0 -7
- package/lib/plugins/relativeCaption/lg-relative-caption-settings.js.map +0 -1
- package/lib/plugins/relativeCaption/lg-relative-caption.js +0 -97
- package/lib/plugins/relativeCaption/lg-relative-caption.js.map +0 -1
- package/lib/plugins/rotate/lg-rotate-settings.js +0 -18
- package/lib/plugins/rotate/lg-rotate-settings.js.map +0 -1
- package/lib/plugins/rotate/lg-rotate.js +0 -206
- package/lib/plugins/rotate/lg-rotate.js.map +0 -1
- package/lib/plugins/share/lg-fb-share-utils.js +0 -10
- package/lib/plugins/share/lg-fb-share-utils.js.map +0 -1
- package/lib/plugins/share/lg-pinterest-share-utils.js +0 -17
- package/lib/plugins/share/lg-pinterest-share-utils.js.map +0 -1
- package/lib/plugins/share/lg-share-settings.js +0 -15
- package/lib/plugins/share/lg-share-settings.js.map +0 -1
- package/lib/plugins/share/lg-share.js +0 -130
- package/lib/plugins/share/lg-share.js.map +0 -1
- package/lib/plugins/share/lg-twitter-share-utils.js +0 -11
- package/lib/plugins/share/lg-twitter-share-utils.js.map +0 -1
- package/lib/plugins/share/types.js +0 -3
- package/lib/plugins/share/types.js.map +0 -1
- package/lib/plugins/thumbnail/lg-thumbnail-settings.js +0 -23
- package/lib/plugins/thumbnail/lg-thumbnail-settings.js.map +0 -1
- package/lib/plugins/thumbnail/lg-thumbnail.js +0 -414
- package/lib/plugins/thumbnail/lg-thumbnail.js.map +0 -1
- package/lib/plugins/video/lg-video-settings.js +0 -15
- package/lib/plugins/video/lg-video-settings.js.map +0 -1
- package/lib/plugins/video/lg-video-utils.js +0 -84
- package/lib/plugins/video/lg-video-utils.js.map +0 -1
- package/lib/plugins/video/lg-video.js +0 -411
- package/lib/plugins/video/lg-video.js.map +0 -1
- package/lib/plugins/video/types.js +0 -3
- package/lib/plugins/video/types.js.map +0 -1
- package/lib/plugins/vimeoThumbnail/lg-vimeo-thumbnail-settings.js +0 -8
- package/lib/plugins/vimeoThumbnail/lg-vimeo-thumbnail-settings.js.map +0 -1
- package/lib/plugins/vimeoThumbnail/lg-vimeo-thumbnail.js +0 -122
- package/lib/plugins/vimeoThumbnail/lg-vimeo-thumbnail.js.map +0 -1
- package/lib/plugins/zoom/lg-zoom-settings.js +0 -21
- package/lib/plugins/zoom/lg-zoom-settings.js.map +0 -1
- package/lib/plugins/zoom/lg-zoom.js +0 -909
- package/lib/plugins/zoom/lg-zoom.js.map +0 -1
- package/lib/types.js +0 -3
- package/lib/types.js.map +0 -1
- package/lightgallery-2.9.0.tgz +0 -0
- package/lightgallery.es5.js +0 -2786
- package/lightgallery.es5.js.map +0 -1
- package/lightgallery.min.js +0 -8
- package/lightgallery.umd.js +0 -2794
- package/lightgallery.umd.js.map +0 -1
- package/lit/custom-elements.json +0 -82
- package/lit/lightgallery.esm.js +0 -59
- package/lit/lightgallery.umd.js +0 -37
- package/lit/package.json +0 -8
- package/plugins/autoplay/lg-autoplay.es5.js +0 -250
- package/plugins/autoplay/lg-autoplay.es5.js.map +0 -1
- package/plugins/autoplay/lg-autoplay.min.js +0 -8
- package/plugins/autoplay/lg-autoplay.umd.js +0 -258
- package/plugins/autoplay/lg-autoplay.umd.js.map +0 -1
- package/plugins/autoplay/package.json +0 -7
- package/plugins/comment/lg-comment.es5.js +0 -205
- package/plugins/comment/lg-comment.es5.js.map +0 -1
- package/plugins/comment/lg-comment.min.js +0 -8
- package/plugins/comment/lg-comment.umd.js +0 -213
- package/plugins/comment/lg-comment.umd.js.map +0 -1
- package/plugins/comment/package.json +0 -7
- package/plugins/fullscreen/lg-fullscreen.es5.js +0 -135
- package/plugins/fullscreen/lg-fullscreen.es5.js.map +0 -1
- package/plugins/fullscreen/lg-fullscreen.min.js +0 -8
- package/plugins/fullscreen/lg-fullscreen.umd.js +0 -143
- package/plugins/fullscreen/lg-fullscreen.umd.js.map +0 -1
- package/plugins/fullscreen/package.json +0 -7
- package/plugins/hash/lg-hash-settings.d.ts +0 -16
- package/plugins/hash/lg-hash.es5.js +0 -198
- package/plugins/hash/lg-hash.es5.js.map +0 -1
- package/plugins/hash/lg-hash.min.js +0 -8
- package/plugins/hash/lg-hash.umd.js +0 -206
- package/plugins/hash/lg-hash.umd.js.map +0 -1
- package/plugins/hash/package.json +0 -7
- package/plugins/mediumZoom/lg-medium-zoom.es5.js +0 -132
- package/plugins/mediumZoom/lg-medium-zoom.es5.js.map +0 -1
- package/plugins/mediumZoom/lg-medium-zoom.min.js +0 -8
- package/plugins/mediumZoom/lg-medium-zoom.umd.js +0 -140
- package/plugins/mediumZoom/lg-medium-zoom.umd.js.map +0 -1
- package/plugins/mediumZoom/package.json +0 -7
- package/plugins/pager/lg-pager.es5.js +0 -139
- package/plugins/pager/lg-pager.es5.js.map +0 -1
- package/plugins/pager/lg-pager.min.js +0 -8
- package/plugins/pager/lg-pager.umd.js +0 -147
- package/plugins/pager/lg-pager.umd.js.map +0 -1
- package/plugins/pager/package.json +0 -7
- package/plugins/relativeCaption/lg-relative-caption.es5.js +0 -154
- package/plugins/relativeCaption/lg-relative-caption.es5.js.map +0 -1
- package/plugins/relativeCaption/lg-relative-caption.min.js +0 -8
- package/plugins/relativeCaption/lg-relative-caption.umd.js +0 -162
- package/plugins/relativeCaption/lg-relative-caption.umd.js.map +0 -1
- package/plugins/relativeCaption/package.json +0 -7
- package/plugins/rotate/lg-rotate.es5.js +0 -274
- package/plugins/rotate/lg-rotate.es5.js.map +0 -1
- package/plugins/rotate/lg-rotate.min.js +0 -8
- package/plugins/rotate/lg-rotate.umd.js +0 -282
- package/plugins/rotate/lg-rotate.umd.js.map +0 -1
- package/plugins/rotate/package.json +0 -7
- package/plugins/share/lg-share.d.ts +0 -15
- package/plugins/share/lg-share.es5.js +0 -219
- package/plugins/share/lg-share.es5.js.map +0 -1
- package/plugins/share/lg-share.min.js +0 -8
- package/plugins/share/lg-share.umd.js +0 -227
- package/plugins/share/lg-share.umd.js.map +0 -1
- package/plugins/share/lg-twitter-share-utils.d.ts +0 -2
- package/plugins/share/package.json +0 -7
- package/plugins/thumbnail/lg-thumbnail.d.ts +0 -48
- package/plugins/thumbnail/lg-thumbnail.es5.js +0 -487
- package/plugins/thumbnail/lg-thumbnail.es5.js.map +0 -1
- package/plugins/thumbnail/lg-thumbnail.min.js +0 -8
- package/plugins/thumbnail/lg-thumbnail.umd.js +0 -495
- package/plugins/thumbnail/lg-thumbnail.umd.js.map +0 -1
- package/plugins/thumbnail/package.json +0 -7
- package/plugins/video/lg-video-utils.d.ts +0 -10
- package/plugins/video/lg-video.es5.js +0 -545
- package/plugins/video/lg-video.es5.js.map +0 -1
- package/plugins/video/lg-video.min.js +0 -8
- package/plugins/video/lg-video.umd.js +0 -553
- package/plugins/video/lg-video.umd.js.map +0 -1
- package/plugins/video/package.json +0 -7
- package/plugins/vimeoThumbnail/lg-vimeo-thumbnail.es5.js +0 -182
- package/plugins/vimeoThumbnail/lg-vimeo-thumbnail.es5.js.map +0 -1
- package/plugins/vimeoThumbnail/lg-vimeo-thumbnail.min.js +0 -8
- package/plugins/vimeoThumbnail/lg-vimeo-thumbnail.umd.js +0 -190
- package/plugins/vimeoThumbnail/lg-vimeo-thumbnail.umd.js.map +0 -1
- package/plugins/vimeoThumbnail/package.json +0 -7
- package/plugins/zoom/lg-zoom.es5.js +0 -980
- package/plugins/zoom/lg-zoom.es5.js.map +0 -1
- package/plugins/zoom/lg-zoom.min.js +0 -8
- package/plugins/zoom/lg-zoom.umd.js +0 -988
- package/plugins/zoom/lg-zoom.umd.js.map +0 -1
- package/plugins/zoom/package.json +0 -7
- package/react/Lightgallery.d.ts +0 -33
- package/react/Lightgallery.es5.js +0 -2988
- package/react/Lightgallery.es5.js.map +0 -1
- package/react/Lightgallery.umd.js +0 -2994
- package/react/Lightgallery.umd.js.map +0 -1
- package/react/package.json +0 -7
- package/scss/_lg-fonts.scss +0 -27
- package/scss/lg-fullscreen.scss +0 -9
- package/vue/LightGallery.vue.d.ts +0 -37
- package/vue/LightGalleryVue.common.js +0 -9343
- package/vue/LightGalleryVue.common.js.map +0 -1
- package/vue/LightGalleryVue.umd.js +0 -9353
- package/vue/LightGalleryVue.umd.js.map +0 -1
- package/vue/LightGalleryVue.umd.min.js +0 -8
- package/vue/LightGalleryVue.umd.min.js.map +0 -1
- package/vue/package.json +0 -7
- /package/{css → dist/css}/lg-medium-zoom.css +0 -0
- /package/{css → dist/css}/lg-medium-zoom.css.map +0 -0
- /package/{css → dist/css}/lg-pager.css +0 -0
- /package/{css → dist/css}/lg-relative-caption.css +0 -0
- /package/{css → dist/css}/lg-relative-caption.css.map +0 -0
- /package/{css → dist/css}/lg-video.css +0 -0
- /package/{css → dist/css}/lg-video.css.map +0 -0
- /package/{images → dist/images}/loading.gif +0 -0
- /package/{scss → dist/scss}/_lg-mixins.scss +0 -0
- /package/{scss → dist/scss}/lg-medium-zoom.scss +0 -0
- /package/{scss → dist/scss}/lg-pager.scss +0 -0
- /package/{scss → dist/scss}/lg-relative-caption.scss +0 -0
- /package/{scss → dist/scss}/lg-transitions.scss +0 -0
- /package/{scss → dist/scss}/lg-video.scss +0 -0
- /package/{scss → dist/scss}/transitions/_index.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-lollipop-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-lollipop.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-rotate-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-rotate.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-cross-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-cross.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-only-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-only-y-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-only-y.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-only.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-ver-cross-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-ver-cross.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-ver-rev.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew-ver.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-skew.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-vertical-growth.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-slide-vertical.scss +0 -0
- /package/{scss → dist/scss}/transitions/_lg-tube.scss +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lg-justified.es5.js","sources":["../../../packages/headless/src/origin.ts","../../../packages/headless/src/justified-layout.ts","../../../src/lg-events.ts","../../../src/plugins/justified/lg-justified-settings.ts","../../../src/plugins/justified/lg-justified.ts"],"sourcesContent":["/**\n * Zoom-from-origin math, ported from 2.x `utils.getSize`/`utils.getTransform`\n * (`src/lg-utils.ts`) as pure rect arithmetic. The framework layer measures\n * the DOM (trigger/container bounding rects) and passes plain numbers in.\n *\n * Note: this module is an addition to the ADR 0001 §1 table — it\n * follows the standing rule that pure functions needed by React live in\n * headless. It is distinct from `zoom-math.ts` (zoom plugin).\n */\n\nexport interface ImageSize {\n width: number;\n height: number;\n}\n\nexport interface RectLike {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Parse an item's `lgSize` value (`\"1920-1280\"`, or a responsive list like\n * `\"240-160-375, 1600-1067\"` where the third number is the max viewport\n * width the entry applies to).\n */\nexport function parseImageSize(\n lgSize: string | undefined,\n viewportWidth: number,\n): ImageSize | undefined {\n if (!lgSize) {\n return undefined;\n }\n let size = lgSize;\n const responsiveSizes = lgSize.split(',');\n if (responsiveSizes[1]) {\n for (let i = 0; i < responsiveSizes.length; i++) {\n const candidate = responsiveSizes[i]!.trim();\n const responsiveWidth = parseInt(candidate.split('-')[2]!, 10);\n if (responsiveWidth > viewportWidth) {\n size = candidate;\n break;\n }\n if (i === responsiveSizes.length - 1) {\n size = candidate;\n }\n }\n }\n const parts = size.trim().split('-');\n const width = parseInt(parts[0]!, 10);\n const height = parseInt(parts[1]!, 10);\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n return undefined;\n }\n return { width, height };\n}\n\n/**\n * Fit a natural image size into the available container box, preserving\n * aspect ratio and never scaling up (2.x `utils.getSize` math).\n */\nexport function fitImageSize(\n size: ImageSize,\n containerWidth: number,\n containerHeight: number,\n): ImageSize {\n const maxWidth = Math.min(containerWidth, size.width);\n const maxHeight = Math.min(containerHeight, size.height);\n const ratio = Math.min(maxWidth / size.width, maxHeight / size.height);\n return { width: size.width * ratio, height: size.height * ratio };\n}\n\n/**\n * Whether a measured trigger rect can anchor the zoom-from-origin flight.\n * A trigger that is hidden (`display: none`, the `hidden` attribute),\n * detached or collapsed measures 0×0 at the viewport origin; a flight\n * aimed at it would shrink the slide into the top-left corner.\n */\nexport function isUsableOriginRect(\n rect: RectLike | null | undefined,\n): rect is RectLike {\n return (\n !!rect &&\n Number.isFinite(rect.left) &&\n Number.isFinite(rect.top) &&\n rect.width > 0 &&\n rect.height > 0\n );\n}\n\n/** Scale the closing slide shrinks to when it has no trigger to return to. */\nexport const CENTER_CLOSE_SCALE = 0.5;\n\n/**\n * Close transform for a slide without a usable origin (hidden or\n * collapsed trigger, no `lgSize`): shrink in place about the stage centre,\n * the mirror of the `lg-start-zoom` open. The runtime pairs it with the\n * `lg-close-to-center` class, which fades the slide out over the same\n * duration.\n */\nexport function getCenterCloseTransform(scale = CENTER_CLOSE_SCALE): string {\n return `translate3d(0, 0, 0) scale3d(${scale}, ${scale}, 1)`;\n}\n\nexport interface OriginTransformInput {\n /** Bounding rect of the trigger thumbnail image, viewport coordinates. */\n triggerRect: RectLike;\n\n /** Bounding rect of the gallery outer element, viewport coordinates. */\n containerRect: RectLike;\n\n /** Media container top offset (toolbar height), px. */\n top: number;\n\n /** Media container bottom offset (caption + thumb strip height), px. */\n bottom: number;\n\n /** Final displayed image size (see {@link fitImageSize}). */\n imageSize: ImageSize;\n}\n\n/**\n * CSS transform that places the (centered, final-size) slide image exactly\n * over the trigger thumbnail — the starting point of the zoom-from-origin\n * open animation and the end point of the close animation.\n */\nexport function getOriginTransform(input: OriginTransformInput): string {\n const { triggerRect, containerRect, top, bottom, imageSize } = input;\n\n const availableWidth = containerRect.width;\n const availableHeight = containerRect.height - (top + bottom);\n\n const x =\n (availableWidth - triggerRect.width) / 2 -\n triggerRect.left +\n containerRect.left;\n const y =\n (availableHeight - triggerRect.height) / 2 - triggerRect.top + top;\n\n const scaleX = triggerRect.width / imageSize.width;\n const scaleY = triggerRect.height / imageSize.height;\n\n return `translate3d(${-x}px, ${-y}px, 0) scale3d(${scaleX}, ${scaleY}, 1)`;\n}\n","/**\n * Justified grid layout for the trigger thumbnails: rows of equal\n * height and varying widths that fill the container edge to edge, the\n * row height staying as close as possible to a target. Pure math —\n * runtimes measure the container, hand in aspect ratios, and position\n * elements from the returned boxes.\n */\n\nexport interface JustifiedLayoutOptions {\n /** Aspect ratios (width / height) in item order. */\n ratios: readonly number[];\n /** Content-box width available for rows (px). */\n containerWidth: number;\n /** Row height (px) the algorithm aims for. */\n targetRowHeight?: number;\n /** Gap between items and between rows (px). */\n gap?: number;\n /**\n * Last-row policy: `'justify'` scales the leftover row to fill the\n * width like every other row (clamped by `maxScale`), `'start'`\n * keeps the target height aligned to the reading start, `'hide'`\n * drops the leftover items (their boxes come back zero-sized).\n */\n lastRow?: 'justify' | 'start' | 'hide';\n /**\n * Row-height clamp as a multiple of `targetRowHeight` — a sparse\n * row (single portrait, justified leftovers) never renders taller\n * than `maxScale * targetRowHeight`. Clamped rows align to the\n * reading start instead of filling the width.\n */\n maxScale?: number;\n}\n\nexport interface JustifiedBox {\n top: number;\n /**\n * Offset from the reading-start edge (logical): the runtime maps\n * it to `left` in LTR and `right` in RTL, the same convention as\n * the thumbnail strip math.\n */\n start: number;\n width: number;\n height: number;\n}\n\nexport interface JustifiedLayout {\n /**\n * One box per input ratio, in item order — items hidden by\n * `lastRow: 'hide'` come back zero-sized (runtimes hide them).\n */\n boxes: JustifiedBox[];\n /** Total content height including the final row (px). */\n containerHeight: number;\n}\n\nconst DEFAULT_TARGET_ROW_HEIGHT = 180;\nconst DEFAULT_GAP = 8;\nconst DEFAULT_MAX_SCALE = 1.75;\n\n/** Coerce invalid aspect ratios to square so boxes stay 1:1 with items. */\nfunction sanitizeRatios(ratios: readonly number[]): number[] {\n let warned = false;\n return ratios.map((ratio) => {\n if (Number.isFinite(ratio) && ratio > 0) {\n return ratio;\n }\n if (!warned && typeof console !== 'undefined') {\n warned = true;\n console.warn(\n 'lightGallery justified layout: invalid aspect ratio, treating as 1 (square). See https://www.lightgalleryjs.com/docs/justified-layout/',\n );\n }\n return 1;\n });\n}\n\ninterface RowRenderOptions {\n row: number[];\n firstIndex: number;\n top: number;\n height: number;\n containerWidth: number;\n gap: number;\n /** Distribute rounding drift so widths + gaps fill the width exactly. */\n fill: boolean;\n boxes: JustifiedBox[];\n}\n\n/** Emit one row's boxes; returns the rendered (rounded) row height. */\nfunction renderRow(options: RowRenderOptions): number {\n const { row, firstIndex, top, containerWidth, gap, fill, boxes } = options;\n const height = Math.round(options.height);\n let start = 0;\n row.forEach((ratio, offset) => {\n let width = Math.round(ratio * height);\n if (fill && offset === row.length - 1) {\n // The row is sized to fill exactly; per-item rounding drift\n // lands on the last item so widths + gaps always sum to the\n // container width.\n width = containerWidth - start;\n }\n boxes[firstIndex + offset] = { top, start, width, height };\n start += width + gap;\n });\n return height;\n}\n\nexport function getJustifiedLayout(\n options: JustifiedLayoutOptions,\n): JustifiedLayout {\n const {\n containerWidth,\n targetRowHeight = DEFAULT_TARGET_ROW_HEIGHT,\n gap = DEFAULT_GAP,\n lastRow = 'start',\n maxScale = DEFAULT_MAX_SCALE,\n } = options;\n const ratios = sanitizeRatios(options.ratios);\n const boxes: JustifiedBox[] = new Array(ratios.length);\n const maxHeight = targetRowHeight * maxScale;\n\n // Height at which `row` fills the container width exactly.\n const fillHeight = (row: readonly number[]): number => {\n const available = containerWidth - gap * (row.length - 1);\n const ratioSum = row.reduce((sum, ratio) => sum + ratio, 0);\n return available / ratioSum;\n };\n\n let top = 0;\n let row: number[] = [];\n let firstIndex = 0;\n\n const closeRow = (height: number, fill: boolean): void => {\n const rendered = renderRow({\n row,\n firstIndex,\n top,\n height: Math.min(height, maxHeight),\n containerWidth,\n gap,\n // A clamped row no longer fills the width — never stretch it.\n fill: fill && height <= maxHeight,\n boxes,\n });\n top += rendered + gap;\n firstIndex += row.length;\n row = [];\n };\n\n ratios.forEach((ratio) => {\n row.push(ratio);\n const height = fillHeight(row);\n if (height > targetRowHeight) {\n return; // Row still too sparse to reach the target — keep filling.\n }\n // The row crossed the target. Render it closer to the target:\n // with this item (shorter row) or without it (taller row).\n const heightWithout =\n row.length > 1 ? fillHeight(row.slice(0, -1)) : null;\n if (\n heightWithout !== null &&\n heightWithout - targetRowHeight < targetRowHeight - height\n ) {\n const carried = row.pop()!;\n closeRow(heightWithout, true);\n row = [carried];\n if (fillHeight(row) <= targetRowHeight) {\n // The carried item alone already fills the width (wider\n // than the container at target height) — close it too.\n closeRow(fillHeight(row), true);\n }\n } else {\n closeRow(height, true);\n }\n });\n\n // Leftover items that never reached the target width.\n if (row.length > 0) {\n if (lastRow === 'hide') {\n row.forEach((_, offset) => {\n boxes[firstIndex + offset] = {\n top: 0,\n start: 0,\n width: 0,\n height: 0,\n };\n });\n } else if (lastRow === 'justify') {\n closeRow(fillHeight(row), true);\n } else {\n closeRow(targetRowHeight, false);\n }\n }\n\n return {\n boxes,\n containerHeight:\n firstIndex > 0 || row.length > 0 ? Math.max(top - gap, 0) : 0,\n };\n}\n\n/**\n * Reveal policy for laid-out thumbnails: 'image' shows each one as it\n * loads, 'row' shows whole rows top to bottom, a row only once every\n * thumbnail in it (and every row above it) has loaded.\n */\nexport type JustifiedReveal = 'row' | 'image';\n\n/**\n * Group laid-out boxes into rows by their top offset, in layout order.\n * Hidden boxes (0×0, the 'hide' last-row policy) belong to no row.\n * Returns item indexes per row.\n */\nexport function getJustifiedRows(boxes: JustifiedBox[]): number[][] {\n const rows: number[][] = [];\n let rowTop = -1;\n boxes.forEach((box, index) => {\n if (box.width === 0 && box.height === 0) {\n return;\n }\n if (!rows.length || box.top !== rowTop) {\n rows.push([]);\n rowTop = box.top;\n }\n rows[rows.length - 1]!.push(index);\n });\n return rows;\n}\n\n/**\n * Which laid-out items may show now, given which have loaded: per\n * image, or per row in reading order (see JustifiedReveal). The result\n * is cumulative — callers reveal every returned item that is not\n * already showing.\n */\nexport function getRevealableItems<T>(\n rows: T[][],\n isLoaded: (item: T) => boolean,\n reveal: JustifiedReveal,\n): T[] {\n if (reveal === 'image') {\n return ([] as T[]).concat(...rows).filter(isLoaded);\n }\n const revealable: T[] = [];\n for (const row of rows) {\n if (!row.every(isLoaded)) {\n break;\n }\n revealable.push(...row);\n }\n return revealable;\n}\n","import { LightGallery } from './lightgallery';\nimport { VideoSource } from './plugins/video/types';\n\n/**\n * List of lightGallery events\n * All events should be documented here\n * Below interfaces are used to build the website documentations\n * */\nexport const lGEvents: {\n [key: string]: string;\n} = {\n afterAppendSlide: 'lgAfterAppendSlide',\n init: 'lgInit',\n hasVideo: 'lgHasVideo',\n containerResize: 'lgContainerResize',\n updateSlides: 'lgUpdateSlides',\n afterAppendSubHtml: 'lgAfterAppendSubHtml',\n beforeOpen: 'lgBeforeOpen',\n afterOpen: 'lgAfterOpen',\n slideItemLoad: 'lgSlideItemLoad',\n beforeSlide: 'lgBeforeSlide',\n afterSlide: 'lgAfterSlide',\n posterClick: 'lgPosterClick',\n dragStart: 'lgDragStart',\n dragMove: 'lgDragMove',\n dragEnd: 'lgDragEnd',\n beforeNextSlide: 'lgBeforeNextSlide',\n beforePrevSlide: 'lgBeforePrevSlide',\n beforeClose: 'lgBeforeClose',\n afterClose: 'lgAfterClose',\n rotateLeft: 'lgRotateLeft',\n rotateRight: 'lgRotateRight',\n flipHorizontal: 'lgFlipHorizontal',\n flipVertical: 'lgFlipVertical',\n autoplay: 'lgAutoplay',\n autoplayStart: 'lgAutoplayStart',\n autoplayStop: 'lgAutoplayStop',\n};\n\n// Follow the below format for the event documentation\n// @method is the method name when event is used with Angular/React components\n\n/**\n * Fired only once when lightGallery is initialized\n * @name lgInit\n * @method onInit\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action on lightGallery initialization.\n * // Init event returns the plugin instance that can be used to call any lightGalley public method\n * let pluginInstance = null;\n * lg.addEventListener('lgInit', (event) => {\n * pluginInstance = event.detail.instance;\n * });\n * lightGallery(lg);\n * @see <a href=\"/docs/methods/\">Methods</a>\n */\nexport interface InitDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired when the slide content has been inserted into it's slide container.\n * @name lgAfterAppendSlide\n * @method onAfterAppendSlide\n */\nexport interface AfterAppendSlideEventDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired immediately before opening the gallery\n * @name lgBeforeOpen\n * @method onBeforeOpen\n */\nexport interface BeforeOpenDetail {}\n\n/**\n * Fired immediately after opening the gallery\n * @name lgAfterOpen\n * @method onAfterOpen\n */\nexport interface AfterOpenDetail {}\n\n/**\n * Fired once the media inside the slide has been completely loaded .\n * @name lgSlideItemLoad\n * @method onSlideItemLoad\n */\nexport interface SlideItemLoadDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * For the first slide, lightGallery adds some delay for displaying the loaded slide item.\n * This delay is required for the transition effect when the slide item is displayed\n * Respect the delay when you use this event\n */\n delay: number;\n\n // Will be true for the first slide\n isFirstSlide: boolean;\n}\n\n/**\n * Fired immediately before each slide transition.\n * @name lgBeforeSlide\n * @method onBeforeSlide\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action before each slide transition\n * lg.addEventListener('lgBeforeSlide', (event) => {\n * const { index, prevIndex } = event.detail;\n * alert(index, prevIndex);\n * });\n * lightGallery(lg);\n */\nexport interface BeforeSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired immediately after each slide transition.\n * @name lgAfterSlide\n * @method onAfterSlide\n */\nexport interface AfterSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired when the video poster is clicked.\n * @name lgPosterClick\n * @method onPosterClick\n */\nexport interface PosterClickDetail {}\n\n/**\n * Fired when the drag event to move to different slide starts.\n * @name lgDragStart\n * @method onDragStart\n */\nexport interface DragStartDetail {}\n\n/**\n * Fired periodically during the drag operation.\n * @name lgDragMove\n * @method onDragMove\n */\nexport interface DragMoveDetail {}\n\n/**\n * Fired when the user has finished the drag operation\n * @name lgDragEnd\n * @method onDragEnd\n */\nexport interface DragEndDetail {}\n\n/**\n * Fired immediately before the start of the close process.\n * @name lgBeforeClose\n * @method onBeforeClose\n */\nexport interface BeforeCloseDetail {}\n\n/**\n * Fired immediately once lightGallery is closed.\n * @name lgAfterClose\n * @method onAfterClose\n */\nexport interface AfterCloseDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired immediately before each \"next\" slide transition\n * @name lgBeforeNextSlide\n * @method onBeforeNextSlide\n */\nexport interface BeforeNextSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired immediately before each \"prev\" slide transition\n * @name lgBeforePrevSlide\n * @method onBeforePrevSlide\n */\nexport interface BeforePrevSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired when the sub-html content (ex : title/ description) has been appended into the slide.\n * @name lgAfterAppendSubHtml\n * @method onAfterAppendSubHtml\n */\nexport interface AfterAppendSubHtmlDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the lightGallery container has been resized.\n * @name lgContainerResize\n * @method onContainerResize\n */\nexport interface ContainerResizeDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when lightGallery detects video slide\n * @name lgHasVideo\n * @method onHasVideo\n */\nexport interface HasVideoDetail {\n /**\n * Index of the slide,\n */\n index: number;\n /**\n * Video source\n */\n src: string;\n /**\n * HTML5 video source if available\n * <p>\n HTML5 video source = source: {\n src: string;\n type: string;\n }[];\n attributes: HTMLVideoElement;\n * </p>\n */\n html5Video: VideoSource;\n /**\n * True if video has poster\n */\n hasPoster: boolean;\n}\n\n/**\n * Fired when the image is rotated in anticlockwise direction\n * @name lgRotateLeft\n * @method onRotateLeft\n */\nexport interface RotateLeftDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is rotated in clockwise direction\n * @name lgRotateRight\n * @method onRotateRight\n */\nexport interface RotateRightDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped horizontally\n * @name lgFlipHorizontal\n * @method onFlipHorizontal\n */\nexport interface FlipHorizontalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped vertically\n * @name lgFlipVertical\n * @method onFlipVertical\n */\nexport interface FlipVerticalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n","export interface JustifiedSettings {\n /**\n * Enable the justified layout for the gallery's trigger thumbnails:\n * rows of equal height and varying widths that fill the container\n * edge to edge. Inline galleries only, dynamic mode has no trigger\n * grid to lay out. Each box shows as a placeholder and its thumbnail\n * fades in once loaded; put `class=\"lg-justified\"` on the container\n * markup so nothing shows unorganized before the script runs.\n * See <a href=\"/docs/justified-layout/\">Justified layout</a>.\n */\n justified: boolean;\n /**\n * Row height (px) the layout aims for; actual rows land as close to\n * it as the aspect ratios allow.\n */\n justifiedRowHeight: number;\n /**\n * Gap between thumbnails and between rows (px).\n */\n justifiedGap: number;\n /**\n * Last-row policy: 'justify' scales the leftover row to fill the\n * width like every other row, 'start' keeps the row height aligned\n * to the reading start, 'hide' hides the leftover thumbnails.\n */\n justifiedLastRow: 'justify' | 'start' | 'hide';\n /**\n * Row-height clamp as a multiple of justifiedRowHeight, a sparse\n * row never renders taller than this.\n */\n justifiedMaxScale: number;\n /**\n * How thumbnails appear as they load: 'row' reveals whole rows top\n * to bottom, each once every thumbnail in it has loaded; 'image'\n * reveals each thumbnail on its own as soon as it has loaded.\n * Until a thumbnail is revealed its box shows as a placeholder.\n * See <a href=\"/docs/justified-layout/\">Justified layout</a>.\n * @version V3.0.0\n */\n justifiedReveal: 'row' | 'image';\n}\n\nexport const justifiedSettings: JustifiedSettings = {\n justified: true,\n justifiedRowHeight: 180,\n justifiedGap: 8,\n justifiedLastRow: 'start',\n justifiedMaxScale: 1.75,\n justifiedReveal: 'row',\n};\n","import {\n getJustifiedLayout,\n getJustifiedRows,\n getRevealableItems,\n parseImageSize,\n} from '@lightgallery/headless';\nimport { lGEvents } from '../../lg-events';\nimport { LgQuery } from '../../lgQuery';\nimport { LightGallery } from '../../lightgallery';\nimport { JustifiedSettings, justifiedSettings } from './lg-justified-settings';\n\n/**\n * lightGallery justified layout: lays the gallery's trigger thumbnails\n * out in rows of equal height and varying widths that fill the\n * container edge to edge. The row math is shared headless code; this\n * plugin measures the container, sources the aspect ratios and writes\n * the geometry.\n *\n * Aspect-ratio sources, in order: the trigger's `data-lg-size`\n * attribute, the thumbnail's `width`/`height` attributes, and finally\n * the loaded image's natural size (one relayout when the last unknown\n * resolves).\n *\n * Triggers stay invisible (stylesheet) until they are positioned; each\n * box then shows as a placeholder and the thumbnails fade in as they\n * load, row by row in reading order or one by one (`justifiedReveal`),\n * so the grid is never seen unorganized. Ship `class=\"lg-justified\"`\n * on the container markup to cover the time before the script runs.\n */\nexport default class Justified {\n core: LightGallery;\n settings: JustifiedSettings;\n private $LG!: LgQuery;\n private triggers: HTMLElement[] = [];\n private ratios: (number | null)[] = [];\n private resizeObserver?: ResizeObserver;\n private layoutWidth = 0;\n private pendingLoads: (() => void)[] = [];\n private rows: HTMLElement[][] = [];\n private loaded = new Set<HTMLElement>();\n private loadWatchers = new Map<HTMLElement, () => void>();\n private originalContainerStyle = '';\n private originalTriggerStyles = new Map<HTMLElement, string>();\n\n constructor(instance: LightGallery, $LG: LgQuery) {\n this.core = instance;\n this.$LG = $LG;\n this.settings = { ...justifiedSettings, ...this.core.settings };\n return this;\n }\n\n public init(): void {\n // Dynamic galleries have no inline trigger grid to lay out.\n if (!this.settings.justified || this.core.settings.dynamic) {\n return;\n }\n this.collectTriggers();\n if (!this.triggers.length) {\n return;\n }\n this.originalContainerStyle = this.core.el.getAttribute('style') || '';\n // The reveal marker gates the stylesheet's placeholder + fade\n // rules: they hold a thumbnail invisible until this plugin\n // reveals it, so they must never apply to a grid positioned by\n // other code.\n this.core.el.classList.add('lg-justified', 'lg-justified-reveal');\n this.resolveRatios();\n this.layout();\n\n // refresh()/updateSlides() re-collect the core's items before\n // firing this event, the grid follows the new trigger set.\n this.core.LGel.on(`${lGEvents.updateSlides}.justified`, () => {\n this.pendingLoads.forEach((cancel) => cancel());\n this.pendingLoads = [];\n this.cancelLoadWatchers();\n this.collectTriggers();\n this.resolveRatios();\n this.layout();\n });\n\n // Row heights derive from the width alone, so one observer on\n // the container covers every reflow source (viewport, sidebar,\n // font swap...).\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => {\n if (this.core.el.clientWidth !== this.layoutWidth) {\n this.layout();\n }\n });\n this.resizeObserver.observe(this.core.el);\n }\n }\n\n /** Adopt the core's current trigger list into the layout. */\n private collectTriggers(): void {\n this.triggers = Array.prototype.slice.call(this.core.items);\n this.triggers.forEach((trigger) => {\n if (!this.originalTriggerStyles.has(trigger)) {\n this.originalTriggerStyles.set(\n trigger,\n trigger.getAttribute('style') || '',\n );\n }\n trigger.classList.add('lg-justified-item');\n });\n }\n\n /** Best-known aspect ratio per trigger; unknowns resolve on load. */\n private resolveRatios(): void {\n this.ratios = this.triggers.map((trigger, index) => {\n const size = parseImageSize(\n trigger.getAttribute('data-lg-size') || undefined,\n window.innerWidth,\n );\n if (size) {\n return size.width / size.height;\n }\n const img = trigger.querySelector('img');\n if (!img) {\n return 1;\n }\n const width = parseInt(img.getAttribute('width') || '', 10);\n const height = parseInt(img.getAttribute('height') || '', 10);\n if (width > 0 && height > 0) {\n return width / height;\n }\n if (img.complete && img.naturalWidth > 0) {\n return img.naturalWidth / img.naturalHeight;\n }\n this.watchImageLoad(img, index);\n return null;\n });\n }\n\n /** Relayout once when the last unknown thumbnail resolves. */\n private watchImageLoad(img: HTMLImageElement, index: number): void {\n const cancel = (): void => {\n img.removeEventListener('load', onDone);\n img.removeEventListener('error', onDone);\n };\n const onDone = (): void => {\n cancel();\n this.pendingLoads = this.pendingLoads.filter((c) => c !== cancel);\n this.ratios[index] =\n img.naturalWidth > 0 ? img.naturalWidth / img.naturalHeight : 1;\n if (this.ratios.every((ratio) => ratio !== null)) {\n this.layout();\n }\n };\n img.addEventListener('load', onDone);\n img.addEventListener('error', onDone);\n this.pendingLoads.push(cancel);\n }\n\n private layout(): void {\n const containerWidth = this.core.el.clientWidth;\n if (!containerWidth) {\n return;\n }\n this.layoutWidth = containerWidth;\n const { boxes, containerHeight } = getJustifiedLayout({\n // Unknown ratios render square until their image resolves.\n ratios: this.ratios.map((ratio) => ratio ?? 1),\n containerWidth,\n targetRowHeight: this.settings.justifiedRowHeight,\n gap: this.settings.justifiedGap,\n lastRow: this.settings.justifiedLastRow,\n maxScale: this.settings.justifiedMaxScale,\n });\n // The box offsets are logical (from the reading-start edge).\n const startSide =\n this.core.settings.direction === 'rtl' ? 'right' : 'left';\n const endSide = startSide === 'left' ? 'right' : 'left';\n this.core.el.style.height = `${containerHeight}px`;\n this.triggers.forEach((trigger, index) => {\n const box = boxes[index]!;\n const hidden = box.width === 0 && box.height === 0;\n trigger.classList.toggle('lg-justified-item-hidden', hidden);\n if (hidden) {\n return;\n }\n trigger.style.top = `${box.top}px`;\n trigger.style[startSide] = `${box.start}px`;\n trigger.style[endSide] = 'auto';\n trigger.style.width = `${box.width}px`;\n trigger.style.height = `${box.height}px`;\n // With the rendered width known exactly, responsive\n // thumbnails get a precise sizes hint.\n const img = trigger.querySelector('img');\n if (img && img.hasAttribute('srcset')) {\n img.setAttribute('sizes', `${box.width}px`);\n }\n this.watchLoad(trigger, img);\n });\n this.rows = getJustifiedRows(boxes).map((row) =>\n row.map((index) => this.triggers[index]!),\n );\n this.reveal();\n }\n\n /** Track when the trigger's thumbnail has settled (loaded or failed). */\n private watchLoad(\n trigger: HTMLElement,\n img: HTMLImageElement | null,\n ): void {\n if (this.loaded.has(trigger) || this.loadWatchers.has(trigger)) {\n return;\n }\n if (!img || img.complete) {\n this.loaded.add(trigger);\n return;\n }\n const onDone = (): void => {\n cancel();\n this.loaded.add(trigger);\n this.reveal();\n };\n const cancel = (): void => {\n img.removeEventListener('load', onDone);\n img.removeEventListener('error', onDone);\n this.loadWatchers.delete(trigger);\n };\n img.addEventListener('load', onDone);\n img.addEventListener('error', onDone);\n this.loadWatchers.set(trigger, cancel);\n }\n\n /**\n * Fade in what may show now (see `justifiedReveal`). Never re-hides:\n * a relayout regroups the rows, already visible triggers stay.\n */\n private reveal(): void {\n getRevealableItems(\n this.rows,\n (trigger) => this.loaded.has(trigger),\n this.settings.justifiedReveal,\n ).forEach((trigger) => {\n trigger.classList.add('lg-justified-item-visible');\n });\n }\n\n private cancelLoadWatchers(): void {\n Array.from(this.loadWatchers.values()).forEach((cancel) => cancel());\n }\n\n public closeGallery(): void {\n // Nothing to do, the layout lives outside the lightbox.\n }\n\n public destroy(): void {\n this.resizeObserver?.disconnect();\n this.pendingLoads.forEach((cancel) => cancel());\n this.pendingLoads = [];\n this.cancelLoadWatchers();\n this.loaded.clear();\n this.rows = [];\n if (!this.triggers.length) {\n return;\n }\n this.core.LGel.off('.justified');\n this.core.el.classList.remove('lg-justified', 'lg-justified-reveal');\n if (this.originalContainerStyle) {\n this.core.el.setAttribute('style', this.originalContainerStyle);\n } else {\n this.core.el.removeAttribute('style');\n }\n this.triggers.forEach((trigger) => {\n trigger.classList.remove(\n 'lg-justified-item',\n 'lg-justified-item-hidden',\n 'lg-justified-item-visible',\n );\n const original = this.originalTriggerStyles.get(trigger);\n if (original) {\n trigger.setAttribute('style', original);\n } else {\n trigger.removeAttribute('style');\n }\n });\n }\n}\n"],"names":["row"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lgJustified=e()}(this,function(){"use strict";const t=180,e=8,i=1.75;function s(s){const{containerWidth:r,targetRowHeight:o=t,gap:a=e,lastRow:n="start",maxScale:h=i}=s,l=function(t){let e=!1;return t.map(t=>Number.isFinite(t)&&t>0?t:(e||"undefined"==typeof console||(e=!0,console.warn("lightGallery justified layout: invalid aspect ratio, treating as 1 (square). See https://www.lightgalleryjs.com/docs/justified-layout/")),1))}(s.ratios),d=new Array(l.length),c=o*h,g=t=>(r-a*(t.length-1))/t.reduce((t,e)=>t+e,0);let u=0,f=[],p=0;const y=(t,e)=>{const i=function(t){const{row:e,firstIndex:i,top:s,containerWidth:r,gap:o,fill:a,boxes:n}=t,h=Math.round(t.height);let l=0;return e.forEach((t,d)=>{let c=Math.round(t*h);a&&d===e.length-1&&(c=r-l),n[i+d]={top:s,start:l,width:c,height:h},l+=c+o}),h}({row:f,firstIndex:p,top:u,height:Math.min(t,c),containerWidth:r,gap:a,fill:e&&t<=c,boxes:d});u+=i+a,p+=f.length,f=[]};return l.forEach(t=>{f.push(t);const e=g(f);if(e>o)return;const i=f.length>1?g(f.slice(0,-1)):null;if(null!==i&&i-o<o-e){const t=f.pop();y(i,!0),f=[t],g(f)<=o&&y(g(f),!0)}else y(e,!0)}),f.length>0&&("hide"===n?f.forEach((t,e)=>{d[p+e]={top:0,start:0,width:0,height:0}}):"justify"===n?y(g(f),!0):y(o,!1)),{boxes:d,containerHeight:p>0||f.length>0?Math.max(u-a,0):0}}const r="lgUpdateSlides",o={justified:!0,justifiedRowHeight:180,justifiedGap:8,justifiedLastRow:"start",justifiedMaxScale:1.75,justifiedReveal:"row"};var a=Object.defineProperty,n=Object.getOwnPropertySymbols,h=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,d=(t,e,i)=>e in t?a(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,c=(t,e)=>{for(var i in e||(e={}))h.call(e,i)&&d(t,i,e[i]);if(n)for(var i of n(e))l.call(e,i)&&d(t,i,e[i]);return t};return class{constructor(t,e){return this.triggers=[],this.ratios=[],this.layoutWidth=0,this.pendingLoads=[],this.rows=[],this.loaded=new Set,this.loadWatchers=new Map,this.originalContainerStyle="",this.originalTriggerStyles=new Map,this.core=t,this.$LG=e,this.settings=c(c({},o),this.core.settings),this}init(){this.settings.justified&&!this.core.settings.dynamic&&(this.collectTriggers(),this.triggers.length&&(this.originalContainerStyle=this.core.el.getAttribute("style")||"",this.core.el.classList.add("lg-justified","lg-justified-reveal"),this.resolveRatios(),this.layout(),this.core.LGel.on(`${r}.justified`,()=>{this.pendingLoads.forEach(t=>t()),this.pendingLoads=[],this.cancelLoadWatchers(),this.collectTriggers(),this.resolveRatios(),this.layout()}),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>{this.core.el.clientWidth!==this.layoutWidth&&this.layout()}),this.resizeObserver.observe(this.core.el))))}collectTriggers(){this.triggers=Array.prototype.slice.call(this.core.items),this.triggers.forEach(t=>{this.originalTriggerStyles.has(t)||this.originalTriggerStyles.set(t,t.getAttribute("style")||""),t.classList.add("lg-justified-item")})}resolveRatios(){this.ratios=this.triggers.map((t,e)=>{const i=function(t,e){if(!t)return;let i=t;const s=t.split(",");if(s[1])for(let n=0;n<s.length;n++){const t=s[n].trim();if(parseInt(t.split("-")[2],10)>e){i=t;break}n===s.length-1&&(i=t)}const r=i.trim().split("-"),o=parseInt(r[0],10),a=parseInt(r[1],10);return Number.isFinite(o)&&Number.isFinite(a)?{width:o,height:a}:void 0}(t.getAttribute("data-lg-size")||void 0,window.innerWidth);if(i)return i.width/i.height;const s=t.querySelector("img");if(!s)return 1;const r=parseInt(s.getAttribute("width")||"",10),o=parseInt(s.getAttribute("height")||"",10);return r>0&&o>0?r/o:s.complete&&s.naturalWidth>0?s.naturalWidth/s.naturalHeight:(this.watchImageLoad(s,e),null)})}watchImageLoad(t,e){const i=()=>{t.removeEventListener("load",s),t.removeEventListener("error",s)},s=()=>{i(),this.pendingLoads=this.pendingLoads.filter(t=>t!==i),this.ratios[e]=t.naturalWidth>0?t.naturalWidth/t.naturalHeight:1,this.ratios.every(t=>null!==t)&&this.layout()};t.addEventListener("load",s),t.addEventListener("error",s),this.pendingLoads.push(i)}layout(){const t=this.core.el.clientWidth;if(!t)return;this.layoutWidth=t;const{boxes:e,containerHeight:i}=s({ratios:this.ratios.map(t=>null!=t?t:1),containerWidth:t,targetRowHeight:this.settings.justifiedRowHeight,gap:this.settings.justifiedGap,lastRow:this.settings.justifiedLastRow,maxScale:this.settings.justifiedMaxScale}),r="rtl"===this.core.settings.direction?"right":"left",o="left"===r?"right":"left";this.core.el.style.height=`${i}px`,this.triggers.forEach((t,i)=>{const s=e[i],a=0===s.width&&0===s.height;if(t.classList.toggle("lg-justified-item-hidden",a),a)return;t.style.top=`${s.top}px`,t.style[r]=`${s.start}px`,t.style[o]="auto",t.style.width=`${s.width}px`,t.style.height=`${s.height}px`;const n=t.querySelector("img");n&&n.hasAttribute("srcset")&&n.setAttribute("sizes",`${s.width}px`),this.watchLoad(t,n)}),this.rows=function(t){const e=[];let i=-1;return t.forEach((t,s)=>{0===t.width&&0===t.height||(e.length&&t.top===i||(e.push([]),i=t.top),e[e.length-1].push(s))}),e}(e).map(t=>t.map(t=>this.triggers[t])),this.reveal()}watchLoad(t,e){if(this.loaded.has(t)||this.loadWatchers.has(t))return;if(!e||e.complete)return void this.loaded.add(t);const i=()=>{s(),this.loaded.add(t),this.reveal()},s=()=>{e.removeEventListener("load",i),e.removeEventListener("error",i),this.loadWatchers.delete(t)};e.addEventListener("load",i),e.addEventListener("error",i),this.loadWatchers.set(t,s)}reveal(){(function(t,e,i){if("image"===i)return[].concat(...t).filter(e);const s=[];for(const r of t){if(!r.every(e))break;s.push(...r)}return s})(this.rows,t=>this.loaded.has(t),this.settings.justifiedReveal).forEach(t=>{t.classList.add("lg-justified-item-visible")})}cancelLoadWatchers(){Array.from(this.loadWatchers.values()).forEach(t=>t())}closeGallery(){}destroy(){var t;null==(t=this.resizeObserver)||t.disconnect(),this.pendingLoads.forEach(t=>t()),this.pendingLoads=[],this.cancelLoadWatchers(),this.loaded.clear(),this.rows=[],this.triggers.length&&(this.core.LGel.off(".justified"),this.core.el.classList.remove("lg-justified","lg-justified-reveal"),this.originalContainerStyle?this.core.el.setAttribute("style",this.originalContainerStyle):this.core.el.removeAttribute("style"),this.triggers.forEach(t=>{t.classList.remove("lg-justified-item","lg-justified-item-hidden","lg-justified-item-visible");const e=this.originalTriggerStyles.get(t);e?t.setAttribute("style",e):t.removeAttribute("style")}))}}});
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.lgJustified = factory());
|
|
3
|
+
})(this, function() {
|
|
4
|
+
"use strict";/*!
|
|
5
|
+
* lightgallery | 3.0.0-beta.2 | October 1st 2026
|
|
6
|
+
* http://www.lightgalleryjs.com/
|
|
7
|
+
* Copyright (c) 2020 Sachin Neravath;
|
|
8
|
+
* @license GPLv3
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function parseImageSize(lgSize, viewportWidth) {
|
|
12
|
+
if (!lgSize) {
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
15
|
+
let size = lgSize;
|
|
16
|
+
const responsiveSizes = lgSize.split(",");
|
|
17
|
+
if (responsiveSizes[1]) {
|
|
18
|
+
for (let i = 0; i < responsiveSizes.length; i++) {
|
|
19
|
+
const candidate = responsiveSizes[i].trim();
|
|
20
|
+
const responsiveWidth = parseInt(candidate.split("-")[2], 10);
|
|
21
|
+
if (responsiveWidth > viewportWidth) {
|
|
22
|
+
size = candidate;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
if (i === responsiveSizes.length - 1) {
|
|
26
|
+
size = candidate;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const parts = size.trim().split("-");
|
|
31
|
+
const width = parseInt(parts[0], 10);
|
|
32
|
+
const height = parseInt(parts[1], 10);
|
|
33
|
+
if (!Number.isFinite(width) || !Number.isFinite(height)) {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
return { width, height };
|
|
37
|
+
}
|
|
38
|
+
const DEFAULT_TARGET_ROW_HEIGHT = 180;
|
|
39
|
+
const DEFAULT_GAP = 8;
|
|
40
|
+
const DEFAULT_MAX_SCALE = 1.75;
|
|
41
|
+
function sanitizeRatios(ratios) {
|
|
42
|
+
let warned = false;
|
|
43
|
+
return ratios.map((ratio) => {
|
|
44
|
+
if (Number.isFinite(ratio) && ratio > 0) {
|
|
45
|
+
return ratio;
|
|
46
|
+
}
|
|
47
|
+
if (!warned && typeof console !== "undefined") {
|
|
48
|
+
warned = true;
|
|
49
|
+
console.warn(
|
|
50
|
+
"lightGallery justified layout: invalid aspect ratio, treating as 1 (square). See https://www.lightgalleryjs.com/docs/justified-layout/"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return 1;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function renderRow(options) {
|
|
57
|
+
const { row, firstIndex, top, containerWidth, gap, fill, boxes } = options;
|
|
58
|
+
const height = Math.round(options.height);
|
|
59
|
+
let start = 0;
|
|
60
|
+
row.forEach((ratio, offset) => {
|
|
61
|
+
let width = Math.round(ratio * height);
|
|
62
|
+
if (fill && offset === row.length - 1) {
|
|
63
|
+
width = containerWidth - start;
|
|
64
|
+
}
|
|
65
|
+
boxes[firstIndex + offset] = { top, start, width, height };
|
|
66
|
+
start += width + gap;
|
|
67
|
+
});
|
|
68
|
+
return height;
|
|
69
|
+
}
|
|
70
|
+
function getJustifiedLayout(options) {
|
|
71
|
+
const {
|
|
72
|
+
containerWidth,
|
|
73
|
+
targetRowHeight = DEFAULT_TARGET_ROW_HEIGHT,
|
|
74
|
+
gap = DEFAULT_GAP,
|
|
75
|
+
lastRow = "start",
|
|
76
|
+
maxScale = DEFAULT_MAX_SCALE
|
|
77
|
+
} = options;
|
|
78
|
+
const ratios = sanitizeRatios(options.ratios);
|
|
79
|
+
const boxes = new Array(ratios.length);
|
|
80
|
+
const maxHeight = targetRowHeight * maxScale;
|
|
81
|
+
const fillHeight = (row2) => {
|
|
82
|
+
const available = containerWidth - gap * (row2.length - 1);
|
|
83
|
+
const ratioSum = row2.reduce((sum, ratio) => sum + ratio, 0);
|
|
84
|
+
return available / ratioSum;
|
|
85
|
+
};
|
|
86
|
+
let top = 0;
|
|
87
|
+
let row = [];
|
|
88
|
+
let firstIndex = 0;
|
|
89
|
+
const closeRow = (height, fill) => {
|
|
90
|
+
const rendered = renderRow({
|
|
91
|
+
row,
|
|
92
|
+
firstIndex,
|
|
93
|
+
top,
|
|
94
|
+
height: Math.min(height, maxHeight),
|
|
95
|
+
containerWidth,
|
|
96
|
+
gap,
|
|
97
|
+
// A clamped row no longer fills the width — never stretch it.
|
|
98
|
+
fill: fill && height <= maxHeight,
|
|
99
|
+
boxes
|
|
100
|
+
});
|
|
101
|
+
top += rendered + gap;
|
|
102
|
+
firstIndex += row.length;
|
|
103
|
+
row = [];
|
|
104
|
+
};
|
|
105
|
+
ratios.forEach((ratio) => {
|
|
106
|
+
row.push(ratio);
|
|
107
|
+
const height = fillHeight(row);
|
|
108
|
+
if (height > targetRowHeight) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const heightWithout = row.length > 1 ? fillHeight(row.slice(0, -1)) : null;
|
|
112
|
+
if (heightWithout !== null && heightWithout - targetRowHeight < targetRowHeight - height) {
|
|
113
|
+
const carried = row.pop();
|
|
114
|
+
closeRow(heightWithout, true);
|
|
115
|
+
row = [carried];
|
|
116
|
+
if (fillHeight(row) <= targetRowHeight) {
|
|
117
|
+
closeRow(fillHeight(row), true);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
closeRow(height, true);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
if (row.length > 0) {
|
|
124
|
+
if (lastRow === "hide") {
|
|
125
|
+
row.forEach((_, offset) => {
|
|
126
|
+
boxes[firstIndex + offset] = {
|
|
127
|
+
top: 0,
|
|
128
|
+
start: 0,
|
|
129
|
+
width: 0,
|
|
130
|
+
height: 0
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
} else if (lastRow === "justify") {
|
|
134
|
+
closeRow(fillHeight(row), true);
|
|
135
|
+
} else {
|
|
136
|
+
closeRow(targetRowHeight, false);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
boxes,
|
|
141
|
+
containerHeight: firstIndex > 0 || row.length > 0 ? Math.max(top - gap, 0) : 0
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function getJustifiedRows(boxes) {
|
|
145
|
+
const rows = [];
|
|
146
|
+
let rowTop = -1;
|
|
147
|
+
boxes.forEach((box, index) => {
|
|
148
|
+
if (box.width === 0 && box.height === 0) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (!rows.length || box.top !== rowTop) {
|
|
152
|
+
rows.push([]);
|
|
153
|
+
rowTop = box.top;
|
|
154
|
+
}
|
|
155
|
+
rows[rows.length - 1].push(index);
|
|
156
|
+
});
|
|
157
|
+
return rows;
|
|
158
|
+
}
|
|
159
|
+
function getRevealableItems(rows, isLoaded, reveal) {
|
|
160
|
+
if (reveal === "image") {
|
|
161
|
+
return [].concat(...rows).filter(isLoaded);
|
|
162
|
+
}
|
|
163
|
+
const revealable = [];
|
|
164
|
+
for (const row of rows) {
|
|
165
|
+
if (!row.every(isLoaded)) {
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
revealable.push(...row);
|
|
169
|
+
}
|
|
170
|
+
return revealable;
|
|
171
|
+
}
|
|
172
|
+
const lGEvents = {
|
|
173
|
+
updateSlides: "lgUpdateSlides"
|
|
174
|
+
};
|
|
175
|
+
const justifiedSettings = {
|
|
176
|
+
justified: true,
|
|
177
|
+
justifiedRowHeight: 180,
|
|
178
|
+
justifiedGap: 8,
|
|
179
|
+
justifiedLastRow: "start",
|
|
180
|
+
justifiedMaxScale: 1.75,
|
|
181
|
+
justifiedReveal: "row"
|
|
182
|
+
};
|
|
183
|
+
var __defProp = Object.defineProperty;
|
|
184
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
185
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
186
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
187
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
188
|
+
var __spreadValues = (a, b) => {
|
|
189
|
+
for (var prop in b || (b = {}))
|
|
190
|
+
if (__hasOwnProp.call(b, prop))
|
|
191
|
+
__defNormalProp(a, prop, b[prop]);
|
|
192
|
+
if (__getOwnPropSymbols)
|
|
193
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
194
|
+
if (__propIsEnum.call(b, prop))
|
|
195
|
+
__defNormalProp(a, prop, b[prop]);
|
|
196
|
+
}
|
|
197
|
+
return a;
|
|
198
|
+
};
|
|
199
|
+
class Justified {
|
|
200
|
+
constructor(instance, $LG) {
|
|
201
|
+
this.triggers = [];
|
|
202
|
+
this.ratios = [];
|
|
203
|
+
this.layoutWidth = 0;
|
|
204
|
+
this.pendingLoads = [];
|
|
205
|
+
this.rows = [];
|
|
206
|
+
this.loaded = /* @__PURE__ */ new Set();
|
|
207
|
+
this.loadWatchers = /* @__PURE__ */ new Map();
|
|
208
|
+
this.originalContainerStyle = "";
|
|
209
|
+
this.originalTriggerStyles = /* @__PURE__ */ new Map();
|
|
210
|
+
this.core = instance;
|
|
211
|
+
this.$LG = $LG;
|
|
212
|
+
this.settings = __spreadValues(__spreadValues({}, justifiedSettings), this.core.settings);
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
init() {
|
|
216
|
+
if (!this.settings.justified || this.core.settings.dynamic) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
this.collectTriggers();
|
|
220
|
+
if (!this.triggers.length) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.originalContainerStyle = this.core.el.getAttribute("style") || "";
|
|
224
|
+
this.core.el.classList.add("lg-justified", "lg-justified-reveal");
|
|
225
|
+
this.resolveRatios();
|
|
226
|
+
this.layout();
|
|
227
|
+
this.core.LGel.on(`${lGEvents.updateSlides}.justified`, () => {
|
|
228
|
+
this.pendingLoads.forEach((cancel) => cancel());
|
|
229
|
+
this.pendingLoads = [];
|
|
230
|
+
this.cancelLoadWatchers();
|
|
231
|
+
this.collectTriggers();
|
|
232
|
+
this.resolveRatios();
|
|
233
|
+
this.layout();
|
|
234
|
+
});
|
|
235
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
236
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
237
|
+
if (this.core.el.clientWidth !== this.layoutWidth) {
|
|
238
|
+
this.layout();
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
this.resizeObserver.observe(this.core.el);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/** Adopt the core's current trigger list into the layout. */
|
|
245
|
+
collectTriggers() {
|
|
246
|
+
this.triggers = Array.prototype.slice.call(this.core.items);
|
|
247
|
+
this.triggers.forEach((trigger) => {
|
|
248
|
+
if (!this.originalTriggerStyles.has(trigger)) {
|
|
249
|
+
this.originalTriggerStyles.set(
|
|
250
|
+
trigger,
|
|
251
|
+
trigger.getAttribute("style") || ""
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
trigger.classList.add("lg-justified-item");
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
/** Best-known aspect ratio per trigger; unknowns resolve on load. */
|
|
258
|
+
resolveRatios() {
|
|
259
|
+
this.ratios = this.triggers.map((trigger, index) => {
|
|
260
|
+
const size = parseImageSize(
|
|
261
|
+
trigger.getAttribute("data-lg-size") || void 0,
|
|
262
|
+
window.innerWidth
|
|
263
|
+
);
|
|
264
|
+
if (size) {
|
|
265
|
+
return size.width / size.height;
|
|
266
|
+
}
|
|
267
|
+
const img = trigger.querySelector("img");
|
|
268
|
+
if (!img) {
|
|
269
|
+
return 1;
|
|
270
|
+
}
|
|
271
|
+
const width = parseInt(img.getAttribute("width") || "", 10);
|
|
272
|
+
const height = parseInt(img.getAttribute("height") || "", 10);
|
|
273
|
+
if (width > 0 && height > 0) {
|
|
274
|
+
return width / height;
|
|
275
|
+
}
|
|
276
|
+
if (img.complete && img.naturalWidth > 0) {
|
|
277
|
+
return img.naturalWidth / img.naturalHeight;
|
|
278
|
+
}
|
|
279
|
+
this.watchImageLoad(img, index);
|
|
280
|
+
return null;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
/** Relayout once when the last unknown thumbnail resolves. */
|
|
284
|
+
watchImageLoad(img, index) {
|
|
285
|
+
const cancel = () => {
|
|
286
|
+
img.removeEventListener("load", onDone);
|
|
287
|
+
img.removeEventListener("error", onDone);
|
|
288
|
+
};
|
|
289
|
+
const onDone = () => {
|
|
290
|
+
cancel();
|
|
291
|
+
this.pendingLoads = this.pendingLoads.filter((c) => c !== cancel);
|
|
292
|
+
this.ratios[index] = img.naturalWidth > 0 ? img.naturalWidth / img.naturalHeight : 1;
|
|
293
|
+
if (this.ratios.every((ratio) => ratio !== null)) {
|
|
294
|
+
this.layout();
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
img.addEventListener("load", onDone);
|
|
298
|
+
img.addEventListener("error", onDone);
|
|
299
|
+
this.pendingLoads.push(cancel);
|
|
300
|
+
}
|
|
301
|
+
layout() {
|
|
302
|
+
const containerWidth = this.core.el.clientWidth;
|
|
303
|
+
if (!containerWidth) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
this.layoutWidth = containerWidth;
|
|
307
|
+
const { boxes, containerHeight } = getJustifiedLayout({
|
|
308
|
+
// Unknown ratios render square until their image resolves.
|
|
309
|
+
ratios: this.ratios.map((ratio) => ratio != null ? ratio : 1),
|
|
310
|
+
containerWidth,
|
|
311
|
+
targetRowHeight: this.settings.justifiedRowHeight,
|
|
312
|
+
gap: this.settings.justifiedGap,
|
|
313
|
+
lastRow: this.settings.justifiedLastRow,
|
|
314
|
+
maxScale: this.settings.justifiedMaxScale
|
|
315
|
+
});
|
|
316
|
+
const startSide = this.core.settings.direction === "rtl" ? "right" : "left";
|
|
317
|
+
const endSide = startSide === "left" ? "right" : "left";
|
|
318
|
+
this.core.el.style.height = `${containerHeight}px`;
|
|
319
|
+
this.triggers.forEach((trigger, index) => {
|
|
320
|
+
const box = boxes[index];
|
|
321
|
+
const hidden = box.width === 0 && box.height === 0;
|
|
322
|
+
trigger.classList.toggle("lg-justified-item-hidden", hidden);
|
|
323
|
+
if (hidden) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
trigger.style.top = `${box.top}px`;
|
|
327
|
+
trigger.style[startSide] = `${box.start}px`;
|
|
328
|
+
trigger.style[endSide] = "auto";
|
|
329
|
+
trigger.style.width = `${box.width}px`;
|
|
330
|
+
trigger.style.height = `${box.height}px`;
|
|
331
|
+
const img = trigger.querySelector("img");
|
|
332
|
+
if (img && img.hasAttribute("srcset")) {
|
|
333
|
+
img.setAttribute("sizes", `${box.width}px`);
|
|
334
|
+
}
|
|
335
|
+
this.watchLoad(trigger, img);
|
|
336
|
+
});
|
|
337
|
+
this.rows = getJustifiedRows(boxes).map(
|
|
338
|
+
(row) => row.map((index) => this.triggers[index])
|
|
339
|
+
);
|
|
340
|
+
this.reveal();
|
|
341
|
+
}
|
|
342
|
+
/** Track when the trigger's thumbnail has settled (loaded or failed). */
|
|
343
|
+
watchLoad(trigger, img) {
|
|
344
|
+
if (this.loaded.has(trigger) || this.loadWatchers.has(trigger)) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
if (!img || img.complete) {
|
|
348
|
+
this.loaded.add(trigger);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const onDone = () => {
|
|
352
|
+
cancel();
|
|
353
|
+
this.loaded.add(trigger);
|
|
354
|
+
this.reveal();
|
|
355
|
+
};
|
|
356
|
+
const cancel = () => {
|
|
357
|
+
img.removeEventListener("load", onDone);
|
|
358
|
+
img.removeEventListener("error", onDone);
|
|
359
|
+
this.loadWatchers.delete(trigger);
|
|
360
|
+
};
|
|
361
|
+
img.addEventListener("load", onDone);
|
|
362
|
+
img.addEventListener("error", onDone);
|
|
363
|
+
this.loadWatchers.set(trigger, cancel);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Fade in what may show now (see `justifiedReveal`). Never re-hides:
|
|
367
|
+
* a relayout regroups the rows, already visible triggers stay.
|
|
368
|
+
*/
|
|
369
|
+
reveal() {
|
|
370
|
+
getRevealableItems(
|
|
371
|
+
this.rows,
|
|
372
|
+
(trigger) => this.loaded.has(trigger),
|
|
373
|
+
this.settings.justifiedReveal
|
|
374
|
+
).forEach((trigger) => {
|
|
375
|
+
trigger.classList.add("lg-justified-item-visible");
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
cancelLoadWatchers() {
|
|
379
|
+
Array.from(this.loadWatchers.values()).forEach((cancel) => cancel());
|
|
380
|
+
}
|
|
381
|
+
closeGallery() {
|
|
382
|
+
}
|
|
383
|
+
destroy() {
|
|
384
|
+
var _a;
|
|
385
|
+
(_a = this.resizeObserver) == null ? void 0 : _a.disconnect();
|
|
386
|
+
this.pendingLoads.forEach((cancel) => cancel());
|
|
387
|
+
this.pendingLoads = [];
|
|
388
|
+
this.cancelLoadWatchers();
|
|
389
|
+
this.loaded.clear();
|
|
390
|
+
this.rows = [];
|
|
391
|
+
if (!this.triggers.length) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
this.core.LGel.off(".justified");
|
|
395
|
+
this.core.el.classList.remove("lg-justified", "lg-justified-reveal");
|
|
396
|
+
if (this.originalContainerStyle) {
|
|
397
|
+
this.core.el.setAttribute("style", this.originalContainerStyle);
|
|
398
|
+
} else {
|
|
399
|
+
this.core.el.removeAttribute("style");
|
|
400
|
+
}
|
|
401
|
+
this.triggers.forEach((trigger) => {
|
|
402
|
+
trigger.classList.remove(
|
|
403
|
+
"lg-justified-item",
|
|
404
|
+
"lg-justified-item-hidden",
|
|
405
|
+
"lg-justified-item-visible"
|
|
406
|
+
);
|
|
407
|
+
const original = this.originalTriggerStyles.get(trigger);
|
|
408
|
+
if (original) {
|
|
409
|
+
trigger.setAttribute("style", original);
|
|
410
|
+
} else {
|
|
411
|
+
trigger.removeAttribute("style");
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return Justified;
|
|
417
|
+
});
|
|
418
|
+
//# sourceMappingURL=lg-justified.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lg-justified.umd.js","sources":["../../../packages/headless/src/origin.ts","../../../packages/headless/src/justified-layout.ts","../../../src/lg-events.ts","../../../src/plugins/justified/lg-justified-settings.ts","../../../src/plugins/justified/lg-justified.ts"],"sourcesContent":["/**\n * Zoom-from-origin math, ported from 2.x `utils.getSize`/`utils.getTransform`\n * (`src/lg-utils.ts`) as pure rect arithmetic. The framework layer measures\n * the DOM (trigger/container bounding rects) and passes plain numbers in.\n *\n * Note: this module is an addition to the ADR 0001 §1 table — it\n * follows the standing rule that pure functions needed by React live in\n * headless. It is distinct from `zoom-math.ts` (zoom plugin).\n */\n\nexport interface ImageSize {\n width: number;\n height: number;\n}\n\nexport interface RectLike {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/**\n * Parse an item's `lgSize` value (`\"1920-1280\"`, or a responsive list like\n * `\"240-160-375, 1600-1067\"` where the third number is the max viewport\n * width the entry applies to).\n */\nexport function parseImageSize(\n lgSize: string | undefined,\n viewportWidth: number,\n): ImageSize | undefined {\n if (!lgSize) {\n return undefined;\n }\n let size = lgSize;\n const responsiveSizes = lgSize.split(',');\n if (responsiveSizes[1]) {\n for (let i = 0; i < responsiveSizes.length; i++) {\n const candidate = responsiveSizes[i]!.trim();\n const responsiveWidth = parseInt(candidate.split('-')[2]!, 10);\n if (responsiveWidth > viewportWidth) {\n size = candidate;\n break;\n }\n if (i === responsiveSizes.length - 1) {\n size = candidate;\n }\n }\n }\n const parts = size.trim().split('-');\n const width = parseInt(parts[0]!, 10);\n const height = parseInt(parts[1]!, 10);\n if (!Number.isFinite(width) || !Number.isFinite(height)) {\n return undefined;\n }\n return { width, height };\n}\n\n/**\n * Fit a natural image size into the available container box, preserving\n * aspect ratio and never scaling up (2.x `utils.getSize` math).\n */\nexport function fitImageSize(\n size: ImageSize,\n containerWidth: number,\n containerHeight: number,\n): ImageSize {\n const maxWidth = Math.min(containerWidth, size.width);\n const maxHeight = Math.min(containerHeight, size.height);\n const ratio = Math.min(maxWidth / size.width, maxHeight / size.height);\n return { width: size.width * ratio, height: size.height * ratio };\n}\n\n/**\n * Whether a measured trigger rect can anchor the zoom-from-origin flight.\n * A trigger that is hidden (`display: none`, the `hidden` attribute),\n * detached or collapsed measures 0×0 at the viewport origin; a flight\n * aimed at it would shrink the slide into the top-left corner.\n */\nexport function isUsableOriginRect(\n rect: RectLike | null | undefined,\n): rect is RectLike {\n return (\n !!rect &&\n Number.isFinite(rect.left) &&\n Number.isFinite(rect.top) &&\n rect.width > 0 &&\n rect.height > 0\n );\n}\n\n/** Scale the closing slide shrinks to when it has no trigger to return to. */\nexport const CENTER_CLOSE_SCALE = 0.5;\n\n/**\n * Close transform for a slide without a usable origin (hidden or\n * collapsed trigger, no `lgSize`): shrink in place about the stage centre,\n * the mirror of the `lg-start-zoom` open. The runtime pairs it with the\n * `lg-close-to-center` class, which fades the slide out over the same\n * duration.\n */\nexport function getCenterCloseTransform(scale = CENTER_CLOSE_SCALE): string {\n return `translate3d(0, 0, 0) scale3d(${scale}, ${scale}, 1)`;\n}\n\nexport interface OriginTransformInput {\n /** Bounding rect of the trigger thumbnail image, viewport coordinates. */\n triggerRect: RectLike;\n\n /** Bounding rect of the gallery outer element, viewport coordinates. */\n containerRect: RectLike;\n\n /** Media container top offset (toolbar height), px. */\n top: number;\n\n /** Media container bottom offset (caption + thumb strip height), px. */\n bottom: number;\n\n /** Final displayed image size (see {@link fitImageSize}). */\n imageSize: ImageSize;\n}\n\n/**\n * CSS transform that places the (centered, final-size) slide image exactly\n * over the trigger thumbnail — the starting point of the zoom-from-origin\n * open animation and the end point of the close animation.\n */\nexport function getOriginTransform(input: OriginTransformInput): string {\n const { triggerRect, containerRect, top, bottom, imageSize } = input;\n\n const availableWidth = containerRect.width;\n const availableHeight = containerRect.height - (top + bottom);\n\n const x =\n (availableWidth - triggerRect.width) / 2 -\n triggerRect.left +\n containerRect.left;\n const y =\n (availableHeight - triggerRect.height) / 2 - triggerRect.top + top;\n\n const scaleX = triggerRect.width / imageSize.width;\n const scaleY = triggerRect.height / imageSize.height;\n\n return `translate3d(${-x}px, ${-y}px, 0) scale3d(${scaleX}, ${scaleY}, 1)`;\n}\n","/**\n * Justified grid layout for the trigger thumbnails: rows of equal\n * height and varying widths that fill the container edge to edge, the\n * row height staying as close as possible to a target. Pure math —\n * runtimes measure the container, hand in aspect ratios, and position\n * elements from the returned boxes.\n */\n\nexport interface JustifiedLayoutOptions {\n /** Aspect ratios (width / height) in item order. */\n ratios: readonly number[];\n /** Content-box width available for rows (px). */\n containerWidth: number;\n /** Row height (px) the algorithm aims for. */\n targetRowHeight?: number;\n /** Gap between items and between rows (px). */\n gap?: number;\n /**\n * Last-row policy: `'justify'` scales the leftover row to fill the\n * width like every other row (clamped by `maxScale`), `'start'`\n * keeps the target height aligned to the reading start, `'hide'`\n * drops the leftover items (their boxes come back zero-sized).\n */\n lastRow?: 'justify' | 'start' | 'hide';\n /**\n * Row-height clamp as a multiple of `targetRowHeight` — a sparse\n * row (single portrait, justified leftovers) never renders taller\n * than `maxScale * targetRowHeight`. Clamped rows align to the\n * reading start instead of filling the width.\n */\n maxScale?: number;\n}\n\nexport interface JustifiedBox {\n top: number;\n /**\n * Offset from the reading-start edge (logical): the runtime maps\n * it to `left` in LTR and `right` in RTL, the same convention as\n * the thumbnail strip math.\n */\n start: number;\n width: number;\n height: number;\n}\n\nexport interface JustifiedLayout {\n /**\n * One box per input ratio, in item order — items hidden by\n * `lastRow: 'hide'` come back zero-sized (runtimes hide them).\n */\n boxes: JustifiedBox[];\n /** Total content height including the final row (px). */\n containerHeight: number;\n}\n\nconst DEFAULT_TARGET_ROW_HEIGHT = 180;\nconst DEFAULT_GAP = 8;\nconst DEFAULT_MAX_SCALE = 1.75;\n\n/** Coerce invalid aspect ratios to square so boxes stay 1:1 with items. */\nfunction sanitizeRatios(ratios: readonly number[]): number[] {\n let warned = false;\n return ratios.map((ratio) => {\n if (Number.isFinite(ratio) && ratio > 0) {\n return ratio;\n }\n if (!warned && typeof console !== 'undefined') {\n warned = true;\n console.warn(\n 'lightGallery justified layout: invalid aspect ratio, treating as 1 (square). See https://www.lightgalleryjs.com/docs/justified-layout/',\n );\n }\n return 1;\n });\n}\n\ninterface RowRenderOptions {\n row: number[];\n firstIndex: number;\n top: number;\n height: number;\n containerWidth: number;\n gap: number;\n /** Distribute rounding drift so widths + gaps fill the width exactly. */\n fill: boolean;\n boxes: JustifiedBox[];\n}\n\n/** Emit one row's boxes; returns the rendered (rounded) row height. */\nfunction renderRow(options: RowRenderOptions): number {\n const { row, firstIndex, top, containerWidth, gap, fill, boxes } = options;\n const height = Math.round(options.height);\n let start = 0;\n row.forEach((ratio, offset) => {\n let width = Math.round(ratio * height);\n if (fill && offset === row.length - 1) {\n // The row is sized to fill exactly; per-item rounding drift\n // lands on the last item so widths + gaps always sum to the\n // container width.\n width = containerWidth - start;\n }\n boxes[firstIndex + offset] = { top, start, width, height };\n start += width + gap;\n });\n return height;\n}\n\nexport function getJustifiedLayout(\n options: JustifiedLayoutOptions,\n): JustifiedLayout {\n const {\n containerWidth,\n targetRowHeight = DEFAULT_TARGET_ROW_HEIGHT,\n gap = DEFAULT_GAP,\n lastRow = 'start',\n maxScale = DEFAULT_MAX_SCALE,\n } = options;\n const ratios = sanitizeRatios(options.ratios);\n const boxes: JustifiedBox[] = new Array(ratios.length);\n const maxHeight = targetRowHeight * maxScale;\n\n // Height at which `row` fills the container width exactly.\n const fillHeight = (row: readonly number[]): number => {\n const available = containerWidth - gap * (row.length - 1);\n const ratioSum = row.reduce((sum, ratio) => sum + ratio, 0);\n return available / ratioSum;\n };\n\n let top = 0;\n let row: number[] = [];\n let firstIndex = 0;\n\n const closeRow = (height: number, fill: boolean): void => {\n const rendered = renderRow({\n row,\n firstIndex,\n top,\n height: Math.min(height, maxHeight),\n containerWidth,\n gap,\n // A clamped row no longer fills the width — never stretch it.\n fill: fill && height <= maxHeight,\n boxes,\n });\n top += rendered + gap;\n firstIndex += row.length;\n row = [];\n };\n\n ratios.forEach((ratio) => {\n row.push(ratio);\n const height = fillHeight(row);\n if (height > targetRowHeight) {\n return; // Row still too sparse to reach the target — keep filling.\n }\n // The row crossed the target. Render it closer to the target:\n // with this item (shorter row) or without it (taller row).\n const heightWithout =\n row.length > 1 ? fillHeight(row.slice(0, -1)) : null;\n if (\n heightWithout !== null &&\n heightWithout - targetRowHeight < targetRowHeight - height\n ) {\n const carried = row.pop()!;\n closeRow(heightWithout, true);\n row = [carried];\n if (fillHeight(row) <= targetRowHeight) {\n // The carried item alone already fills the width (wider\n // than the container at target height) — close it too.\n closeRow(fillHeight(row), true);\n }\n } else {\n closeRow(height, true);\n }\n });\n\n // Leftover items that never reached the target width.\n if (row.length > 0) {\n if (lastRow === 'hide') {\n row.forEach((_, offset) => {\n boxes[firstIndex + offset] = {\n top: 0,\n start: 0,\n width: 0,\n height: 0,\n };\n });\n } else if (lastRow === 'justify') {\n closeRow(fillHeight(row), true);\n } else {\n closeRow(targetRowHeight, false);\n }\n }\n\n return {\n boxes,\n containerHeight:\n firstIndex > 0 || row.length > 0 ? Math.max(top - gap, 0) : 0,\n };\n}\n\n/**\n * Reveal policy for laid-out thumbnails: 'image' shows each one as it\n * loads, 'row' shows whole rows top to bottom, a row only once every\n * thumbnail in it (and every row above it) has loaded.\n */\nexport type JustifiedReveal = 'row' | 'image';\n\n/**\n * Group laid-out boxes into rows by their top offset, in layout order.\n * Hidden boxes (0×0, the 'hide' last-row policy) belong to no row.\n * Returns item indexes per row.\n */\nexport function getJustifiedRows(boxes: JustifiedBox[]): number[][] {\n const rows: number[][] = [];\n let rowTop = -1;\n boxes.forEach((box, index) => {\n if (box.width === 0 && box.height === 0) {\n return;\n }\n if (!rows.length || box.top !== rowTop) {\n rows.push([]);\n rowTop = box.top;\n }\n rows[rows.length - 1]!.push(index);\n });\n return rows;\n}\n\n/**\n * Which laid-out items may show now, given which have loaded: per\n * image, or per row in reading order (see JustifiedReveal). The result\n * is cumulative — callers reveal every returned item that is not\n * already showing.\n */\nexport function getRevealableItems<T>(\n rows: T[][],\n isLoaded: (item: T) => boolean,\n reveal: JustifiedReveal,\n): T[] {\n if (reveal === 'image') {\n return ([] as T[]).concat(...rows).filter(isLoaded);\n }\n const revealable: T[] = [];\n for (const row of rows) {\n if (!row.every(isLoaded)) {\n break;\n }\n revealable.push(...row);\n }\n return revealable;\n}\n","import { LightGallery } from './lightgallery';\nimport { VideoSource } from './plugins/video/types';\n\n/**\n * List of lightGallery events\n * All events should be documented here\n * Below interfaces are used to build the website documentations\n * */\nexport const lGEvents: {\n [key: string]: string;\n} = {\n afterAppendSlide: 'lgAfterAppendSlide',\n init: 'lgInit',\n hasVideo: 'lgHasVideo',\n containerResize: 'lgContainerResize',\n updateSlides: 'lgUpdateSlides',\n afterAppendSubHtml: 'lgAfterAppendSubHtml',\n beforeOpen: 'lgBeforeOpen',\n afterOpen: 'lgAfterOpen',\n slideItemLoad: 'lgSlideItemLoad',\n beforeSlide: 'lgBeforeSlide',\n afterSlide: 'lgAfterSlide',\n posterClick: 'lgPosterClick',\n dragStart: 'lgDragStart',\n dragMove: 'lgDragMove',\n dragEnd: 'lgDragEnd',\n beforeNextSlide: 'lgBeforeNextSlide',\n beforePrevSlide: 'lgBeforePrevSlide',\n beforeClose: 'lgBeforeClose',\n afterClose: 'lgAfterClose',\n rotateLeft: 'lgRotateLeft',\n rotateRight: 'lgRotateRight',\n flipHorizontal: 'lgFlipHorizontal',\n flipVertical: 'lgFlipVertical',\n autoplay: 'lgAutoplay',\n autoplayStart: 'lgAutoplayStart',\n autoplayStop: 'lgAutoplayStop',\n};\n\n// Follow the below format for the event documentation\n// @method is the method name when event is used with Angular/React components\n\n/**\n * Fired only once when lightGallery is initialized\n * @name lgInit\n * @method onInit\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action on lightGallery initialization.\n * // Init event returns the plugin instance that can be used to call any lightGalley public method\n * let pluginInstance = null;\n * lg.addEventListener('lgInit', (event) => {\n * pluginInstance = event.detail.instance;\n * });\n * lightGallery(lg);\n * @see <a href=\"/docs/methods/\">Methods</a>\n */\nexport interface InitDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired when the slide content has been inserted into it's slide container.\n * @name lgAfterAppendSlide\n * @method onAfterAppendSlide\n */\nexport interface AfterAppendSlideEventDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired immediately before opening the gallery\n * @name lgBeforeOpen\n * @method onBeforeOpen\n */\nexport interface BeforeOpenDetail {}\n\n/**\n * Fired immediately after opening the gallery\n * @name lgAfterOpen\n * @method onAfterOpen\n */\nexport interface AfterOpenDetail {}\n\n/**\n * Fired once the media inside the slide has been completely loaded .\n * @name lgSlideItemLoad\n * @method onSlideItemLoad\n */\nexport interface SlideItemLoadDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * For the first slide, lightGallery adds some delay for displaying the loaded slide item.\n * This delay is required for the transition effect when the slide item is displayed\n * Respect the delay when you use this event\n */\n delay: number;\n\n // Will be true for the first slide\n isFirstSlide: boolean;\n}\n\n/**\n * Fired immediately before each slide transition.\n * @name lgBeforeSlide\n * @method onBeforeSlide\n * @example\n * const lg = document.getElementById('custom-events-demo');\n * // Perform any action before each slide transition\n * lg.addEventListener('lgBeforeSlide', (event) => {\n * const { index, prevIndex } = event.detail;\n * alert(index, prevIndex);\n * });\n * lightGallery(lg);\n */\nexport interface BeforeSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired immediately after each slide transition.\n * @name lgAfterSlide\n * @method onAfterSlide\n */\nexport interface AfterSlideDetail {\n /**\n * Index of the previous slide\n */\n prevIndex: number;\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n /**\n * true if slide function called via thumbnail click\n */\n fromThumb: boolean;\n}\n\n/**\n * Fired when the video poster is clicked.\n * @name lgPosterClick\n * @method onPosterClick\n */\nexport interface PosterClickDetail {}\n\n/**\n * Fired when the drag event to move to different slide starts.\n * @name lgDragStart\n * @method onDragStart\n */\nexport interface DragStartDetail {}\n\n/**\n * Fired periodically during the drag operation.\n * @name lgDragMove\n * @method onDragMove\n */\nexport interface DragMoveDetail {}\n\n/**\n * Fired when the user has finished the drag operation\n * @name lgDragEnd\n * @method onDragEnd\n */\nexport interface DragEndDetail {}\n\n/**\n * Fired immediately before the start of the close process.\n * @name lgBeforeClose\n * @method onBeforeClose\n */\nexport interface BeforeCloseDetail {}\n\n/**\n * Fired immediately once lightGallery is closed.\n * @name lgAfterClose\n * @method onAfterClose\n */\nexport interface AfterCloseDetail {\n /**\n * lightGallery plugin instance\n */\n instance: LightGallery;\n}\n\n/**\n * Fired immediately before each \"next\" slide transition\n * @name lgBeforeNextSlide\n * @method onBeforeNextSlide\n */\nexport interface BeforeNextSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired immediately before each \"prev\" slide transition\n * @name lgBeforePrevSlide\n * @method onBeforePrevSlide\n */\nexport interface BeforePrevSlideDetail {\n /**\n * Index of the slide\n */\n index: number;\n /**\n * true if slide function called via touch event or mouse drag\n */\n fromTouch: boolean;\n}\n\n/**\n * Fired when the sub-html content (ex : title/ description) has been appended into the slide.\n * @name lgAfterAppendSubHtml\n * @method onAfterAppendSubHtml\n */\nexport interface AfterAppendSubHtmlDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the lightGallery container has been resized.\n * @name lgContainerResize\n * @method onContainerResize\n */\nexport interface ContainerResizeDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when lightGallery detects video slide\n * @name lgHasVideo\n * @method onHasVideo\n */\nexport interface HasVideoDetail {\n /**\n * Index of the slide,\n */\n index: number;\n /**\n * Video source\n */\n src: string;\n /**\n * HTML5 video source if available\n * <p>\n HTML5 video source = source: {\n src: string;\n type: string;\n }[];\n attributes: HTMLVideoElement;\n * </p>\n */\n html5Video: VideoSource;\n /**\n * True if video has poster\n */\n hasPoster: boolean;\n}\n\n/**\n * Fired when the image is rotated in anticlockwise direction\n * @name lgRotateLeft\n * @method onRotateLeft\n */\nexport interface RotateLeftDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is rotated in clockwise direction\n * @name lgRotateRight\n * @method onRotateRight\n */\nexport interface RotateRightDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped horizontally\n * @name lgFlipHorizontal\n * @method onFlipHorizontal\n */\nexport interface FlipHorizontalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n\n/**\n * Fired when the image is flipped vertically\n * @name lgFlipVertical\n * @method onFlipVertical\n */\nexport interface FlipVerticalDetail {\n /**\n * Index of the slide\n */\n index: number;\n}\n","export interface JustifiedSettings {\n /**\n * Enable the justified layout for the gallery's trigger thumbnails:\n * rows of equal height and varying widths that fill the container\n * edge to edge. Inline galleries only, dynamic mode has no trigger\n * grid to lay out. Each box shows as a placeholder and its thumbnail\n * fades in once loaded; put `class=\"lg-justified\"` on the container\n * markup so nothing shows unorganized before the script runs.\n * See <a href=\"/docs/justified-layout/\">Justified layout</a>.\n */\n justified: boolean;\n /**\n * Row height (px) the layout aims for; actual rows land as close to\n * it as the aspect ratios allow.\n */\n justifiedRowHeight: number;\n /**\n * Gap between thumbnails and between rows (px).\n */\n justifiedGap: number;\n /**\n * Last-row policy: 'justify' scales the leftover row to fill the\n * width like every other row, 'start' keeps the row height aligned\n * to the reading start, 'hide' hides the leftover thumbnails.\n */\n justifiedLastRow: 'justify' | 'start' | 'hide';\n /**\n * Row-height clamp as a multiple of justifiedRowHeight, a sparse\n * row never renders taller than this.\n */\n justifiedMaxScale: number;\n /**\n * How thumbnails appear as they load: 'row' reveals whole rows top\n * to bottom, each once every thumbnail in it has loaded; 'image'\n * reveals each thumbnail on its own as soon as it has loaded.\n * Until a thumbnail is revealed its box shows as a placeholder.\n * See <a href=\"/docs/justified-layout/\">Justified layout</a>.\n * @version V3.0.0\n */\n justifiedReveal: 'row' | 'image';\n}\n\nexport const justifiedSettings: JustifiedSettings = {\n justified: true,\n justifiedRowHeight: 180,\n justifiedGap: 8,\n justifiedLastRow: 'start',\n justifiedMaxScale: 1.75,\n justifiedReveal: 'row',\n};\n","import {\n getJustifiedLayout,\n getJustifiedRows,\n getRevealableItems,\n parseImageSize,\n} from '@lightgallery/headless';\nimport { lGEvents } from '../../lg-events';\nimport { LgQuery } from '../../lgQuery';\nimport { LightGallery } from '../../lightgallery';\nimport { JustifiedSettings, justifiedSettings } from './lg-justified-settings';\n\n/**\n * lightGallery justified layout: lays the gallery's trigger thumbnails\n * out in rows of equal height and varying widths that fill the\n * container edge to edge. The row math is shared headless code; this\n * plugin measures the container, sources the aspect ratios and writes\n * the geometry.\n *\n * Aspect-ratio sources, in order: the trigger's `data-lg-size`\n * attribute, the thumbnail's `width`/`height` attributes, and finally\n * the loaded image's natural size (one relayout when the last unknown\n * resolves).\n *\n * Triggers stay invisible (stylesheet) until they are positioned; each\n * box then shows as a placeholder and the thumbnails fade in as they\n * load, row by row in reading order or one by one (`justifiedReveal`),\n * so the grid is never seen unorganized. Ship `class=\"lg-justified\"`\n * on the container markup to cover the time before the script runs.\n */\nexport default class Justified {\n core: LightGallery;\n settings: JustifiedSettings;\n private $LG!: LgQuery;\n private triggers: HTMLElement[] = [];\n private ratios: (number | null)[] = [];\n private resizeObserver?: ResizeObserver;\n private layoutWidth = 0;\n private pendingLoads: (() => void)[] = [];\n private rows: HTMLElement[][] = [];\n private loaded = new Set<HTMLElement>();\n private loadWatchers = new Map<HTMLElement, () => void>();\n private originalContainerStyle = '';\n private originalTriggerStyles = new Map<HTMLElement, string>();\n\n constructor(instance: LightGallery, $LG: LgQuery) {\n this.core = instance;\n this.$LG = $LG;\n this.settings = { ...justifiedSettings, ...this.core.settings };\n return this;\n }\n\n public init(): void {\n // Dynamic galleries have no inline trigger grid to lay out.\n if (!this.settings.justified || this.core.settings.dynamic) {\n return;\n }\n this.collectTriggers();\n if (!this.triggers.length) {\n return;\n }\n this.originalContainerStyle = this.core.el.getAttribute('style') || '';\n // The reveal marker gates the stylesheet's placeholder + fade\n // rules: they hold a thumbnail invisible until this plugin\n // reveals it, so they must never apply to a grid positioned by\n // other code.\n this.core.el.classList.add('lg-justified', 'lg-justified-reveal');\n this.resolveRatios();\n this.layout();\n\n // refresh()/updateSlides() re-collect the core's items before\n // firing this event, the grid follows the new trigger set.\n this.core.LGel.on(`${lGEvents.updateSlides}.justified`, () => {\n this.pendingLoads.forEach((cancel) => cancel());\n this.pendingLoads = [];\n this.cancelLoadWatchers();\n this.collectTriggers();\n this.resolveRatios();\n this.layout();\n });\n\n // Row heights derive from the width alone, so one observer on\n // the container covers every reflow source (viewport, sidebar,\n // font swap...).\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => {\n if (this.core.el.clientWidth !== this.layoutWidth) {\n this.layout();\n }\n });\n this.resizeObserver.observe(this.core.el);\n }\n }\n\n /** Adopt the core's current trigger list into the layout. */\n private collectTriggers(): void {\n this.triggers = Array.prototype.slice.call(this.core.items);\n this.triggers.forEach((trigger) => {\n if (!this.originalTriggerStyles.has(trigger)) {\n this.originalTriggerStyles.set(\n trigger,\n trigger.getAttribute('style') || '',\n );\n }\n trigger.classList.add('lg-justified-item');\n });\n }\n\n /** Best-known aspect ratio per trigger; unknowns resolve on load. */\n private resolveRatios(): void {\n this.ratios = this.triggers.map((trigger, index) => {\n const size = parseImageSize(\n trigger.getAttribute('data-lg-size') || undefined,\n window.innerWidth,\n );\n if (size) {\n return size.width / size.height;\n }\n const img = trigger.querySelector('img');\n if (!img) {\n return 1;\n }\n const width = parseInt(img.getAttribute('width') || '', 10);\n const height = parseInt(img.getAttribute('height') || '', 10);\n if (width > 0 && height > 0) {\n return width / height;\n }\n if (img.complete && img.naturalWidth > 0) {\n return img.naturalWidth / img.naturalHeight;\n }\n this.watchImageLoad(img, index);\n return null;\n });\n }\n\n /** Relayout once when the last unknown thumbnail resolves. */\n private watchImageLoad(img: HTMLImageElement, index: number): void {\n const cancel = (): void => {\n img.removeEventListener('load', onDone);\n img.removeEventListener('error', onDone);\n };\n const onDone = (): void => {\n cancel();\n this.pendingLoads = this.pendingLoads.filter((c) => c !== cancel);\n this.ratios[index] =\n img.naturalWidth > 0 ? img.naturalWidth / img.naturalHeight : 1;\n if (this.ratios.every((ratio) => ratio !== null)) {\n this.layout();\n }\n };\n img.addEventListener('load', onDone);\n img.addEventListener('error', onDone);\n this.pendingLoads.push(cancel);\n }\n\n private layout(): void {\n const containerWidth = this.core.el.clientWidth;\n if (!containerWidth) {\n return;\n }\n this.layoutWidth = containerWidth;\n const { boxes, containerHeight } = getJustifiedLayout({\n // Unknown ratios render square until their image resolves.\n ratios: this.ratios.map((ratio) => ratio ?? 1),\n containerWidth,\n targetRowHeight: this.settings.justifiedRowHeight,\n gap: this.settings.justifiedGap,\n lastRow: this.settings.justifiedLastRow,\n maxScale: this.settings.justifiedMaxScale,\n });\n // The box offsets are logical (from the reading-start edge).\n const startSide =\n this.core.settings.direction === 'rtl' ? 'right' : 'left';\n const endSide = startSide === 'left' ? 'right' : 'left';\n this.core.el.style.height = `${containerHeight}px`;\n this.triggers.forEach((trigger, index) => {\n const box = boxes[index]!;\n const hidden = box.width === 0 && box.height === 0;\n trigger.classList.toggle('lg-justified-item-hidden', hidden);\n if (hidden) {\n return;\n }\n trigger.style.top = `${box.top}px`;\n trigger.style[startSide] = `${box.start}px`;\n trigger.style[endSide] = 'auto';\n trigger.style.width = `${box.width}px`;\n trigger.style.height = `${box.height}px`;\n // With the rendered width known exactly, responsive\n // thumbnails get a precise sizes hint.\n const img = trigger.querySelector('img');\n if (img && img.hasAttribute('srcset')) {\n img.setAttribute('sizes', `${box.width}px`);\n }\n this.watchLoad(trigger, img);\n });\n this.rows = getJustifiedRows(boxes).map((row) =>\n row.map((index) => this.triggers[index]!),\n );\n this.reveal();\n }\n\n /** Track when the trigger's thumbnail has settled (loaded or failed). */\n private watchLoad(\n trigger: HTMLElement,\n img: HTMLImageElement | null,\n ): void {\n if (this.loaded.has(trigger) || this.loadWatchers.has(trigger)) {\n return;\n }\n if (!img || img.complete) {\n this.loaded.add(trigger);\n return;\n }\n const onDone = (): void => {\n cancel();\n this.loaded.add(trigger);\n this.reveal();\n };\n const cancel = (): void => {\n img.removeEventListener('load', onDone);\n img.removeEventListener('error', onDone);\n this.loadWatchers.delete(trigger);\n };\n img.addEventListener('load', onDone);\n img.addEventListener('error', onDone);\n this.loadWatchers.set(trigger, cancel);\n }\n\n /**\n * Fade in what may show now (see `justifiedReveal`). Never re-hides:\n * a relayout regroups the rows, already visible triggers stay.\n */\n private reveal(): void {\n getRevealableItems(\n this.rows,\n (trigger) => this.loaded.has(trigger),\n this.settings.justifiedReveal,\n ).forEach((trigger) => {\n trigger.classList.add('lg-justified-item-visible');\n });\n }\n\n private cancelLoadWatchers(): void {\n Array.from(this.loadWatchers.values()).forEach((cancel) => cancel());\n }\n\n public closeGallery(): void {\n // Nothing to do, the layout lives outside the lightbox.\n }\n\n public destroy(): void {\n this.resizeObserver?.disconnect();\n this.pendingLoads.forEach((cancel) => cancel());\n this.pendingLoads = [];\n this.cancelLoadWatchers();\n this.loaded.clear();\n this.rows = [];\n if (!this.triggers.length) {\n return;\n }\n this.core.LGel.off('.justified');\n this.core.el.classList.remove('lg-justified', 'lg-justified-reveal');\n if (this.originalContainerStyle) {\n this.core.el.setAttribute('style', this.originalContainerStyle);\n } else {\n this.core.el.removeAttribute('style');\n }\n this.triggers.forEach((trigger) => {\n trigger.classList.remove(\n 'lg-justified-item',\n 'lg-justified-item-hidden',\n 'lg-justified-item-visible',\n );\n const original = this.originalTriggerStyles.get(trigger);\n if (original) {\n trigger.setAttribute('style', original);\n } else {\n trigger.removeAttribute('style');\n }\n });\n }\n}\n"],"names":["row"],"mappings":"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"}
|