| 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; |
||
|
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
| 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; |
||
| 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(); |
||
| 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 |