@pernod-ricard-global-cms/jsutils 2.0.0 → 2.1.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.
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "Using fixtures to represent data",
3
+ "email": "hello@cypress.io",
4
+ "body": "Fixtures are a great way to mock data for responses to routes"
5
+ }
@@ -0,0 +1,13 @@
1
+ import { getPercent } from '../../jsutils';
2
+
3
+ describe('A suite to test getPercent()', () => {
4
+ it('passes by rounding down', () => {
5
+ expect(getPercent(30, 10)).to.eq(33);
6
+ });
7
+ it('passes with various numbers', () => {
8
+ expect(getPercent(100, 10)).to.eq(10);
9
+ });
10
+ it('passes by rounding up', () => {
11
+ expect(getPercent(30, 20)).to.eq(67);
12
+ });
13
+ });
@@ -0,0 +1,22 @@
1
+ import jsutils from '../../jsutils';
2
+
3
+ describe('A suite', () => {
4
+ it('passes with mixed case letters and numbers', () => {
5
+ expect(jsutils.isEmailValid('aS93scFFx@jKoO0908ahdb.com')).to.eq(true);
6
+ });
7
+ it('fails on a string of letters', () => {
8
+ expect(jsutils.isEmailValid('jkahdb')).to.eq(false);
9
+ });
10
+ it('fails with mixed case letters and numbers and no @', () => {
11
+ expect(jsutils.isEmailValid('aS93scFFxjKoO0908ahdb.com')).to.eq(false);
12
+ });
13
+ it('fails with a space in the string', () => {
14
+ expect(jsutils.isEmailValid('hello@te st.com')).to.eq(false);
15
+ });
16
+ it('fails with a £ symbol', () => {
17
+ expect(jsutils.isEmailValid('hello@te£st.com')).to.eq(false);
18
+ });
19
+ it('fails with a § symbol', () => {
20
+ expect(jsutils.isEmailValid('hello@te£st.com')).to.eq(false);
21
+ });
22
+ });
@@ -0,0 +1,22 @@
1
+ /// <reference types="cypress" />
2
+ // ***********************************************************
3
+ // This example plugins/index.js can be used to load plugins
4
+ //
5
+ // You can change the location of this file or turn off loading
6
+ // the plugins file with the 'pluginsFile' configuration option.
7
+ //
8
+ // You can read more here:
9
+ // https://on.cypress.io/plugins-guide
10
+ // ***********************************************************
11
+
12
+ // This function is called when a project is opened or re-opened (e.g. due to
13
+ // the project's config changing)
14
+
15
+ /**
16
+ * @type {Cypress.PluginConfig}
17
+ */
18
+ // eslint-disable-next-line no-unused-vars
19
+ module.exports = (on, config) => {
20
+ // `on` is used to hook into various events Cypress emits
21
+ // `config` is the resolved Cypress config
22
+ }
@@ -0,0 +1,25 @@
1
+ // ***********************************************
2
+ // This example commands.js shows you how to
3
+ // create various custom commands and overwrite
4
+ // existing commands.
5
+ //
6
+ // For more comprehensive examples of custom
7
+ // commands please read more here:
8
+ // https://on.cypress.io/custom-commands
9
+ // ***********************************************
10
+ //
11
+ //
12
+ // -- This is a parent command --
13
+ // Cypress.Commands.add('login', (email, password) => { ... })
14
+ //
15
+ //
16
+ // -- This is a child command --
17
+ // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
18
+ //
19
+ //
20
+ // -- This is a dual command --
21
+ // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
22
+ //
23
+ //
24
+ // -- This will overwrite an existing command --
25
+ // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
@@ -0,0 +1,20 @@
1
+ // ***********************************************************
2
+ // This example support/index.js is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands'
18
+
19
+ // Alternatively you can use CommonJS syntax:
20
+ // require('./commands')
package/cypress.json ADDED
@@ -0,0 +1 @@
1
+ {}
@@ -6,7 +6,7 @@
6
6
  * @returns {Boolean}
7
7
  */
8
8
  export function isWpAdmin() {
9
- return document.body.classList.contains('wp-admin') ? true : false;
9
+ return document.body.classList.contains("wp-admin") ? true : false;
10
10
  }
11
11
 
12
12
  /**
@@ -25,8 +25,8 @@ export function getPosition(element) {
25
25
  element = element.offsetParent;
26
26
  }
27
27
  // Quirks mode safety - in case of missing DOCTYPE
28
- if (scrollElementTag === 'BODY') {
29
- yPosition += document.querySelector('body').scrollTop;
28
+ if (scrollElementTag === "BODY") {
29
+ yPosition += document.querySelector("body").scrollTop;
30
30
  }
31
31
  return { x: xPosition, y: yPosition };
32
32
  }
@@ -38,21 +38,21 @@ export function getPosition(element) {
38
38
  */
39
39
  export function toggleClassByValidity(input, button) {
40
40
  try {
41
- input.addEventListener('input', () => {
41
+ input.addEventListener("input", () => {
42
42
  if (input.validity.valid && input.value) {
43
- if (!button.classList.contains('valid')) {
44
- button.classList.add('valid');
43
+ if (!button.classList.contains("valid")) {
44
+ button.classList.add("valid");
45
45
  }
46
- if (!input.classList.contains('valid')) {
47
- input.classList.add('valid');
46
+ if (!input.classList.contains("valid")) {
47
+ input.classList.add("valid");
48
48
  }
49
49
  } else {
50
- button.classList.remove('valid');
51
- input.classList.remove('valid');
50
+ button.classList.remove("valid");
51
+ input.classList.remove("valid");
52
52
  }
53
53
  });
54
54
  } catch (error) {
55
- console.error('jsutils.js ~ toggleClassByValidity ~ error', error);
55
+ console.error("jsutils.js ~ toggleClassByValidity ~ error", error);
56
56
  }
57
57
  }
58
58
 
@@ -100,16 +100,16 @@ export function loadCss(assetKey, options = { css: true }) {
100
100
  export function checkDevice() {
101
101
  try {
102
102
  const deviceAgent = navigator.userAgent.toLowerCase();
103
- const htmlElement = document.querySelector('html');
103
+ const htmlElement = document.querySelector("html");
104
104
  if (
105
- 'ontouchstart' in globalThis &&
105
+ "ontouchstart" in globalThis &&
106
106
  window.screen.width * window.devicePixelRatio >= 2048 &&
107
107
  window.screen.width < window.screen.height
108
108
  ) {
109
- htmlElement.classList.add('highResTabletPortrait');
109
+ htmlElement.classList.add("highResTabletPortrait");
110
110
  }
111
- if ('ontouchstart' in globalThis) {
112
- htmlElement.classList.add('touch');
111
+ if ("ontouchstart" in globalThis) {
112
+ htmlElement.classList.add("touch");
113
113
  }
114
114
  if (navigator.connection) {
115
115
  htmlElement.classList.add(navigator.connection.effectiveType);
@@ -117,42 +117,42 @@ export function checkDevice() {
117
117
  if (navigator.platform) {
118
118
  let platform = navigator.platform.toLowerCase();
119
119
  let platformArray = [platform];
120
- if (platform.search('-')) {
121
- platformArray = platform.split('-');
120
+ if (platform.search("-")) {
121
+ platformArray = platform.split("-");
122
122
  }
123
- if (platform.search(' ')) {
124
- platformArray = platform.split(' ');
123
+ if (platform.search(" ")) {
124
+ platformArray = platform.split(" ");
125
125
  }
126
126
  htmlElement.classList.add(...platformArray);
127
127
  }
128
128
  if (deviceAgent.match(/(iphone|ipod|ipad)/)) {
129
- htmlElement.classList.add('ios');
130
- htmlElement.classList.add('mobile');
129
+ htmlElement.classList.add("ios");
130
+ htmlElement.classList.add("mobile");
131
131
  }
132
132
  if (deviceAgent.match(/(windows)/)) {
133
- htmlElement.classList.add('windows');
133
+ htmlElement.classList.add("windows");
134
134
  }
135
135
  if (deviceAgent.match(/(macintosh)/)) {
136
- htmlElement.classList.add('mac');
136
+ htmlElement.classList.add("mac");
137
137
  }
138
138
  if (deviceAgent.match(/(android)/)) {
139
- htmlElement.classList.add('android');
139
+ htmlElement.classList.add("android");
140
140
  }
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');
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");
149
149
  } else if (
150
- navigator.userAgent.search('Safari') >= 0 &&
151
- navigator.userAgent.search('Chrome') < 0
150
+ navigator.userAgent.search("Safari") >= 0 &&
151
+ navigator.userAgent.search("Chrome") < 0
152
152
  ) {
153
- htmlElement.classList.add('safari');
154
- } else if (navigator.userAgent.search('Opera') >= 0) {
155
- htmlElement.classList.add('opera');
153
+ htmlElement.classList.add("safari");
154
+ } else if (navigator.userAgent.search("Opera") >= 0) {
155
+ htmlElement.classList.add("opera");
156
156
  }
157
157
  } catch (error) {
158
158
  console.error(error);
@@ -169,22 +169,22 @@ export function checkDevice() {
169
169
  export async function waitForLoad(img, delayedFunction) {
170
170
  const loaded = new Promise((resolve) => {
171
171
  if (img.complete) {
172
- if (typeof delayedFunction === 'function') {
172
+ if (typeof delayedFunction === "function") {
173
173
  delayedFunction();
174
174
  }
175
175
  return resolve(true);
176
176
  }
177
177
  img.addEventListener(
178
- 'load',
178
+ "load",
179
179
  () => {
180
- if (typeof delayedFunction === 'function') {
180
+ if (typeof delayedFunction === "function") {
181
181
  delayedFunction();
182
182
  }
183
183
  return resolve(true);
184
184
  },
185
185
  { once: true }
186
186
  );
187
- }).catch((error) => console.log(error, 'could not load the image', img));
187
+ }).catch((error) => console.log(error, "could not load the image", img));
188
188
  return loaded;
189
189
  }
190
190
 
@@ -197,7 +197,7 @@ export async function supportsWebp() {
197
197
  // eslint-disable-next-line no-restricted-globals
198
198
  if (!self.createImageBitmap) return false;
199
199
  const webpData =
200
- 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
200
+ "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=";
201
201
  const blob = await fetch(webpData).then((r) => r.blob());
202
202
  return createImageBitmap(blob).then(
203
203
  () => true,
@@ -221,7 +221,7 @@ export function footerIntersection(entries, element) {
221
221
  const { height } = entry.boundingClientRect;
222
222
  element.style.bottom = `${height}px`;
223
223
  } else {
224
- element.style.bottom = '0px';
224
+ element.style.bottom = "0px";
225
225
  }
226
226
  }
227
227
  });
@@ -231,9 +231,9 @@ export function footerIntersection(entries, element) {
231
231
  * Dynamically retrieves the swiper css and js and returns a resolved promise when they have both been successfully fetched.
232
232
  * @returns {promise}
233
233
  */
234
- export function getSwiperAssetsV2(options = { css: 'bundle' }) {
234
+ export function getSwiperAssetsV2(options = { css: "bundle" }) {
235
235
  const getSwiperJs = () =>
236
- import(/* webpackChunkName: 'swiper' */ 'NodeModules/swiper/swiper.esm');
236
+ import(/* webpackChunkName: 'swiper' */ "swiper/swiper.esm");
237
237
 
238
238
  const promisedJs = Promise.all([getSwiperJs()]).then((values) => {
239
239
  return values;
@@ -248,9 +248,7 @@ export function getSwiperAssetsV2(options = { css: 'bundle' }) {
248
248
  export function getJquery() {
249
249
  if (!window.jQuery) {
250
250
  const importCode = () =>
251
- import(
252
- /* webpackChunkName: 'jquery' */ '../../jquery/dist/jquery.min.js'
253
- );
251
+ import(/* webpackChunkName: 'jquery' */ "jquery/dist/jquery.min.js");
254
252
  return importCode();
255
253
  }
256
254
  return Promise.resolve();
@@ -262,13 +260,13 @@ export function getJquery() {
262
260
  */
263
261
  export function getGsap() {
264
262
  const gsapCore = () =>
265
- import('../../gsap/dist/gsap.min.js').then((gsapObj) => {
263
+ import("gsap/dist/gsap.min.js").then((gsapObj) => {
266
264
  const { gsap } = gsapObj;
267
265
  return gsap;
268
266
  });
269
267
 
270
268
  const gsapPlugin = () =>
271
- import('../../gsap/dist/ScrollTrigger.min.js').then((scrollObj) => {
269
+ import("gsap/dist/ScrollTrigger.min.js").then((scrollObj) => {
272
270
  const ScrollTrigger = scrollObj;
273
271
  return ScrollTrigger;
274
272
  });
@@ -318,7 +316,7 @@ export function mobileCheck() {
318
316
  */
319
317
  export function resizeDebouncer(debouncedFunction, time = 250) {
320
318
  let resizeTimer;
321
- window.addEventListener('resize', () => {
319
+ window.addEventListener("resize", () => {
322
320
  clearTimeout(resizeTimer);
323
321
  resizeTimer = setTimeout(() => {
324
322
  debouncedFunction();
@@ -358,14 +356,14 @@ export function injectYouTubeIframeScript() {
358
356
  if (globalThis.YT) {
359
357
  return resolve();
360
358
  }
361
- const tag = document.createElement('script');
362
- tag.id = 'iframe-api';
363
- tag.src = 'https://www.youtube.com/iframe_api';
359
+ const tag = document.createElement("script");
360
+ tag.id = "iframe-api";
361
+ tag.src = "https://www.youtube.com/iframe_api";
364
362
 
365
- const firstScriptTag = document.getElementsByTagName('script')[0];
363
+ const firstScriptTag = document.getElementsByTagName("script")[0];
366
364
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
367
365
 
368
- tag.addEventListener('load', () => {
366
+ tag.addEventListener("load", () => {
369
367
  if (!YT.loaded) {
370
368
  const loadingCheck = setInterval(() => {
371
369
  if (YT.loaded) {
@@ -383,34 +381,34 @@ export function injectYouTubeIframeScript() {
383
381
  }
384
382
 
385
383
  export function fallbackCopyToClipboard(text) {
386
- const textArea = document.createElement('textarea');
384
+ const textArea = document.createElement("textarea");
387
385
  textArea.value = text;
388
386
 
389
387
  // Avoid scrolling to bottom
390
- textArea.style.top = '0';
391
- textArea.style.left = '0';
392
- textArea.style.position = 'fixed';
388
+ textArea.style.top = "0";
389
+ textArea.style.left = "0";
390
+ textArea.style.position = "fixed";
393
391
 
394
392
  document.body.appendChild(textArea);
395
393
  textArea.focus();
396
394
  textArea.select();
397
395
 
398
396
  try {
399
- const successful = document.execCommand('copy');
400
- const msg = successful ? 'successful' : 'unsuccessful';
397
+ const successful = document.execCommand("copy");
398
+ const msg = successful ? "successful" : "unsuccessful";
401
399
  console.log(`Fallback: Copying text command was ${msg}`);
402
400
  } catch (err) {
403
- console.error('Fallback: Oops, unable to copy', err);
401
+ console.error("Fallback: Oops, unable to copy", err);
404
402
  }
405
403
 
406
404
  document.body.removeChild(textArea);
407
405
  }
408
406
 
409
407
  export function copyToClipboard() {
410
- const copyLinks = document.querySelectorAll('.copy-to-clipboard');
408
+ const copyLinks = document.querySelectorAll(".copy-to-clipboard");
411
409
  let timeout;
412
410
  copyLinks.forEach((link) => {
413
- link.addEventListener('click', function () {
411
+ link.addEventListener("click", function () {
414
412
  const copyToClipboardDone = link.nextElementSibling;
415
413
  if (!navigator.clipboard) {
416
414
  fallbackCopyToClipboard(this.dataset.url);
@@ -419,23 +417,23 @@ export function copyToClipboard() {
419
417
 
420
418
  navigator.clipboard.writeText(this.dataset.url).then(
421
419
  function () {
422
- console.log('Copying to clipboard was successful!');
420
+ console.log("Copying to clipboard was successful!");
423
421
  },
424
422
  function (err) {
425
- console.error('Could not copy text: ', err);
423
+ console.error("Could not copy text: ", err);
426
424
  }
427
425
  );
428
426
 
429
427
  if (
430
428
  copyToClipboardDone &&
431
429
  copyToClipboardDone.classList &&
432
- copyToClipboardDone.classList.contains('sharing__clipboard-done')
430
+ copyToClipboardDone.classList.contains("sharing__clipboard-done")
433
431
  ) {
434
432
  clearTimeout(timeout);
435
- copyToClipboardDone.classList.remove('hidden');
433
+ copyToClipboardDone.classList.remove("hidden");
436
434
 
437
435
  timeout = setTimeout(() => {
438
- copyToClipboardDone.classList.add('hidden');
436
+ copyToClipboardDone.classList.add("hidden");
439
437
  }, 2000);
440
438
  }
441
439
  });
@@ -515,13 +513,13 @@ export function detectSwipe(element, callback, removeHandlers = false) {
515
513
 
516
514
  if (Math.abs(delx) > pixels || Math.abs(dely) > pixels) {
517
515
  if (Math.abs(delx) > Math.abs(dely)) {
518
- if (delx > 0) return 'right';
519
- else return 'left';
516
+ if (delx > 0) return "right";
517
+ else return "left";
520
518
  } else if (Math.abs(delx) < Math.abs(dely)) {
521
- if (dely > 0) return 'down';
522
- else return 'up';
519
+ if (dely > 0) return "down";
520
+ else return "up";
523
521
  }
524
- } else return 'tap';
522
+ } else return "tap";
525
523
  }
526
524
 
527
525
  function touchStart(event) {
@@ -529,10 +527,10 @@ export function detectSwipe(element, callback, removeHandlers = false) {
529
527
  touchstartY = event.changedTouches[0].screenY;
530
528
  }
531
529
 
532
- element.addEventListener('touchstart', () => touchStart(event), false);
530
+ element.addEventListener("touchstart", () => touchStart(event), false);
533
531
 
534
532
  element.addEventListener(
535
- 'touchend',
533
+ "touchend",
536
534
  function (event) {
537
535
  touchendX = event.changedTouches[0].screenX;
538
536
  touchendY = event.changedTouches[0].screenY;
@@ -540,9 +538,9 @@ export function detectSwipe(element, callback, removeHandlers = false) {
540
538
  },
541
539
  false
542
540
  );
543
- if (removeHandlers === 'remove') {
544
- element.removeEventListener('touchstart', touchStart);
545
- element.removeEventListener('touchend', handleGesture);
541
+ if (removeHandlers === "remove") {
542
+ element.removeEventListener("touchstart", touchStart);
543
+ element.removeEventListener("touchend", handleGesture);
546
544
  return;
547
545
  }
548
546
  }
@@ -554,12 +552,12 @@ export function detectSwipe(element, callback, removeHandlers = false) {
554
552
  */
555
553
  export function checkIosVersion() {
556
554
  const agent = window.navigator.userAgent,
557
- start = agent.indexOf('OS ');
555
+ start = agent.indexOf("OS ");
558
556
  if (
559
- (agent.indexOf('iPhone') > -1 || agent.indexOf('iPad') > -1) &&
557
+ (agent.indexOf("iPhone") > -1 || agent.indexOf("iPad") > -1) &&
560
558
  start > -1
561
559
  ) {
562
- return window.Number(agent.substr(start + 3, 3).replace('_', '.'));
560
+ return window.Number(agent.substr(start + 3, 3).replace("_", "."));
563
561
  }
564
562
  return 0;
565
563
  }
@@ -572,11 +570,11 @@ export function checkIosVersion() {
572
570
  export function appendPreconnect(domain) {
573
571
  try {
574
572
  if (!domain) {
575
- console.log('The domain was missing or broken...');
573
+ console.log("The domain was missing or broken...");
576
574
  return;
577
575
  }
578
- const link = document.createElement('link');
579
- link.rel = 'preconnect';
576
+ const link = document.createElement("link");
577
+ link.rel = "preconnect";
580
578
  link.href = domain;
581
579
  document.head.appendChild(link);
582
580
  return;
@@ -609,6 +607,6 @@ const api = {
609
607
  getElementStyles,
610
608
  getPercent,
611
609
  checkIosVersion,
612
- appendPreconnect
610
+ appendPreconnect,
613
611
  };
614
612
  export default api;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@pernod-ricard-global-cms/jsutils",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "Handy collection of Javascript utility functions",
5
- "type": "module",
6
- "main": "jsutils.js",
5
+ "type": "commonjs",
6
+ "main": "jsutils.mjs",
7
7
  "scripts": {
8
- "test": "jasmine"
8
+ "test": "cypress"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
@@ -18,13 +18,13 @@
18
18
  },
19
19
  "homepage": "https://github.com/Chivas-Brothers/jsUtils#readme",
20
20
  "dependencies": {
21
- "gsap": "^3.7.1",
21
+ "gsap": "^3.10.4",
22
22
  "jquery": "^3.6.0",
23
23
  "prettier": "^2.5.1",
24
24
  "swiper": "^8.1.4"
25
25
  },
26
26
  "devDependencies": {
27
- "jasmine": "^3.9.0",
27
+ "cypress": "^9.6.1",
28
28
  "jsdoc": "^3.6.7"
29
29
  }
30
30
  }
@@ -1,10 +0,0 @@
1
- import jsutils from "../jsutils.js";
2
-
3
- describe("A suite", function() {
4
- it("fails on a string of letters", function() {
5
- expect(jsutils.isEmailValid('jkahdb')).toBe(false);
6
- });
7
- it("passes with mixed case letters and numbers", function() {
8
- expect(jsutils.isEmailValid('aS93scFFx@jKoO0908ahdb.com')).toBe(true);
9
- });
10
- });
@@ -1,7 +0,0 @@
1
- import jsutils from "../jsutils.js";
2
-
3
- describe("A suite", function() {
4
- it("passes as element is in the viewport", function() {
5
-
6
- });
7
- });
@@ -1,12 +0,0 @@
1
- {
2
- "spec_dir": "spec",
3
- "spec_files": [
4
- "**/*[sS]pec.?(m)js"
5
- ],
6
- "helpers": [
7
- "helpers/**/*.?(m)js"
8
- ],
9
- "jsLoader": "import",
10
- "stopSpecOnExpectationFailure": false,
11
- "random": true
12
- }