@pernod-ricard-global-cms/jsutils 2.0.0 → 2.2.0
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.
- package/cypress/e2e/getPercent.cy.js +13 -0
- package/cypress/e2e/isEmailValid.cy.js +22 -0
- package/cypress/e2e/resizeDebouncer.cy.js +5 -0
- package/cypress/fixtures/example.json +5 -0
- package/cypress/plugins/index.js +22 -0
- package/cypress/support/commands.js +25 -0
- package/cypress/support/e2e.js +20 -0
- package/cypress.config.js +11 -0
- package/{jsutils.js → jsutils.mjs} +104 -93
- package/package.json +6 -6
- package/spec/isEmailValid.spec.js +0 -10
- package/spec/isInViewport.spec.js +0 -7
- package/spec/support/jasmine.json +0 -12
|
@@ -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')
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const { defineConfig } = require('cypress')
|
|
2
|
+
|
|
3
|
+
module.exports = defineConfig({
|
|
4
|
+
e2e: {
|
|
5
|
+
// We've imported your old cypress plugins here.
|
|
6
|
+
// You may want to clean this up later by importing these.
|
|
7
|
+
setupNodeEvents(on, config) {
|
|
8
|
+
return require('./cypress/plugins/index.js')(on, config)
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
})
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @returns {Boolean}
|
|
7
7
|
*/
|
|
8
8
|
export function isWpAdmin() {
|
|
9
|
-
return document.body.classList.contains(
|
|
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 ===
|
|
29
|
-
yPosition += document.querySelector(
|
|
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(
|
|
41
|
+
input.addEventListener("input", () => {
|
|
42
42
|
if (input.validity.valid && input.value) {
|
|
43
|
-
if (!button.classList.contains(
|
|
44
|
-
button.classList.add(
|
|
43
|
+
if (!button.classList.contains("valid")) {
|
|
44
|
+
button.classList.add("valid");
|
|
45
45
|
}
|
|
46
|
-
if (!input.classList.contains(
|
|
47
|
-
input.classList.add(
|
|
46
|
+
if (!input.classList.contains("valid")) {
|
|
47
|
+
input.classList.add("valid");
|
|
48
48
|
}
|
|
49
49
|
} else {
|
|
50
|
-
button.classList.remove(
|
|
51
|
-
input.classList.remove(
|
|
50
|
+
button.classList.remove("valid");
|
|
51
|
+
input.classList.remove("valid");
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
} catch (error) {
|
|
55
|
-
console.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(
|
|
103
|
+
const htmlElement = document.querySelector("html");
|
|
104
104
|
if (
|
|
105
|
-
|
|
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(
|
|
109
|
+
htmlElement.classList.add("highResTabletPortrait");
|
|
110
110
|
}
|
|
111
|
-
if (
|
|
112
|
-
htmlElement.classList.add(
|
|
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(
|
|
130
|
-
htmlElement.classList.add(
|
|
129
|
+
htmlElement.classList.add("ios");
|
|
130
|
+
htmlElement.classList.add("mobile");
|
|
131
131
|
}
|
|
132
132
|
if (deviceAgent.match(/(windows)/)) {
|
|
133
|
-
htmlElement.classList.add(
|
|
133
|
+
htmlElement.classList.add("windows");
|
|
134
134
|
}
|
|
135
135
|
if (deviceAgent.match(/(macintosh)/)) {
|
|
136
|
-
htmlElement.classList.add(
|
|
136
|
+
htmlElement.classList.add("mac");
|
|
137
137
|
}
|
|
138
138
|
if (deviceAgent.match(/(android)/)) {
|
|
139
|
-
htmlElement.classList.add(
|
|
139
|
+
htmlElement.classList.add("android");
|
|
140
140
|
}
|
|
141
|
-
if (navigator.userAgent.search(
|
|
142
|
-
htmlElement.classList.add(
|
|
143
|
-
} else if (navigator.userAgent.search(
|
|
144
|
-
htmlElement.classList.add(
|
|
145
|
-
} else if (navigator.userAgent.search(
|
|
146
|
-
htmlElement.classList.add(
|
|
147
|
-
} else if (navigator.userAgent.search(
|
|
148
|
-
htmlElement.classList.add(
|
|
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(
|
|
151
|
-
navigator.userAgent.search(
|
|
150
|
+
navigator.userAgent.search("Safari") >= 0 &&
|
|
151
|
+
navigator.userAgent.search("Chrome") < 0
|
|
152
152
|
) {
|
|
153
|
-
htmlElement.classList.add(
|
|
154
|
-
} else if (navigator.userAgent.search(
|
|
155
|
-
htmlElement.classList.add(
|
|
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 ===
|
|
172
|
+
if (typeof delayedFunction === "function") {
|
|
173
173
|
delayedFunction();
|
|
174
174
|
}
|
|
175
175
|
return resolve(true);
|
|
176
176
|
}
|
|
177
177
|
img.addEventListener(
|
|
178
|
-
|
|
178
|
+
"load",
|
|
179
179
|
() => {
|
|
180
|
-
if (typeof delayedFunction ===
|
|
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,
|
|
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
|
-
|
|
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 =
|
|
224
|
+
element.style.bottom = "0px";
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
});
|
|
@@ -231,9 +231,8 @@ 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:
|
|
235
|
-
const getSwiperJs = () =>
|
|
236
|
-
import(/* webpackChunkName: 'swiper' */ 'NodeModules/swiper/swiper.esm');
|
|
234
|
+
export function getSwiperAssetsV2(options = { css: "bundle" }) {
|
|
235
|
+
const getSwiperJs = () => import(/* webpackChunkName: 'swiper' */ "swiper");
|
|
237
236
|
|
|
238
237
|
const promisedJs = Promise.all([getSwiperJs()]).then((values) => {
|
|
239
238
|
return values;
|
|
@@ -248,9 +247,7 @@ export function getSwiperAssetsV2(options = { css: 'bundle' }) {
|
|
|
248
247
|
export function getJquery() {
|
|
249
248
|
if (!window.jQuery) {
|
|
250
249
|
const importCode = () =>
|
|
251
|
-
import(
|
|
252
|
-
/* webpackChunkName: 'jquery' */ '../../jquery/dist/jquery.min.js'
|
|
253
|
-
);
|
|
250
|
+
import(/* webpackChunkName: 'jquery' */ "jquery/dist/jquery.min.js");
|
|
254
251
|
return importCode();
|
|
255
252
|
}
|
|
256
253
|
return Promise.resolve();
|
|
@@ -262,13 +259,13 @@ export function getJquery() {
|
|
|
262
259
|
*/
|
|
263
260
|
export function getGsap() {
|
|
264
261
|
const gsapCore = () =>
|
|
265
|
-
import(
|
|
262
|
+
import("gsap/dist/gsap.min.js").then((gsapObj) => {
|
|
266
263
|
const { gsap } = gsapObj;
|
|
267
264
|
return gsap;
|
|
268
265
|
});
|
|
269
266
|
|
|
270
267
|
const gsapPlugin = () =>
|
|
271
|
-
import(
|
|
268
|
+
import("gsap/dist/ScrollTrigger.min.js").then((scrollObj) => {
|
|
272
269
|
const ScrollTrigger = scrollObj;
|
|
273
270
|
return ScrollTrigger;
|
|
274
271
|
});
|
|
@@ -312,23 +309,37 @@ export function mobileCheck() {
|
|
|
312
309
|
|
|
313
310
|
/**
|
|
314
311
|
* Run a function after a window resize event, but only after the alloted time has ended.
|
|
315
|
-
* If another resize
|
|
312
|
+
* If another resize event occurs it resets the time window.
|
|
316
313
|
* @param {function} debouncedFunction The function you want to run after a window resize event.
|
|
317
314
|
* @param {number} time The time in ms.
|
|
315
|
+
* @param {boolean} ignoreVertical Set to true if you only want to listen for horizontal resizing events.
|
|
318
316
|
*/
|
|
319
|
-
export function resizeDebouncer(
|
|
317
|
+
export function resizeDebouncer(
|
|
318
|
+
debouncedFunction,
|
|
319
|
+
time = 250,
|
|
320
|
+
ignoreVertical = false
|
|
321
|
+
) {
|
|
320
322
|
let resizeTimer;
|
|
321
|
-
|
|
323
|
+
let screenWidth = window.innerWidth;
|
|
324
|
+
window.addEventListener("resize", () => {
|
|
322
325
|
clearTimeout(resizeTimer);
|
|
323
326
|
resizeTimer = setTimeout(() => {
|
|
324
|
-
|
|
327
|
+
if (ignoreVertical) {
|
|
328
|
+
let currentWidth = window.innerWidth;
|
|
329
|
+
if (currentWidth - screenWidth !== 0) {
|
|
330
|
+
debouncedFunction();
|
|
331
|
+
}
|
|
332
|
+
screenWidth = currentWidth;
|
|
333
|
+
} else {
|
|
334
|
+
debouncedFunction();
|
|
335
|
+
}
|
|
325
336
|
}, time);
|
|
326
337
|
});
|
|
327
338
|
}
|
|
328
339
|
|
|
329
340
|
/**
|
|
330
341
|
* 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.
|
|
331
|
-
* If another resize
|
|
342
|
+
* If another resize event occurs it resets the time window.
|
|
332
343
|
* @param {htmlElement} element The element that emits the event.
|
|
333
344
|
* @param {string} eventType The type of event to listen for.
|
|
334
345
|
* @param {function} debouncedFunction The function to run after the event.
|
|
@@ -358,14 +369,14 @@ export function injectYouTubeIframeScript() {
|
|
|
358
369
|
if (globalThis.YT) {
|
|
359
370
|
return resolve();
|
|
360
371
|
}
|
|
361
|
-
const tag = document.createElement(
|
|
362
|
-
tag.id =
|
|
363
|
-
tag.src =
|
|
372
|
+
const tag = document.createElement("script");
|
|
373
|
+
tag.id = "iframe-api";
|
|
374
|
+
tag.src = "https://www.youtube.com/iframe_api";
|
|
364
375
|
|
|
365
|
-
const firstScriptTag = document.getElementsByTagName(
|
|
376
|
+
const firstScriptTag = document.getElementsByTagName("script")[0];
|
|
366
377
|
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
|
367
378
|
|
|
368
|
-
tag.addEventListener(
|
|
379
|
+
tag.addEventListener("load", () => {
|
|
369
380
|
if (!YT.loaded) {
|
|
370
381
|
const loadingCheck = setInterval(() => {
|
|
371
382
|
if (YT.loaded) {
|
|
@@ -383,34 +394,34 @@ export function injectYouTubeIframeScript() {
|
|
|
383
394
|
}
|
|
384
395
|
|
|
385
396
|
export function fallbackCopyToClipboard(text) {
|
|
386
|
-
const textArea = document.createElement(
|
|
397
|
+
const textArea = document.createElement("textarea");
|
|
387
398
|
textArea.value = text;
|
|
388
399
|
|
|
389
400
|
// Avoid scrolling to bottom
|
|
390
|
-
textArea.style.top =
|
|
391
|
-
textArea.style.left =
|
|
392
|
-
textArea.style.position =
|
|
401
|
+
textArea.style.top = "0";
|
|
402
|
+
textArea.style.left = "0";
|
|
403
|
+
textArea.style.position = "fixed";
|
|
393
404
|
|
|
394
405
|
document.body.appendChild(textArea);
|
|
395
406
|
textArea.focus();
|
|
396
407
|
textArea.select();
|
|
397
408
|
|
|
398
409
|
try {
|
|
399
|
-
const successful = document.execCommand(
|
|
400
|
-
const msg = successful ?
|
|
410
|
+
const successful = document.execCommand("copy");
|
|
411
|
+
const msg = successful ? "successful" : "unsuccessful";
|
|
401
412
|
console.log(`Fallback: Copying text command was ${msg}`);
|
|
402
413
|
} catch (err) {
|
|
403
|
-
console.error(
|
|
414
|
+
console.error("Fallback: Oops, unable to copy", err);
|
|
404
415
|
}
|
|
405
416
|
|
|
406
417
|
document.body.removeChild(textArea);
|
|
407
418
|
}
|
|
408
419
|
|
|
409
420
|
export function copyToClipboard() {
|
|
410
|
-
const copyLinks = document.querySelectorAll(
|
|
421
|
+
const copyLinks = document.querySelectorAll(".copy-to-clipboard");
|
|
411
422
|
let timeout;
|
|
412
423
|
copyLinks.forEach((link) => {
|
|
413
|
-
link.addEventListener(
|
|
424
|
+
link.addEventListener("click", function () {
|
|
414
425
|
const copyToClipboardDone = link.nextElementSibling;
|
|
415
426
|
if (!navigator.clipboard) {
|
|
416
427
|
fallbackCopyToClipboard(this.dataset.url);
|
|
@@ -419,23 +430,23 @@ export function copyToClipboard() {
|
|
|
419
430
|
|
|
420
431
|
navigator.clipboard.writeText(this.dataset.url).then(
|
|
421
432
|
function () {
|
|
422
|
-
console.log(
|
|
433
|
+
console.log("Copying to clipboard was successful!");
|
|
423
434
|
},
|
|
424
435
|
function (err) {
|
|
425
|
-
console.error(
|
|
436
|
+
console.error("Could not copy text: ", err);
|
|
426
437
|
}
|
|
427
438
|
);
|
|
428
439
|
|
|
429
440
|
if (
|
|
430
441
|
copyToClipboardDone &&
|
|
431
442
|
copyToClipboardDone.classList &&
|
|
432
|
-
copyToClipboardDone.classList.contains(
|
|
443
|
+
copyToClipboardDone.classList.contains("sharing__clipboard-done")
|
|
433
444
|
) {
|
|
434
445
|
clearTimeout(timeout);
|
|
435
|
-
copyToClipboardDone.classList.remove(
|
|
446
|
+
copyToClipboardDone.classList.remove("hidden");
|
|
436
447
|
|
|
437
448
|
timeout = setTimeout(() => {
|
|
438
|
-
copyToClipboardDone.classList.add(
|
|
449
|
+
copyToClipboardDone.classList.add("hidden");
|
|
439
450
|
}, 2000);
|
|
440
451
|
}
|
|
441
452
|
});
|
|
@@ -515,13 +526,13 @@ export function detectSwipe(element, callback, removeHandlers = false) {
|
|
|
515
526
|
|
|
516
527
|
if (Math.abs(delx) > pixels || Math.abs(dely) > pixels) {
|
|
517
528
|
if (Math.abs(delx) > Math.abs(dely)) {
|
|
518
|
-
if (delx > 0) return
|
|
519
|
-
else return
|
|
529
|
+
if (delx > 0) return "right";
|
|
530
|
+
else return "left";
|
|
520
531
|
} else if (Math.abs(delx) < Math.abs(dely)) {
|
|
521
|
-
if (dely > 0) return
|
|
522
|
-
else return
|
|
532
|
+
if (dely > 0) return "down";
|
|
533
|
+
else return "up";
|
|
523
534
|
}
|
|
524
|
-
} else return
|
|
535
|
+
} else return "tap";
|
|
525
536
|
}
|
|
526
537
|
|
|
527
538
|
function touchStart(event) {
|
|
@@ -529,10 +540,10 @@ export function detectSwipe(element, callback, removeHandlers = false) {
|
|
|
529
540
|
touchstartY = event.changedTouches[0].screenY;
|
|
530
541
|
}
|
|
531
542
|
|
|
532
|
-
element.addEventListener(
|
|
543
|
+
element.addEventListener("touchstart", () => touchStart(event), false);
|
|
533
544
|
|
|
534
545
|
element.addEventListener(
|
|
535
|
-
|
|
546
|
+
"touchend",
|
|
536
547
|
function (event) {
|
|
537
548
|
touchendX = event.changedTouches[0].screenX;
|
|
538
549
|
touchendY = event.changedTouches[0].screenY;
|
|
@@ -540,9 +551,9 @@ export function detectSwipe(element, callback, removeHandlers = false) {
|
|
|
540
551
|
},
|
|
541
552
|
false
|
|
542
553
|
);
|
|
543
|
-
if (removeHandlers ===
|
|
544
|
-
element.removeEventListener(
|
|
545
|
-
element.removeEventListener(
|
|
554
|
+
if (removeHandlers === "remove") {
|
|
555
|
+
element.removeEventListener("touchstart", touchStart);
|
|
556
|
+
element.removeEventListener("touchend", handleGesture);
|
|
546
557
|
return;
|
|
547
558
|
}
|
|
548
559
|
}
|
|
@@ -554,12 +565,12 @@ export function detectSwipe(element, callback, removeHandlers = false) {
|
|
|
554
565
|
*/
|
|
555
566
|
export function checkIosVersion() {
|
|
556
567
|
const agent = window.navigator.userAgent,
|
|
557
|
-
start = agent.indexOf(
|
|
568
|
+
start = agent.indexOf("OS ");
|
|
558
569
|
if (
|
|
559
|
-
(agent.indexOf(
|
|
570
|
+
(agent.indexOf("iPhone") > -1 || agent.indexOf("iPad") > -1) &&
|
|
560
571
|
start > -1
|
|
561
572
|
) {
|
|
562
|
-
return window.Number(agent.substr(start + 3, 3).replace(
|
|
573
|
+
return window.Number(agent.substr(start + 3, 3).replace("_", "."));
|
|
563
574
|
}
|
|
564
575
|
return 0;
|
|
565
576
|
}
|
|
@@ -572,11 +583,11 @@ export function checkIosVersion() {
|
|
|
572
583
|
export function appendPreconnect(domain) {
|
|
573
584
|
try {
|
|
574
585
|
if (!domain) {
|
|
575
|
-
console.log(
|
|
586
|
+
console.log("The domain was missing or broken...");
|
|
576
587
|
return;
|
|
577
588
|
}
|
|
578
|
-
const link = document.createElement(
|
|
579
|
-
link.rel =
|
|
589
|
+
const link = document.createElement("link");
|
|
590
|
+
link.rel = "preconnect";
|
|
580
591
|
link.href = domain;
|
|
581
592
|
document.head.appendChild(link);
|
|
582
593
|
return;
|
|
@@ -609,6 +620,6 @@ const api = {
|
|
|
609
620
|
getElementStyles,
|
|
610
621
|
getPercent,
|
|
611
622
|
checkIosVersion,
|
|
612
|
-
appendPreconnect
|
|
623
|
+
appendPreconnect,
|
|
613
624
|
};
|
|
614
625
|
export default api;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pernod-ricard-global-cms/jsutils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Handy collection of Javascript utility functions",
|
|
5
|
-
"type": "
|
|
6
|
-
"main": "jsutils.
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "jsutils.mjs",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "
|
|
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.
|
|
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
|
-
"
|
|
27
|
+
"cypress": "^10.5.0",
|
|
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
|
-
});
|