PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 3.33
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v3.33
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
photonic / include / js / front-end / src / Core.js

Core.js in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 3.33, at include/js/front-end/src/Core.js

265 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import * as Util from "./Util";
2 import {Tooltip} from "./Components/Tooltip";
3 import {Prompter} from "./Components/Prompter";
4
5 export class Core {
6 static lightboxList = [];
7 static prompterList = [];
8
9 static lightbox;
10 static deep = location.hash;
11
12 static setLightbox = (lb) => this.lightbox = lb;
13 static getLightbox = () => this.lightbox;
14
15 static setDeep = (d) => this.deep = d;
16 static getDeep = () => this.deep;
17
18 static addToLightboxList = (idx, lightbox) => this.lightboxList[idx] = lightbox;
19 static getLightboxList = () => this.lightboxList;
20
21 static showSpinner = () => {
22 let loading = document.getElementsByClassName('photonic-loading');
23 if (loading.length > 0) {
24 loading = loading[0];
25 }
26 else {
27 loading = document.createElement('div');
28 loading.className = 'photonic-loading';
29 }
30 loading.style.display = 'block';
31 document.body.appendChild(loading);
32 };
33
34 static hideLoading = () => {
35 let loading = document.getElementsByClassName('photonic-loading');
36 if (loading.length > 0) {
37 loading = loading[0];
38 loading.style.display = 'none';
39 }
40 };
41
42 static initializePasswordPrompter = selector => {
43 const selectorNoHash = selector.replace(/^#+/g, '');
44 const prompter = new Prompter(selectorNoHash);
45 prompter.attach();
46 this.prompterList[selector] = prompter;
47 prompter.show();
48 };
49
50 static moveHTML5External = () => {
51 let videos = document.getElementById('photonic-html5-external-videos');
52 if (!videos) {
53 videos = document.createElement('div');
54 videos.id = 'photonic-html5-external-videos';
55 videos.style.display = 'none';
56 document.body.appendChild(videos);
57 }
58
59 const current = document.querySelectorAll('.photonic-html5-external');
60 if (current) {
61 const cLen = current.length;
62 for (let c = 0; c < cLen; c++) {
63 current[c].classList.remove('photonic-html5-external');
64 videos.appendChild(current[c]);
65 }
66 }
67 };
68
69 static blankSlideupTitle = () => {
70 document.querySelectorAll('.title-display-slideup-stick, .photonic-slideshow.title-display-slideup-stick').forEach((item) => {
71 Array.from(item.getElementsByTagName('a')).forEach(a => {
72 a.setAttribute('title', '');
73 });
74 });
75 };
76
77 static showSlideupTitle = () => {
78 let titles = document.documentElement.querySelectorAll('.title-display-slideup-stick a .photonic-title');
79 const len = titles.length;
80 for (let i = 0; i < len; i++) {
81 titles[i].style.display = 'block';
82 }
83 };
84
85 static waitForImages = async (selector) => {
86 let images = this.getImagesFromSelector(selector);
87 let imageUrlArray = [];
88 let anchorArray = [];
89 let setDimensions = false;
90
91 if (selector instanceof Element && selector.getAttribute('data-photonic-platform') === 'instagram') {
92 setDimensions = true;
93 }
94
95 images.forEach(img => {
96 imageUrlArray.push(img.getAttribute('src'));
97 anchorArray.push(img.parentElement);
98 });
99
100 const promiseArray = []; // create an array for promises
101 const imageArray = []; // array for the images
102
103 for (const [idx, imageUrl] of imageUrlArray.entries()) {
104 promiseArray.push(new Promise(resolve => {
105 const img = new Image();
106 img.onload = () => {
107 if (setDimensions) {
108 anchorArray[idx].setAttribute('data-pswp-width', img.naturalWidth);
109 anchorArray[idx].setAttribute('data-pswp-height', img.naturalHeight);
110 }
111 resolve();
112 };
113
114 img.src = imageUrl;
115 imageArray.push(img);
116 }));
117 }
118
119 await Promise.all(promiseArray); // wait for all the images to be loaded
120 return imageArray;
121 };
122
123 static loadSingleImage = async(image) => {
124 const promiseArray = [];
125 let retImage = null;
126 promiseArray.push(new Promise(resolve => {
127 const img = new Image();
128 img.onload = () => {
129 resolve();
130 };
131
132 if (image.getAttribute('data-src') !== null) {
133 img.src = image.getAttribute('data-src');
134 }
135 else {
136 img.src = image.getAttribute('src'); // Leave the 'src' in just as a backup. E.g. Gallery header images
137 }
138
139 retImage = img;
140 }));
141
142 await Promise.all(promiseArray);
143 return retImage;
144 };
145
146 static watchForImages = (selector) => {
147 let images = this.getImagesFromSelector(selector);
148
149 const intersectionObserver = new IntersectionObserver((items, observer) => {
150 items.forEach((item) => {
151 if (item.isIntersecting || item.intersectionRatio > 0) {
152 const image = item.target;
153 image.closest('a').classList.add('photonic-image-loading');
154
155 this.loadSingleImage(image).then(() => {
156 if (image.getAttribute('data-src') !== null && image.getAttribute('data-src') !== '') {
157 image.src = image.getAttribute('data-src');
158 image.setAttribute('data-src', '');
159 image.setAttribute('data-loaded', 'true');
160 }
161
162 image.closest('a').classList.remove('photonic-image-loading');
163 Util.fadeIn(image);
164 });
165 observer.unobserve(image);
166 }
167 });
168 });
169
170 images.forEach((image) => {
171 intersectionObserver.observe(image);
172 });
173 };
174
175 static getImagesFromSelector = selector => {
176 let images = [];
177 if (typeof selector === 'string') {
178 document.querySelectorAll(selector).forEach(selection => {
179 images = Array.from(selection.getElementsByTagName('img'));
180 });
181 }
182 else if (selector instanceof Element) {
183 images = Array.from(selector.getElementsByTagName('img'));
184 }
185 else if (selector instanceof NodeList) {
186 selector.forEach((selection) => {
187 images.push(selection.querySelector('img'));
188 });
189 }
190 return images;
191 };
192
193 static standardizeTitleWidths = () => {
194 const self = this;
195
196 const setWidths = grid => {
197 grid.querySelectorAll('.photonic-thumb').forEach(item => {
198 let img = item.getElementsByTagName('img');
199 if (img != null) {
200 img = img[0];
201 let title = item.querySelector('.photonic-title-info');
202 if (title) {
203 title.style.width = img.width + 'px';
204 }
205 }
206 });
207 };
208
209 document.querySelectorAll('.photonic-standard-layout.title-display-below, .photonic-standard-layout.title-display-hover-slideup-show, .photonic-standard-layout.title-display-slideup-stick').forEach(grid => {
210 if (grid.classList.contains('sizes-present')) {
211 self.watchForImages(grid);
212 setWidths(grid);
213 }
214 else {
215 self.waitForImages(grid).then(() => {
216 setWidths(grid);
217 });
218 }
219 });
220 };
221
222 static sanitizeTitles = () => {
223 const thumbs = document.querySelectorAll('.photonic-stream a, a.photonic-level-2-thumb');
224 thumbs.forEach((thumb) => {
225 if (!thumb.parentNode.classList.contains('photonic-header-title')) {
226 const title = thumb.getAttribute('title');
227 // Not doing a Util.getText, which uses innerHTML, which is susceptible to XSS
228 thumb.setAttribute('title', Util.getText(title));
229 const dataTitle = thumb.getAttribute('data-title')
230 thumb.setAttribute('data-title', Util.HTMLSanitizer.SanitizeHTML(dataTitle));
231 }
232 });
233 };
234
235 static initializeTooltips = () => {
236 if (document.querySelector('.title-display-tooltip a, .photonic-slideshow.title-display-tooltip img') != null) {
237 Tooltip('[data-photonic-tooltip]', '.photonic-tooltip-container');
238 }
239 };
240
241 static showRegularGrids = () => {
242 document.querySelectorAll('.photonic-standard-layout').forEach(grid => {
243 if (grid.classList.contains('sizes-present')) {
244 this.watchForImages(grid);
245 }
246 else {
247 this.waitForImages(grid).then(() => {
248 grid.querySelectorAll('.photonic-level-1, .photonic-level-2').forEach(item => {
249 item.style.display = 'inline-block';
250 });
251 });
252 }
253 });
254 };
255
256 static executeCommon = () => {
257 Core.moveHTML5External();
258 Core.blankSlideupTitle();
259 Core.standardizeTitleWidths();
260 Core.sanitizeTitles();
261 Core.initializeTooltips();
262 Core.showRegularGrids();
263 };
264 }
265