1 | /** |
||
2 | * List of all functions |
||
3 | * |
||
4 | * - liveBlock(attr) |
||
5 | * - liveForm(attr) |
||
6 | * |
||
7 | * - seasonedBackground |
||
8 | * - responsiveImage(string) Relative to Liip filters |
||
9 | * - uncloakLinks(attr) |
||
10 | * - convertFormFromRot13(attr) |
||
11 | * - readableEmail(attr) |
||
12 | * - convertImageLinkToWebPLink() |
||
13 | */ |
||
14 | |||
15 | /** |
||
16 | * Live Block Watcher (and button) |
||
17 | * |
||
18 | * Fetch (ajax) function permitting to get block via a POST request |
||
19 | * |
||
20 | * @param {string} attribute |
||
21 | */ |
||
22 | export function liveBlock( |
||
23 | liveBlockAttribute = 'data-live', |
||
24 | liveFormSelector = '.live-form' |
||
25 | ) { |
||
26 | var btnToBlock = function (event, btn) { |
||
27 | btn.setAttribute( |
||
28 | liveBlockAttribute, |
||
29 | btn.getAttribute('src-' + liveBlockAttribute) |
||
30 | ); |
||
31 | getLiveBlock(btn); |
||
32 | }; |
||
33 | |||
34 | var getLiveBlock = function (item) { |
||
35 | fetch(item.getAttribute(liveBlockAttribute), { |
||
36 | //headers: { "Content-Type": "application/json", Accept: "text/plain" }, |
||
37 | method: 'POST', |
||
38 | credentials: 'include', |
||
39 | }) |
||
40 | .then(function (response) { |
||
41 | return response.text(); |
||
42 | }) |
||
43 | .then(function (body) { |
||
44 | item.removeAttribute(liveBlockAttribute); |
||
45 | item.outerHTML = body; |
||
46 | }) |
||
47 | .then(function () { |
||
48 | document.dispatchEvent(new Event('DOMChanged')); |
||
49 | }); |
||
50 | }; |
||
51 | |||
52 | var htmlLoader = |
||
53 | '<div style="width:1em;height:1em;border: 2px solid #222;border-top-color: #fff;border-radius: 50%; animation: 1s spin linear infinite;"></div><style>@keyframes spin {from{transform:rotate(0deg)}to{transform:rotate(360deg)}}</style>'; |
||
54 | |||
55 | var setLoader = function (form) { |
||
56 | var $submitButton = getSubmitButton(form); |
||
57 | if ($submitButton !== undefined) { |
||
58 | var initialButton = $submitButton.outerHTML; |
||
59 | $submitButton.innerHTML = ''; |
||
60 | $submitButton.outerHTML = htmlLoader; |
||
61 | } |
||
62 | }; |
||
63 | |||
64 | var sendForm = function (form, liveFormBlock) { |
||
65 | setLoader(form); |
||
66 | |||
67 | var formData = new FormData(form.srcElement); |
||
68 | fetch(form.srcElement.action, { |
||
69 | method: 'POST', |
||
70 | body: formData, |
||
71 | credentials: 'include', |
||
72 | }) |
||
73 | .then(function (response) { |
||
74 | return response.text(); |
||
75 | }) |
||
76 | .then(function (body) { |
||
77 | liveFormBlock.outerHTML = body; |
||
78 | }) |
||
79 | .then(function () { |
||
80 | document.dispatchEvent(new Event('DOMChanged')); |
||
81 | }); |
||
82 | }; |
||
83 | |||
84 | var getSubmitButton = function (form) { |
||
85 | if (form.srcElement.querySelector('[type=submit]') !== null) { |
||
86 | return form.srcElement.querySelector('[type=submit]'); |
||
87 | } |
||
88 | if (form.srcElement.getElementsByTagName('button') !== null) { |
||
89 | return form.srcElement.getElementsByTagName('button')[0]; |
||
90 | } |
||
91 | return null; |
||
92 | }; |
||
93 | |||
94 | // Listen data-live |
||
95 | document.querySelectorAll('[' + liveBlockAttribute + ']').forEach((item) => { |
||
96 | getLiveBlock(item); |
||
97 | }); |
||
98 | |||
99 | // Listen button src-data-live |
||
100 | document |
||
101 | .querySelectorAll('[src-' + liveBlockAttribute + ']') |
||
102 | .forEach((item) => { |
||
103 | item.addEventListener('click', (event) => { |
||
104 | btnToBlock(event, item); |
||
105 | }); |
||
106 | }); |
||
107 | |||
108 | // Listen live-form |
||
109 | document.querySelectorAll(liveFormSelector).forEach((item) => { |
||
110 | if (item.querySelector('form') !== null) { |
||
111 | item.querySelector('form').addEventListener('submit', (e) => { |
||
112 | e.preventDefault(); |
||
113 | sendForm(e, item); |
||
114 | }); |
||
115 | } |
||
116 | }); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Block to replace Watcher |
||
121 | * On $event on element find via $attribute, set attribute's content in element.innerHTML |
||
122 | */ |
||
123 | export function replaceOn(attribute = 'replaceBy', eventName = 'click') { |
||
124 | var loadVideo = function (element) { |
||
125 | var content = element.getAttribute(attribute); |
||
126 | if ( |
||
127 | element.classList.contains('hero-banner-overlay-lg') && |
||
128 | element.querySelector('picture') && |
||
129 | window.innerWidth < 992 |
||
130 | ) { |
||
131 | element.querySelector('picture').outerHTML = content; |
||
132 | element.querySelector('.btn-play').outerHTML = ' '; |
||
133 | } else { |
||
134 | element.innerHTML = content; |
||
135 | } |
||
136 | if (element.classList.contains('hero-banner-overlay-lg')) { |
||
137 | element.style.zIndex = '2000'; |
||
138 | } |
||
139 | element.removeAttribute(attribute); |
||
140 | document.dispatchEvent(new Event('DOMChanged')); |
||
141 | }; |
||
142 | |||
143 | document |
||
144 | .querySelectorAll('[' + attribute + ']:not([listen])') |
||
145 | .forEach(function (element) { |
||
146 | element.setAttribute('listen', ''); |
||
147 | element.addEventListener( |
||
148 | eventName, |
||
149 | function (event) { |
||
150 | loadVideo(event.currentTarget); //event.currentTarget; |
||
151 | element.removeAttribute('listen'); |
||
152 | }, |
||
153 | { once: true } |
||
154 | ); |
||
155 | }); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * |
||
160 | * |
||
161 | */ |
||
162 | export function seasonedBackground() { |
||
163 | document.querySelectorAll('[x-hash]').forEach(function (element) { |
||
164 | if (window.location.hash) { |
||
165 | if (element.getAttribute('x-hash') == window.location.hash.substring(1)) { |
||
166 | element.parentNode.parentNode |
||
167 | .querySelectorAll('img') |
||
168 | .forEach(function (img) { |
||
169 | img.style = 'display:none'; |
||
170 | }); |
||
171 | element.style = 'display:block'; |
||
172 | } |
||
173 | } |
||
174 | }); |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Transform image's path (src) produce with Liip to responsive path |
||
179 | * |
||
180 | * @param {string} src |
||
181 | */ |
||
182 | export function responsiveImage(src) { |
||
183 | var screenWidth = window.innerWidth; |
||
184 | if (screenWidth <= 576) { |
||
185 | src = src.replace('/default/', '/xs/'); |
||
186 | } else if (screenWidth <= 768) { |
||
187 | src = src.replace('/default/', '/sm/'); |
||
188 | } else if (screenWidth <= 992) { |
||
189 | src = src.replace('/default/', '/md/'); |
||
190 | } else if (screenWidth <= 1200) { |
||
191 | src = src.replace('/default/', '/lg/'); |
||
192 | } else { |
||
193 | // 1200+ |
||
194 | src = src.replace('/default/', '/xl/'); |
||
195 | } |
||
196 | |||
197 | return src; |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Convert elements wich contain attribute (data-href) in normal link (a href) |
||
202 | * You can use a callback function to decrypt the link (eg: rot13ToText ;-)) |
||
203 | * |
||
204 | * @param {string} attribute |
||
205 | */ |
||
206 | export async function uncloakLinks(attribute = 'data-rot') { |
||
207 | var convertLink = function (element) { |
||
208 | // fix "bug" with img |
||
209 | if (element.getAttribute(attribute) === null) { |
||
210 | var element = element.closest('[' + attribute + ']'); |
||
211 | } |
||
212 | if (element.getAttribute(attribute) === null) return; |
||
0 ignored issues
–
show
|
|||
213 | var link = document.createElement('a'); |
||
214 | var href = element.getAttribute(attribute); |
||
215 | element.removeAttribute(attribute); |
||
216 | for (var i = 0, n = element.attributes.length; i < n; i++) { |
||
217 | link.setAttribute( |
||
218 | element.attributes[i].nodeName, |
||
219 | element.attributes[i].nodeValue |
||
220 | ); |
||
221 | } |
||
222 | link.innerHTML = element.innerHTML; |
||
223 | link.setAttribute( |
||
224 | 'href', |
||
225 | responsiveImage(convertShortchutForLink(rot13ToText(href))) |
||
226 | ); |
||
227 | element.parentNode.replaceChild(link, element); |
||
228 | return link; |
||
229 | }; |
||
230 | |||
231 | var convertThemAll = function (attribute) { |
||
232 | [].forEach.call(document.querySelectorAll('[' + attribute + ']'), function ( |
||
233 | element |
||
234 | ) { |
||
235 | convertLink(element); |
||
236 | }); |
||
237 | }; |
||
238 | |||
239 | var fireEventLinksBuilt = async function (element, event) { |
||
240 | await document.dispatchEvent(new Event('DOMChanged')); |
||
241 | |||
242 | var clickEvent = new Event(event.type); |
||
243 | element.dispatchEvent(clickEvent); |
||
244 | }; |
||
245 | |||
246 | var convertLinkOnEvent = async function (event) { |
||
247 | // convert them all if it's an image (thanks this bug), permit to use gallery (baguetteBox) |
||
248 | if (event.target.tagName == 'IMG') { |
||
249 | await convertThemAll(attribute); |
||
250 | var element = event.target; |
||
251 | } else { |
||
252 | var element = convertLink(event.target); |
||
253 | } |
||
254 | fireEventLinksBuilt(element, event); |
||
255 | }; |
||
256 | |||
257 | [].forEach.call(document.querySelectorAll('[' + attribute + ']'), function ( |
||
258 | element |
||
259 | ) { |
||
260 | element.addEventListener( |
||
261 | 'touchstart', |
||
262 | function (e) { |
||
263 | convertLinkOnEvent(e); |
||
264 | }, |
||
265 | { once: true, passive: true } |
||
266 | ); |
||
267 | element.addEventListener( |
||
268 | 'click', |
||
269 | function (e) { |
||
270 | convertLinkOnEvent(e); |
||
271 | }, |
||
272 | { once: true } |
||
273 | ); |
||
274 | element.addEventListener( |
||
275 | 'mouseover', |
||
276 | function (e) { |
||
277 | convertLinkOnEvent(e); |
||
278 | }, |
||
279 | { once: true } |
||
280 | ); |
||
281 | }); |
||
282 | } |
||
283 | |||
284 | /** |
||
285 | * Convert action attr encoded in rot 13 to normal action with default attr `data-frot` |
||
286 | * |
||
287 | * @param {string} attribute |
||
288 | */ |
||
289 | export function convertFormFromRot13(attribute = 'data-frot') { |
||
290 | [].forEach.call(document.querySelectorAll('[' + attribute + ']'), function ( |
||
291 | element |
||
292 | ) { |
||
293 | var action = element.getAttribute(attribute); |
||
294 | element.removeAttribute(attribute); |
||
295 | element.setAttribute( |
||
296 | 'action', |
||
297 | convertShortchutForLink(rot13ToText(action)) |
||
298 | ); |
||
299 | }); |
||
300 | } |
||
301 | |||
302 | export function convertShortchutForLink(str) { |
||
303 | if (str.charAt(0) == '-') { |
||
304 | return str.replace('-', 'http://'); |
||
305 | } |
||
306 | if (str.charAt(0) == '_') { |
||
307 | return str.replace('_', 'https://'); |
||
308 | } |
||
309 | if (str.charAt(0) == '@') { |
||
310 | return str.replace('@', 'mailto:'); |
||
311 | } |
||
312 | return str; |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * readableEmail(selector) Transform an email encoded with rot13 in a readable mail (and add mailto:) |
||
317 | * |
||
318 | * @param {string} text |
||
319 | */ |
||
320 | export function readableEmail(selector) { |
||
321 | document.querySelectorAll(selector).forEach(function (item) { |
||
322 | var mail = rot13ToText(item.textContent); |
||
323 | item.innerHTML = '<a href="mailto:' + mail + '">' + mail + '</a>'; |
||
324 | if (selector.charAt(0) == '.') { |
||
325 | item.classList.remove(selector.substring(1)); |
||
326 | } |
||
327 | }); |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * Decode rot13 |
||
332 | * |
||
333 | * @param {string} str |
||
334 | */ |
||
335 | export function rot13ToText(str) { |
||
336 | return str.replace(/[a-zA-Z]/g, function (c) { |
||
337 | return String.fromCharCode( |
||
338 | (c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26 |
||
339 | ); |
||
340 | }); |
||
341 | } |
||
342 | |||
343 | export function testWebPSupport() { |
||
344 | var elem = document.createElement('canvas'); |
||
345 | |||
346 | if (elem.getContext && elem.getContext('2d')) { |
||
347 | return elem.toDataURL('image/webp').indexOf('data:image/webp') == 0; |
||
348 | } |
||
349 | |||
350 | return false; |
||
351 | } |
||
352 | |||
353 | /** |
||
354 | * Used in ThemeComponent |
||
355 | */ |
||
356 | export function convertImageLinkToWebPLink() { |
||
357 | var switchToWebP = function () { |
||
358 | [].forEach.call(document.querySelectorAll('a[dwl]'), function (element) { |
||
359 | var href = responsiveImage(element.getAttribute('dwl')); |
||
360 | element.setAttribute('href', href); |
||
361 | element.removeAttribute('dwl'); |
||
362 | }); |
||
363 | }; |
||
364 | |||
365 | if (testWebPSupport()) switchToWebP(); |
||
0 ignored issues
–
show
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later. Consider: if (a > 0)
b = 42;
If you or someone else later decides to put another statement in, only the first statement will be executed. if (a > 0)
console.log("a > 0");
b = 42;
In this case the statement if (a > 0) {
console.log("a > 0");
b = 42;
}
ensures that the proper code will be executed conditionally no matter how many statements are added or removed. ![]() |
|||
366 | } |
||
367 | |||
368 | /** |
||
369 | * Simple Image Lazy Loader |
||
370 | * original from : https://davidwalsh.name/lazyload-image-fade |
||
371 | * |
||
372 | * @param {string} attribute |
||
373 | * |
||
374 | * @example |
||
375 | * imgLazyLoad() |
||
376 | * <span data-img=/img/me.png>Tagada</span> or <img data-img=/img/me.png alt=Tagada> |
||
377 | * |
||
378 | * will be converted to |
||
379 | * |
||
380 | * <img src=/img/me.png alt=Tagada /> |
||
381 | * |
||
382 | * still used in piedvert. To remove ?! |
||
383 | */ |
||
384 | export function imgLazyLoad(attribute = 'data-img') { |
||
385 | [].forEach.call(document.querySelectorAll('[' + attribute + ']'), function ( |
||
386 | img |
||
387 | ) { |
||
388 | var newDomImg = document.createElement('img'); |
||
389 | var src = img.getAttribute(attribute); |
||
390 | img.removeAttribute(attribute); |
||
391 | for (var i = 0, n = img.attributes.length; i < n; i++) { |
||
392 | newDomImg.setAttribute( |
||
393 | img.attributes[i].nodeName, |
||
394 | img.attributes[i].nodeValue |
||
395 | ); |
||
396 | } |
||
397 | if (newDomImg.getAttribute('alt') === null && img.textContent != '') { |
||
398 | newDomImg.setAttribute('alt', img.textContent); |
||
399 | } |
||
400 | newDomImg.setAttribute( |
||
401 | 'src', |
||
402 | typeof responsiveImage === 'function' ? responsiveImage(src) : src |
||
403 | ); |
||
404 | img.outerHTML = newDomImg.outerHTML; |
||
405 | }); |
||
406 | } |
||
407 |
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42
will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.