PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
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 +104 -29 12.6.4 → 16.3-a.7 View file →
@@ -1,48 +1,123 @@
1 +/* global Jetpack_Subscriptions */
1 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';
2 7
3 -domReady( function () {
4 - const modal = document.getElementsByClassName( 'jetpack-subscribe-modal' )[ 0 ];
8 + function hasEnoughTimePassed() {
9 + const lastDismissed = localStorage.getItem( modalDismissedCookie );
10 + return lastDismissed ? Date.now() - lastDismissed > Jetpack_Subscriptions.modalInterval : true;
11 + }
5 12
6 - if ( ! modal ) {
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() ) {
7 28 return;
8 29 }
9 30
10 - const close = document.getElementsByClassName( 'jetpack-subscribe-modal__close' )[ 0 ];
11 - const modalDismissedCookie = 'jetpack_subscribe_modal_dismissed';
12 - const hasModalDismissedCookie =
13 - document.cookie && document.cookie.indexOf( modalDismissedCookie ) > -1;
14 - let hasLoaded = false;
15 - let isScrolling;
31 + const modalLoadTimeout = setTimeout( openModal, Jetpack_Subscriptions.modalLoadTime );
16 32
17 - window.onscroll = function () {
18 - window.clearTimeout( isScrolling );
33 + const targetElement = (
34 + document.querySelector( '.entry-content' ) || document.documentElement
35 + ).getBoundingClientRect();
19 36
20 - isScrolling = setTimeout( function () {
21 - if ( ! hasLoaded && ! hasModalDismissedCookie ) {
22 - modal.classList.toggle( 'open' );
23 - hasLoaded = true;
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() ) {
48 + openModal();
24 49 }
25 - }, 300 );
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 () {
31 - modal.classList.toggle( 'open' );
32 - setModalDismissedCookie();
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 - modal.style.display = 'none';
39 - setModalDismissedCookie();
82 + closeModal();
40 83 }
41 - };
84 + }
42 85
43 - function setModalDismissedCookie() {
44 - // Expires in 1 day
45 - const expires = new Date( Date.now() + 86400 * 1000 ).toUTCString();
46 - document.cookie = `${ modalDismissedCookie }=true; expires=${ expires };`;
86 + function closeModalOnEscapeKeydown( event ) {
87 + if ( event.key === 'Escape' ) {
88 + closeModal();
89 + }
90 + }
91 +
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 +
98 + modal.classList.add( 'open' );
99 + document.body.classList.add( 'jetpack-subscribe-modal-open' );
100 + window.addEventListener( 'keydown', closeModalOnEscapeKeydown );
101 + window.addEventListener( 'click', closeOnWindowClick );
102 + removeEventListeners();
103 + }
104 +
105 + function closeModal() {
106 + modal.classList.remove( 'open' );
107 + document.body.classList.remove( 'jetpack-subscribe-modal-open' );
108 + window.removeEventListener( 'keydown', closeModalOnEscapeKeydown );
109 + window.removeEventListener( 'storage', onLocalStorage );
110 + window.removeEventListener( 'click', closeOnWindowClick );
111 + storeCloseTimestamp();
112 + }
113 +
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() );
47 122 }
48 123 } );