@pernod-ricard-global-cms/jsutils 1.6.4 → 1.7.1

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.
Files changed (3) hide show
  1. package/.prettierrc +19 -0
  2. package/jsutils.js +223 -185
  3. package/package.json +28 -27
package/.prettierrc ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "useTabs": true,
3
+ "overrides": [
4
+ {
5
+ "files": "*.test.js",
6
+ "options": {
7
+ "semi": true
8
+ }
9
+ },
10
+ {
11
+ "files": ["*.js"],
12
+ "options": {
13
+ "semi": true,
14
+ "singleQuote": true,
15
+ "trailingComma": "none"
16
+ }
17
+ }
18
+ ]
19
+ }
package/jsutils.js CHANGED
@@ -2,47 +2,58 @@
2
2
  /* eslint-disable no-console */
3
3
 
4
4
  /**
5
- * This function accepts an html element and returns the position of that element on the page.
6
- *
5
+ * Function for check whether the code is running within the Wordpress admin page. Checks for wp-admin class.
6
+ * @returns {Boolean}
7
+ */
8
+ export function isWpAdmin() {
9
+ return document.body.classList.contains('wp-admin') ? true : false;
10
+ }
11
+
12
+ /**
13
+ * This function accepts an html element and returns the position of that element on the page.
14
+ *
7
15
  * @param {htmlElement} element The element whose position you want to get.
8
16
  * @returns {object} An object with the x and y pixel values.
9
17
  */
10
- export function getPosition( element ) {
18
+ export function getPosition(element) {
11
19
  const scrollElementTag = document.scrollingElement.tagName;
12
20
  let xPosition = 0;
13
21
  let yPosition = 0;
14
- while ( element ) {
15
- xPosition +=
16
- element.offsetLeft - element.scrollLeft + element.clientLeft;
22
+ while (element) {
23
+ xPosition += element.offsetLeft - element.scrollLeft + element.clientLeft;
17
24
  yPosition += element.offsetTop - element.scrollTop + element.clientTop;
18
25
  element = element.offsetParent;
19
26
  }
20
27
  // Quirks mode safety - in case of missing DOCTYPE
21
- if ( scrollElementTag === 'BODY' ) {
22
- yPosition += document.querySelector( 'body' ).scrollTop;
28
+ if (scrollElementTag === 'BODY') {
29
+ yPosition += document.querySelector('body').scrollTop;
23
30
  }
24
31
  return { x: xPosition, y: yPosition };
25
32
  }
26
33
 
27
34
  /**
28
- * Adds or removes a 'valid' class to an input and button element depending on whether the value of the input is valid.
35
+ * Adds or removes a 'valid' class to an input and button element depending on whether the value of the input is valid.
29
36
  * @param {htmlElement} input The input element to check.
30
- * @param {htmlElement} button A corresponding button to disable if invalid.
37
+ * @param {htmlElement} button A corresponding button to disable if invalid.
31
38
  */
32
- export function toggleClassByValidity( input, button ) {
33
- input.addEventListener( 'input', () => {
34
- if ( input.validity.valid && input.value ) {
35
- if ( ! button.classList.contains( 'valid' ) ) {
36
- button.classList.add( 'valid' );
37
- }
38
- if ( ! input.classList.contains( 'valid' ) ) {
39
- input.classList.add( 'valid' );
39
+ export function toggleClassByValidity(input, button) {
40
+ try {
41
+ input.addEventListener('input', () => {
42
+ if (input.validity.valid && input.value) {
43
+ if (!button.classList.contains('valid')) {
44
+ button.classList.add('valid');
45
+ }
46
+ if (!input.classList.contains('valid')) {
47
+ input.classList.add('valid');
48
+ }
49
+ } else {
50
+ button.classList.remove('valid');
51
+ input.classList.remove('valid');
40
52
  }
41
- } else {
42
- button.classList.remove( 'valid' );
43
- input.classList.remove( 'valid' );
44
- }
45
- } );
53
+ });
54
+ } catch (error) {
55
+ console.error('jsutils.js ~ toggleClassByValidity ~ error', error);
56
+ }
46
57
  }
47
58
 
48
59
  /**
@@ -51,13 +62,13 @@ export function toggleClassByValidity( input, button ) {
51
62
  * @param {string} assetKey The assetkey string of the block.
52
63
  * @returns {boolean}
53
64
  */
54
- export function inCriticalCssConfig( assetKey ) {
55
- if(!globalThis.criticalConfig) {
65
+ export function inCriticalCssConfig(assetKey) {
66
+ if (!globalThis.criticalConfig) {
56
67
  return false;
57
68
  }
58
69
  if (
59
70
  globalThis.criticalConfig &&
60
- globalThis.criticalConfig.indexOf( assetKey ) === -1
71
+ globalThis.criticalConfig.indexOf(assetKey) === -1
61
72
  ) {
62
73
  return false;
63
74
  }
@@ -70,16 +81,16 @@ export function inCriticalCssConfig( assetKey ) {
70
81
  * @param {object} options The options object which will at the very least contain the css property set to true.
71
82
  * @returns {promise}
72
83
  */
73
- export function loadCss( assetKey, options = { css: true } ) {
74
- const promise = new Promise( ( resolve ) => {
75
- if ( options.css === true && ! inCriticalCssConfig( assetKey ) ) {
84
+ export function loadCss(assetKey, options = { css: true }) {
85
+ const promise = new Promise((resolve) => {
86
+ if (options.css === true && !inCriticalCssConfig(assetKey)) {
76
87
  import(
77
- /* webpackChunkName: "[request]" */ `Assets/scss/components/blocks/${ assetKey }.scss`
78
- ).then( () => resolve( true ) );
88
+ /* webpackChunkName: "[request]" */ `Assets/scss/components/blocks/${assetKey}.scss`
89
+ ).then(() => resolve(true));
79
90
  } else {
80
- return resolve( true );
91
+ return resolve(true);
81
92
  }
82
- } );
93
+ });
83
94
  return promise;
84
95
  }
85
96
 
@@ -89,104 +100,106 @@ export function loadCss( assetKey, options = { css: true } ) {
89
100
  export function checkDevice() {
90
101
  try {
91
102
  const deviceAgent = navigator.userAgent.toLowerCase();
92
- const htmlElement = document.querySelector( 'html' );
93
- if ( ( 'ontouchstart' in globalThis )&&( (window.screen.width * window.devicePixelRatio) >= 2048 ) && (window.screen.width<window.screen.height)) {
94
- htmlElement.classList.add( 'highResTabletPortrait' );
103
+ const htmlElement = document.querySelector('html');
104
+ if (
105
+ 'ontouchstart' in globalThis &&
106
+ window.screen.width * window.devicePixelRatio >= 2048 &&
107
+ window.screen.width < window.screen.height
108
+ ) {
109
+ htmlElement.classList.add('highResTabletPortrait');
95
110
  }
96
- if ( 'ontouchstart' in globalThis ) {
97
- htmlElement.classList.add( 'touch' );
111
+ if ('ontouchstart' in globalThis) {
112
+ htmlElement.classList.add('touch');
98
113
  }
99
- if ( navigator.connection ) {
100
- htmlElement.classList.add( navigator.connection.effectiveType );
114
+ if (navigator.connection) {
115
+ htmlElement.classList.add(navigator.connection.effectiveType);
101
116
  }
102
- if ( navigator.platform ) {
117
+ if (navigator.platform) {
103
118
  let platform = navigator.platform.toLowerCase();
104
119
  let platformArray = [platform];
105
- if ( platform.search('-') ) {
120
+ if (platform.search('-')) {
106
121
  platformArray = platform.split('-');
107
122
  }
108
- if ( platform.search(' ') ) {
123
+ if (platform.search(' ')) {
109
124
  platformArray = platform.split(' ');
110
125
  }
111
- htmlElement.classList.add( ...platformArray );
126
+ htmlElement.classList.add(...platformArray);
112
127
  }
113
- if ( deviceAgent.match( /(iphone|ipod|ipad)/ ) ) {
114
- htmlElement.classList.add( 'ios' );
115
- htmlElement.classList.add( 'mobile' );
128
+ if (deviceAgent.match(/(iphone|ipod|ipad)/)) {
129
+ htmlElement.classList.add('ios');
130
+ htmlElement.classList.add('mobile');
116
131
  }
117
- if (deviceAgent.match( /(windows)/ )) {
118
- htmlElement.classList.add( 'windows' );
132
+ if (deviceAgent.match(/(windows)/)) {
133
+ htmlElement.classList.add('windows');
119
134
  }
120
- if (deviceAgent.match( /(macintosh)/ )) {
121
- htmlElement.classList.add( 'mac' );
135
+ if (deviceAgent.match(/(macintosh)/)) {
136
+ htmlElement.classList.add('mac');
122
137
  }
123
- if (deviceAgent.match( /(android)/ )) {
124
- htmlElement.classList.add( 'android' );
138
+ if (deviceAgent.match(/(android)/)) {
139
+ htmlElement.classList.add('android');
125
140
  }
126
- if ( navigator.userAgent.search( 'MSIE' ) >= 0 ) {
127
- htmlElement.classList.add( 'ie' );
128
- } else if ( navigator.userAgent.search( 'Edge' ) >= 0 ) {
129
- htmlElement.classList.add( 'edge-legacy' );
130
- } else if ( navigator.userAgent.search( 'Chrome' ) >= 0 ) {
131
- htmlElement.classList.add( 'chrome' );
132
- } else if ( navigator.userAgent.search( 'Firefox' ) >= 0 ) {
133
- htmlElement.classList.add( 'firefox' );
141
+ if (navigator.userAgent.search('MSIE') >= 0) {
142
+ htmlElement.classList.add('ie');
143
+ } else if (navigator.userAgent.search('Edge') >= 0) {
144
+ htmlElement.classList.add('edge-legacy');
145
+ } else if (navigator.userAgent.search('Chrome') >= 0) {
146
+ htmlElement.classList.add('chrome');
147
+ } else if (navigator.userAgent.search('Firefox') >= 0) {
148
+ htmlElement.classList.add('firefox');
134
149
  } else if (
135
- navigator.userAgent.search( 'Safari' ) >= 0 &&
136
- navigator.userAgent.search( 'Chrome' ) < 0
150
+ navigator.userAgent.search('Safari') >= 0 &&
151
+ navigator.userAgent.search('Chrome') < 0
137
152
  ) {
138
- htmlElement.classList.add( 'safari' );
139
- } else if ( navigator.userAgent.search( 'Opera' ) >= 0 ) {
140
- htmlElement.classList.add( 'opera' );
153
+ htmlElement.classList.add('safari');
154
+ } else if (navigator.userAgent.search('Opera') >= 0) {
155
+ htmlElement.classList.add('opera');
141
156
  }
142
157
  } catch (error) {
143
- console.error(error)
158
+ console.error(error);
144
159
  }
145
160
  }
146
161
 
147
162
  /**
148
- * Check and possibly wait for an image to have downloaded before running an optional function.
163
+ * Check and possibly wait for an image to have downloaded before running an optional function.
149
164
  * Returns a resolved promise when the load event has fired.
150
165
  * @param {htmlElement} img The image element you want to wait for.
151
- * @param {function} delayedFunction The optional function you want to run when/if the image has downloaded.
166
+ * @param {function} delayedFunction The optional function you want to run when/if the image has downloaded.
152
167
  * @returns {promise}
153
168
  */
154
- export async function waitForLoad( img, delayedFunction ) {
155
- const loaded = new Promise( ( resolve ) => {
156
- if ( img.complete ) {
157
- if ( typeof delayedFunction === 'function' ) {
169
+ export async function waitForLoad(img, delayedFunction) {
170
+ const loaded = new Promise((resolve) => {
171
+ if (img.complete) {
172
+ if (typeof delayedFunction === 'function') {
158
173
  delayedFunction();
159
174
  }
160
- return resolve( true );
175
+ return resolve(true);
161
176
  }
162
177
  img.addEventListener(
163
178
  'load',
164
179
  () => {
165
- if ( typeof delayedFunction === 'function' ) {
180
+ if (typeof delayedFunction === 'function') {
166
181
  delayedFunction();
167
182
  }
168
- return resolve( true );
183
+ return resolve(true);
169
184
  },
170
185
  { once: true }
171
186
  );
172
- } ).catch( ( error ) =>
173
- console.log( error, 'could not load the image', img )
174
- );
187
+ }).catch((error) => console.log(error, 'could not load the image', img));
175
188
  return loaded;
176
189
  }
177
190
 
178
191
  /**
179
- * Check whether the current environment supports the webp image format.
180
- * Returns true if it does.
192
+ * Check whether the current environment supports the webp image format.
193
+ * Returns true if it does.
181
194
  * @returns {boolean}
182
195
  */
183
196
  export async function supportsWebp() {
184
197
  // eslint-disable-next-line no-restricted-globals
185
- if ( ! self.createImageBitmap ) return false;
198
+ if (!self.createImageBitmap) return false;
186
199
  const webpData =
187
200
  'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
188
- const blob = await fetch( webpData ).then( ( r ) => r.blob() );
189
- return createImageBitmap( blob ).then(
201
+ const blob = await fetch(webpData).then((r) => r.blob());
202
+ return createImageBitmap(blob).then(
190
203
  () => true,
191
204
  () => false
192
205
  );
@@ -199,30 +212,28 @@ export async function supportsWebp() {
199
212
  // } )();
200
213
 
201
214
  /**
202
- * DEPRECATED!! footerIntersection will be removed in a future version.
215
+ * DEPRECATED!! footerIntersection will be removed in a future version.
203
216
  */
204
- export function footerIntersection( entries, element ) {
205
- entries.forEach( ( entry ) => {
206
- if ( element ) {
207
- if ( entry.isIntersecting ) {
217
+ export function footerIntersection(entries, element) {
218
+ entries.forEach((entry) => {
219
+ if (element) {
220
+ if (entry.isIntersecting) {
208
221
  const { height } = entry.boundingClientRect;
209
- element.style.bottom = `${ height }px`;
222
+ element.style.bottom = `${height}px`;
210
223
  } else {
211
224
  element.style.bottom = '0px';
212
225
  }
213
226
  }
214
- } );
227
+ });
215
228
  }
216
229
 
217
230
  /**
218
- * Dynamically retrieves the swiper css and js and returns a resolved promise when they have both been successfully fetched.
231
+ * Dynamically retrieves the swiper css and js and returns a resolved promise when they have both been successfully fetched.
219
232
  * @returns {promise}
220
233
  */
221
234
  export function getSwiperAssets() {
222
235
  const getSwiperJs = () =>
223
- import(
224
- /* webpackChunkName: 'swiper' */ '../../swiper/swiper-bundle.js'
225
- );
236
+ import(/* webpackChunkName: 'swiper' */ '../../swiper/swiper-bundle.js');
226
237
 
227
238
  const getSwiperCss = () =>
228
239
  import(
@@ -230,8 +241,8 @@ export function getSwiperAssets() {
230
241
  '../../swiper/swiper-bundle.min.css'
231
242
  );
232
243
 
233
- const promisedJs = Promise.all( [ getSwiperJs(), getSwiperCss() ] ).then(
234
- ( values ) => {
244
+ const promisedJs = Promise.all([getSwiperJs(), getSwiperCss()]).then(
245
+ (values) => {
235
246
  return values;
236
247
  }
237
248
  );
@@ -239,11 +250,11 @@ export function getSwiperAssets() {
239
250
  }
240
251
 
241
252
  /**
242
- * Dynamically retrieves the jQuery and returns a resolved promise when it has been successfully fetched.
253
+ * Dynamically retrieves the jQuery and returns a resolved promise when it has been successfully fetched.
243
254
  * @returns {promise}
244
255
  */
245
256
  export function getJquery() {
246
- if ( ! window.jQuery ) {
257
+ if (!window.jQuery) {
247
258
  const importCode = () =>
248
259
  import(
249
260
  /* webpackChunkName: 'jquery' */ '../../jquery/dist/jquery.min.js'
@@ -254,29 +265,25 @@ export function getJquery() {
254
265
  }
255
266
 
256
267
  /**
257
- * Dynamically retrieves GSAP and the scrolltrigger plugin and returns a resolved promise when they have both been successfully fetched.
268
+ * Dynamically retrieves GSAP and the scrolltrigger plugin and returns a resolved promise when they have both been successfully fetched.
258
269
  * @returns {promise}
259
270
  */
260
271
  export function getGsap() {
261
272
  const gsapCore = () =>
262
- import( '../../gsap/dist/gsap.min.js' ).then( ( gsapObj ) => {
273
+ import('../../gsap/dist/gsap.min.js').then((gsapObj) => {
263
274
  const { gsap } = gsapObj;
264
275
  return gsap;
265
- } );
276
+ });
266
277
 
267
278
  const gsapPlugin = () =>
268
- import( '../../gsap/dist/ScrollTrigger.min.js' ).then(
269
- ( scrollObj ) => {
270
- const ScrollTrigger = scrollObj;
271
- return ScrollTrigger;
272
- }
273
- );
274
-
275
- const prom = Promise.all( [ gsapCore(), gsapPlugin() ] ).then(
276
- ( values ) => {
277
- return values;
278
- }
279
- );
279
+ import('../../gsap/dist/ScrollTrigger.min.js').then((scrollObj) => {
280
+ const ScrollTrigger = scrollObj;
281
+ return ScrollTrigger;
282
+ });
283
+
284
+ const prom = Promise.all([gsapCore(), gsapPlugin()]).then((values) => {
285
+ return values;
286
+ });
280
287
  return prom;
281
288
  }
282
289
 
@@ -285,7 +292,7 @@ export function getGsap() {
285
292
  * @param {*} userAgent Pass the value of navigator.userAgent.
286
293
  * @returns {boolean}
287
294
  */
288
- export function isTablet( userAgent ) {
295
+ export function isTablet(userAgent) {
289
296
  return /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(
290
297
  userAgent.toLowerCase()
291
298
  );
@@ -293,35 +300,45 @@ export function isTablet( userAgent ) {
293
300
 
294
301
  /**
295
302
  * Returns true if the device is a mobile device. Checks navigator.userAgent||navigator.vendor||window.opera.
296
- * @returns {boolean}
303
+ * @returns {boolean}
297
304
  */
298
- export function mobileCheck () {
305
+ export function mobileCheck() {
299
306
  let check = false;
300
- (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
307
+ (function (a) {
308
+ if (
309
+ /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
310
+ a
311
+ ) ||
312
+ /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
313
+ a.substr(0, 4)
314
+ )
315
+ )
316
+ check = true;
317
+ })(navigator.userAgent || navigator.vendor || window.opera);
301
318
  return check;
302
- };
319
+ }
303
320
 
304
321
  /**
305
- * Run a function after a window resize event, but only after the alloted time has ended.
322
+ * Run a function after a window resize event, but only after the alloted time has ended.
306
323
  * If another resize even occurs it resets the time window.
307
324
  * @param {function} debouncedFunction The function you want to run after a window resize event.
308
325
  * @param {number} time The time in ms.
309
- */
310
- export function resizeDebouncer( debouncedFunction, time = 250 ) {
326
+ */
327
+ export function resizeDebouncer(debouncedFunction, time = 250) {
311
328
  let resizeTimer;
312
- window.addEventListener( 'resize', () => {
313
- clearTimeout( resizeTimer );
314
- resizeTimer = setTimeout( () => {
329
+ window.addEventListener('resize', () => {
330
+ clearTimeout(resizeTimer);
331
+ resizeTimer = setTimeout(() => {
315
332
  debouncedFunction();
316
- }, time );
317
- } );
333
+ }, time);
334
+ });
318
335
  }
319
336
 
320
337
  /**
321
- * General purpose utility for running a function after a particular event fires on a specified element. The function only fires after the alloted time has ended.
338
+ * General purpose utility for running a function after a particular event fires on a specified element. The function only fires after the alloted time has ended.
322
339
  * If another resize even occurs it resets the time window.
323
340
  * @param {htmlElement} element The element that emits the event.
324
- * @param {string} eventType The type of event to listen for.
341
+ * @param {string} eventType The type of event to listen for.
325
342
  * @param {function} debouncedFunction The function to run after the event.
326
343
  * @param {number} time The time in ms.
327
344
  */
@@ -332,49 +349,49 @@ export function eventListenerDebouncer(
332
349
  time = 250
333
350
  ) {
334
351
  let timer;
335
- element.addEventListener( eventType, ( event ) => {
336
- clearTimeout( timer );
337
- timer = setTimeout( () => {
338
- debouncedFunction( event );
339
- }, time );
340
- } );
352
+ element.addEventListener(eventType, (event) => {
353
+ clearTimeout(timer);
354
+ timer = setTimeout(() => {
355
+ debouncedFunction(event);
356
+ }, time);
357
+ });
341
358
  }
342
359
 
343
360
  /**
344
361
  * Injects the youtube iframe api script and waits for the YT object to be instantiated before resolving the promise
345
- * @returns {promise} Resolves once the YT object is available.
362
+ * @returns {promise} Resolves once the YT object is available.
346
363
  */
347
364
  export function injectYouTubeIframeScript() {
348
- const prom = new Promise( ( resolve ) => {
349
- if ( globalThis.YT ) {
365
+ const prom = new Promise((resolve) => {
366
+ if (globalThis.YT) {
350
367
  return resolve();
351
368
  }
352
- const tag = document.createElement( 'script' );
369
+ const tag = document.createElement('script');
353
370
  tag.id = 'iframe-api';
354
371
  tag.src = 'https://www.youtube.com/iframe_api';
355
372
 
356
- const firstScriptTag = document.getElementsByTagName( 'script' )[ 0 ];
357
- firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
373
+ const firstScriptTag = document.getElementsByTagName('script')[0];
374
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
358
375
 
359
- tag.addEventListener( 'load', () => {
376
+ tag.addEventListener('load', () => {
360
377
  if (!YT.loaded) {
361
378
  const loadingCheck = setInterval(() => {
362
379
  if (YT.loaded) {
363
380
  clearInterval(loadingCheck);
364
- return resolve( true );
381
+ return resolve(true);
365
382
  }
366
383
  }, 50);
367
384
  } else {
368
- return resolve( true );
385
+ return resolve(true);
369
386
  }
370
- } );
371
- } );
387
+ });
388
+ });
372
389
 
373
390
  return prom;
374
391
  }
375
392
 
376
- export function fallbackCopyToClipboard( text ) {
377
- const textArea = document.createElement( 'textarea' );
393
+ export function fallbackCopyToClipboard(text) {
394
+ const textArea = document.createElement('textarea');
378
395
  textArea.value = text;
379
396
 
380
397
  // Avoid scrolling to bottom
@@ -382,58 +399,55 @@ export function fallbackCopyToClipboard( text ) {
382
399
  textArea.style.left = '0';
383
400
  textArea.style.position = 'fixed';
384
401
 
385
- document.body.appendChild( textArea );
402
+ document.body.appendChild(textArea);
386
403
  textArea.focus();
387
404
  textArea.select();
388
405
 
389
406
  try {
390
- const successful = document.execCommand( 'copy' );
407
+ const successful = document.execCommand('copy');
391
408
  const msg = successful ? 'successful' : 'unsuccessful';
392
- console.log( `Fallback: Copying text command was ${ msg }` );
393
- } catch ( err ) {
394
- console.error( 'Fallback: Oops, unable to copy', err );
409
+ console.log(`Fallback: Copying text command was ${msg}`);
410
+ } catch (err) {
411
+ console.error('Fallback: Oops, unable to copy', err);
395
412
  }
396
413
 
397
- document.body.removeChild( textArea );
414
+ document.body.removeChild(textArea);
398
415
  }
399
416
 
400
-
401
417
  export function copyToClipboard() {
402
- const copyLinks = document.querySelectorAll( '.copy-to-clipboard' );
418
+ const copyLinks = document.querySelectorAll('.copy-to-clipboard');
403
419
  let timeout;
404
- copyLinks.forEach( ( link ) => {
405
- link.addEventListener( 'click', function () {
420
+ copyLinks.forEach((link) => {
421
+ link.addEventListener('click', function () {
406
422
  const copyToClipboardDone = link.nextElementSibling;
407
- if ( ! navigator.clipboard ) {
408
- fallbackCopyToClipboard( this.dataset.url );
423
+ if (!navigator.clipboard) {
424
+ fallbackCopyToClipboard(this.dataset.url);
409
425
  return;
410
426
  }
411
427
 
412
- navigator.clipboard.writeText( this.dataset.url ).then(
428
+ navigator.clipboard.writeText(this.dataset.url).then(
413
429
  function () {
414
- console.log( 'Copying to clipboard was successful!' );
430
+ console.log('Copying to clipboard was successful!');
415
431
  },
416
- function ( err ) {
417
- console.error( 'Could not copy text: ', err );
432
+ function (err) {
433
+ console.error('Could not copy text: ', err);
418
434
  }
419
435
  );
420
436
 
421
437
  if (
422
438
  copyToClipboardDone &&
423
439
  copyToClipboardDone.classList &&
424
- copyToClipboardDone.classList.contains(
425
- 'sharing__clipboard-done'
426
- )
440
+ copyToClipboardDone.classList.contains('sharing__clipboard-done')
427
441
  ) {
428
- clearTimeout( timeout );
429
- copyToClipboardDone.classList.remove( 'hidden' );
442
+ clearTimeout(timeout);
443
+ copyToClipboardDone.classList.remove('hidden');
430
444
 
431
- timeout = setTimeout( () => {
432
- copyToClipboardDone.classList.add( 'hidden' );
433
- }, 2000 );
445
+ timeout = setTimeout(() => {
446
+ copyToClipboardDone.classList.add('hidden');
447
+ }, 2000);
434
448
  }
435
- } );
436
- } );
449
+ });
450
+ });
437
451
  }
438
452
 
439
453
  /**
@@ -442,21 +456,25 @@ export function copyToClipboard() {
442
456
  * @returns {boolean} True if visible and false if not.
443
457
  */
444
458
  export function isInViewport(element) {
445
- const position = element.getBoundingClientRect();
446
- return ( position.top >= 0 && position.bottom <= window.innerHeight ) || ( position.top < window.innerHeight && position.bottom >= 0 );
459
+ const position = element.getBoundingClientRect();
460
+ return (
461
+ (position.top >= 0 && position.bottom <= window.innerHeight) ||
462
+ (position.top < window.innerHeight && position.bottom >= 0)
463
+ );
447
464
  }
448
465
 
449
466
  /* eslint-disable-next-line */
450
- const emailRegex = /^[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~](\.?[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~])*@[a-zA-Z0-9](-*\.?[a-zA-Z0-9])*\.[a-zA-Z](-?[a-zA-Z0-9])+$/;
467
+ const emailRegex =
468
+ /^[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~](\.?[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~])*@[a-zA-Z0-9](-*\.?[a-zA-Z0-9])*\.[a-zA-Z](-?[a-zA-Z0-9])+$/;
451
469
 
452
470
  /**
453
471
  * Checks to make sure a passed string has a valid email address structure and characters.
454
472
  * @param {RegExp} email - The email address as a string.
455
473
  * @returns {boolean} True if valid and false if not.
456
474
  */
457
- export function isEmailValid( email ) {
458
- return emailRegex.test( email );
459
- };
475
+ export function isEmailValid(email) {
476
+ return emailRegex.test(email);
477
+ }
460
478
 
461
479
  /**
462
480
  * Get the value of a css property on a specific element.
@@ -526,9 +544,7 @@ export function detectSwipe(element, callback, removeHandlers = false) {
526
544
  function (event) {
527
545
  touchendX = event.changedTouches[0].screenX;
528
546
  touchendY = event.changedTouches[0].screenY;
529
- callback(
530
- handleGesture(touchstartX, touchstartY, touchendX, touchendY)
531
- );
547
+ callback(handleGesture(touchstartX, touchstartY, touchendX, touchendY));
532
548
  },
533
549
  false
534
550
  );
@@ -541,7 +557,7 @@ export function detectSwipe(element, callback, removeHandlers = false) {
541
557
 
542
558
  /**
543
559
  * Function for getting the ios operating system version
544
- *
560
+ *
545
561
  * @returns {number} the ios version
546
562
  */
547
563
  export function checkIosVersion() {
@@ -556,6 +572,27 @@ export function checkIosVersion() {
556
572
  return 0;
557
573
  }
558
574
 
575
+ /**
576
+ * Function for adding a link tag with preconnect to the head of the document. Very useful if you need to add this dynamically.
577
+ * @param {string} domain The domain you wish to preconnect to.
578
+ * @returns {void} The preconnect will be appended to the head tag.
579
+ */
580
+ export function appendPreconnect(domain) {
581
+ try {
582
+ if (!domain) {
583
+ console.log('The domain was missing or broken...');
584
+ return;
585
+ }
586
+ const link = document.createElement('link');
587
+ link.rel = 'preconnect';
588
+ link.href = domain;
589
+ document.head.appendChild(link);
590
+ return;
591
+ } catch (error) {
592
+ console.error(error);
593
+ }
594
+ }
595
+
559
596
  const api = {
560
597
  copyToClipboard,
561
598
  checkDevice,
@@ -579,6 +616,7 @@ const api = {
579
616
  waitForLoad,
580
617
  getElementStyles,
581
618
  getPercent,
582
- checkIosVersion
619
+ checkIosVersion,
620
+ appendPreconnect
583
621
  };
584
622
  export default api;
package/package.json CHANGED
@@ -1,29 +1,30 @@
1
1
  {
2
- "name": "@pernod-ricard-global-cms/jsutils",
3
- "version": "1.6.4",
4
- "description": "Handy collection of Javascript utility functions",
5
- "type": "module",
6
- "main": "jsutils.js",
7
- "scripts": {
8
- "test": "jasmine"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/Chivas-Brothers/jsUtils.git"
13
- },
14
- "author": "",
15
- "license": "ISC",
16
- "bugs": {
17
- "url": "https://github.com/Chivas-Brothers/jsUtils/issues"
18
- },
19
- "homepage": "https://github.com/Chivas-Brothers/jsUtils#readme",
20
- "dependencies": {
21
- "gsap": "^3.7.1",
22
- "jquery": "^3.6.0",
23
- "swiper": "^6.8.3"
24
- },
25
- "devDependencies": {
26
- "jasmine": "^3.9.0",
27
- "jsdoc": "^3.6.7"
28
- }
2
+ "name": "@pernod-ricard-global-cms/jsutils",
3
+ "version": "1.7.1",
4
+ "description": "Handy collection of Javascript utility functions",
5
+ "type": "module",
6
+ "main": "jsutils.js",
7
+ "scripts": {
8
+ "test": "jasmine"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/Chivas-Brothers/jsUtils.git"
13
+ },
14
+ "author": "",
15
+ "license": "ISC",
16
+ "bugs": {
17
+ "url": "https://github.com/Chivas-Brothers/jsUtils/issues"
18
+ },
19
+ "homepage": "https://github.com/Chivas-Brothers/jsUtils#readme",
20
+ "dependencies": {
21
+ "gsap": "^3.7.1",
22
+ "jquery": "^3.6.0",
23
+ "prettier": "^2.5.1",
24
+ "swiper": "^6.8.3"
25
+ },
26
+ "devDependencies": {
27
+ "jasmine": "^3.9.0",
28
+ "jsdoc": "^3.6.7"
29
+ }
29
30
  }