Issues (14)

src/helpers.js (4 issues)

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'));
0 ignored issues
show
The variable Event seems to be never declared. If this is a global, consider adding a /** global: Event */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
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'));
0 ignored issues
show
The variable Event seems to be never declared. If this is a global, consider adding a /** global: Event */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
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'));
0 ignored issues
show
The variable Event seems to be never declared. If this is a global, consider adding a /** global: Event */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
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'));
0 ignored issues
show
The variable Event seems to be never declared. If this is a global, consider adding a /** global: Event */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
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