PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.5
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.5
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
← All changes | modules/subscriptions/subscribe-modal/subscribe-modal.js +83 -27 13.4.5 → 16.3-a.5 View file →
@@ -1,44 +1,88 @@
1 1 /* global Jetpack_Subscriptions */
2 2 const { domReady } = wp;
3 +domReady( () => {
4 + const modal = document.querySelector( '.jetpack-subscribe-modal' );
5 + const modalDismissedCookie = 'jetpack_post_subscribe_modal_dismissed';
6 + const skipUrlParam = 'jetpack_skip_subscription_popup';
3 7
4 -domReady( function () {
5 - const modal = document.getElementsByClassName( 'jetpack-subscribe-modal' )[ 0 ];
6 - const modalDismissedCookie = 'jetpack_post_subscribe_modal_dismissed';
7 - const hasModalDismissedCookie =
8 - document.cookie && document.cookie.indexOf( modalDismissedCookie ) > -1;
8 + function hasEnoughTimePassed() {
9 + const lastDismissed = localStorage.getItem( modalDismissedCookie );
10 + return lastDismissed ? Date.now() - lastDismissed > Jetpack_Subscriptions.modalInterval : true;
11 + }
9 12
10 - if ( ! modal || hasModalDismissedCookie ) {
13 + // Subscriber ended up here e.g. from emails:
14 + // we won't show the modal to them in future since they most likely are already a subscriber.
15 + function skipModal() {
16 + const url = new URL( window.location.href );
17 + if ( url.searchParams.has( skipUrlParam ) ) {
18 + url.searchParams.delete( skipUrlParam );
19 + window.history.replaceState( {}, '', url );
20 + storeCloseTimestamp();
21 + return true;
22 + }
23 +
24 + return false;
25 + }
26 +
27 + if ( ! modal || ! hasEnoughTimePassed() || skipModal() ) {
11 28 return;
12 29 }
13 30
14 - const close = document.getElementsByClassName( 'jetpack-subscribe-modal__close' )[ 0 ];
15 - let hasLoaded = false;
16 - let isScrolling;
31 + const modalLoadTimeout = setTimeout( openModal, Jetpack_Subscriptions.modalLoadTime );
17 32
18 - window.onscroll = function () {
19 - window.clearTimeout( isScrolling );
33 + const targetElement = (
34 + document.querySelector( '.entry-content' ) || document.documentElement
35 + ).getBoundingClientRect();
20 36
21 - isScrolling = setTimeout( function () {
22 - if ( ! hasLoaded ) {
37 + function hasPassedScrollThreshold() {
38 + const scrollPosition = window.scrollY + window.innerHeight / 2;
39 + const scrollPositionThreshold =
40 + targetElement.top +
41 + ( targetElement.height * Jetpack_Subscriptions.modalScrollThreshold ) / 100;
42 + return scrollPosition > scrollPositionThreshold;
43 + }
44 +
45 + function onScroll() {
46 + requestAnimationFrame( () => {
47 + if ( hasPassedScrollThreshold() ) {
23 48 openModal();
24 49 }
25 - }, Jetpack_Subscriptions.modalLoadTime );
26 - };
50 + } );
51 + }
27 52
53 + window.addEventListener( 'scroll', onScroll, { passive: true } );
54 +
55 + // This take care of the case where the user has multiple tabs open.
56 + function onLocalStorage( event ) {
57 + if ( event.key === modalDismissedCookie ) {
58 + closeModal();
59 + removeEventListeners();
60 + }
61 + }
62 + window.addEventListener( 'storage', onLocalStorage );
63 +
64 + // When the form is submitted, and next modal loads, it'll fire "subscription-modal-loaded" signalling that this form can be hidden.
65 + const form = modal.querySelector( 'form' );
66 + if ( form ) {
67 + form.addEventListener( 'subscription-modal-loaded', closeModal );
68 + }
69 +
28 70 // User can edit modal, and could remove close link.
71 + function onCloseButtonClick( event ) {
72 + event.preventDefault();
73 + closeModal();
74 + }
75 + const close = document.getElementsByClassName( 'jetpack-subscribe-modal__close' )[ 0 ];
29 76 if ( close ) {
30 - close.onclick = function ( event ) {
31 - event.preventDefault();
32 - closeModal();
33 - };
77 + close.addEventListener( 'click', onCloseButtonClick );
34 78 }
35 79
36 - window.onclick = function ( event ) {
80 + function closeOnWindowClick( event ) {
37 81 if ( event.target === modal ) {
38 82 closeModal();
39 83 }
40 - };
84 + }
41 85
42 86 function closeModalOnEscapeKeydown( event ) {
43 87 if ( event.key === 'Escape' ) {
44 88 closeModal();
@@ -45,13 +89,18 @@
45 89 }
46 90 }
47 91
48 92 function openModal() {
93 + // If the user is typing in a form, don't open the modal or has anything else focused.
94 + if ( document.activeElement && document.activeElement.tagName !== 'BODY' ) {
95 + return;
96 + }
97 +
49 98 modal.classList.add( 'open' );
50 99 document.body.classList.add( 'jetpack-subscribe-modal-open' );
51 - hasLoaded = true;
52 - setModalDismissedCookie();
53 100 window.addEventListener( 'keydown', closeModalOnEscapeKeydown );
101 + window.addEventListener( 'click', closeOnWindowClick );
102 + removeEventListeners();
54 103 }
55 104
56 105 function closeModal() {
57 106 modal.classList.remove( 'open' );
@@ -56,12 +105,19 @@
56 105 function closeModal() {
57 106 modal.classList.remove( 'open' );
58 107 document.body.classList.remove( 'jetpack-subscribe-modal-open' );
59 108 window.removeEventListener( 'keydown', closeModalOnEscapeKeydown );
109 + window.removeEventListener( 'storage', onLocalStorage );
110 + window.removeEventListener( 'click', closeOnWindowClick );
111 + storeCloseTimestamp();
60 112 }
61 113
62 - function setModalDismissedCookie() {
63 - // Expires in 1 day
64 - const expires = new Date( Date.now() + 86400 * 1000 ).toUTCString();
65 - document.cookie = `${ modalDismissedCookie }=true; expires=${ expires };path=/;`;
114 + // Remove all event listeners. That would add the modal again.
115 + function removeEventListeners() {
116 + window.removeEventListener( 'scroll', onScroll );
117 + clearTimeout( modalLoadTimeout );
118 + }
119 +
120 + function storeCloseTimestamp() {
121 + localStorage.setItem( modalDismissedCookie, Date.now() );
66 122 }
67 123 } );