PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 13.5
Jetpack – WP Security, Backup, Speed, & Growth v13.5
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 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / plugin-search / plugin-search.js

plugin-search.js in Jetpack – WP Security, Backup, Speed, & Growth 13.5, at modules/plugin-search/plugin-search.js

274 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Handles the activation of a Jetpack feature, dismissing the card, and replacing the bottom row
3 * of the card with customized content.
4 */
5
6 /* global jetpackPluginSearch, JSON, jpTracksAJAX */
7
8 var JetpackPSH = {};
9
10 ( function ( $, jpsh ) {
11 JetpackPSH = {
12 $pluginFilter: $( '#plugin-filter' ),
13
14 /**
15 * Get parent search hint element.
16 * @returns {Element | null}
17 */
18 getCard: function () {
19 return document.querySelector( '.plugin-card-jetpack-plugin-search' );
20 },
21
22 /**
23 * Track user event such as a click on a button or a link.
24 *
25 * @param {string} eventName Event identifier.
26 * @param {object} feature Identifier of feature involved in the event.
27 * @param {object} target Object where action was performed.
28 */
29 trackEvent: function ( eventName, feature, target ) {
30 jpTracksAJAX
31 .record_ajax_event( eventName, 'click', { feature: feature } )
32 .always( function () {
33 if ( 'undefined' !== typeof target && !! target.getAttribute( 'href' ) ) {
34 // If it has an href, follow it.
35 window.location = target.getAttribute( 'href' );
36 }
37 } );
38 },
39
40 /**
41 * Update title of the card to add a mention that the result is from the Jetpack plugin.
42 */
43 updateCardTitle: function () {
44 var hint = JetpackPSH.getCard();
45
46 if ( 'object' === typeof hint && null !== hint ) {
47 var title = hint.querySelector( '.column-name h3' );
48 title.outerHTML =
49 title.outerHTML + '<strong>' + jetpackPluginSearch.poweredBy + '</strong>';
50 }
51 },
52
53 /**
54 * Move action links below description.
55 */
56 moveActionLinks: function () {
57 var hint = JetpackPSH.getCard();
58 if ( 'object' === typeof hint && null !== hint ) {
59 var descriptionContainer = hint.querySelector( '.column-description' );
60 // Keep only the first paragraph. The second is the plugin author.
61 var descriptionText = descriptionContainer.querySelector( 'p:first-child' );
62 var actionLinks = hint.querySelector( '.action-links' );
63
64 // Change the contents of the description, to keep the description text and the action links.
65 descriptionContainer.innerHTML = descriptionText.outerHTML + actionLinks.outerHTML;
66
67 // Remove the action links from their default location.
68 actionLinks.parentNode.removeChild( actionLinks );
69 }
70 },
71
72 /**
73 * Replace bottom row of the card to insert logo, text and link to dismiss the card.
74 */
75 replaceCardBottom: function () {
76 var hint = JetpackPSH.getCard();
77 if ( 'object' === typeof hint && null !== hint ) {
78 hint.querySelector( '.plugin-card-bottom' ).outerHTML =
79 '<div class="jetpack-plugin-search__bottom"><img src="' +
80 jetpackPluginSearch.logo +
81 '" width="32" />' +
82 '<p class="jetpack-plugin-search__text">' +
83 jetpackPluginSearch.legend +
84 ' <a class="jetpack-plugin-search__support_link" href="' +
85 jetpackPluginSearch.supportLink +
86 '" target="_blank" rel="noopener noreferrer" data-track="support_link" >' +
87 jetpackPluginSearch.supportText +
88 '</a>' +
89 '</p>' +
90 '</div>';
91
92 // Remove link and parent li from action links and move it to bottom row
93 var dismissLink = document.querySelector( '.jetpack-plugin-search__dismiss' );
94 dismissLink.parentNode.parentNode.removeChild( dismissLink.parentNode );
95 document.querySelector( '.jetpack-plugin-search__bottom' ).appendChild( dismissLink );
96 }
97 },
98
99 /**
100 * Check if plugin card list nodes changed. If there's a Jetpack PSH card, replace the title and the bottom row.
101 * @param {array} mutationsList
102 */
103 replaceOnNewResults: function ( mutationsList ) {
104 mutationsList.forEach( function ( mutation ) {
105 if (
106 'childList' === mutation.type &&
107 1 === document.querySelectorAll( '.plugin-card-jetpack-plugin-search' ).length
108 ) {
109 JetpackPSH.updateCardTitle();
110 JetpackPSH.moveActionLinks();
111 JetpackPSH.replaceCardBottom();
112 }
113 } );
114 },
115
116 dismiss: function ( moduleName ) {
117 document.getElementById( 'the-list' ).removeChild( JetpackPSH.getCard() );
118 $.ajax( {
119 url: jpsh.base_rest_url + '/hints',
120 method: 'post',
121 beforeSend: function ( xhr ) {
122 xhr.setRequestHeader( 'X-WP-Nonce', jpsh.nonce );
123 },
124 data: JSON.stringify( {
125 hint: moduleName,
126 } ),
127 contentType: 'application/json',
128 dataType: 'json',
129 } ).done( function () {
130 JetpackPSH.trackEvent( 'wpa_plugin_search_dismiss', moduleName );
131 } );
132 },
133
134 ajaxActivateModule: function ( moduleName ) {
135 var $moduleBtn = JetpackPSH.$pluginFilter.find( '#plugin-select-activate' );
136 $moduleBtn.toggleClass( 'install-now updating-message' );
137 $moduleBtn.prop( 'disabled', true );
138 $moduleBtn.text( jpsh.activating );
139 var data = {};
140 data[ moduleName ] = true;
141 $.ajax( {
142 url: jpsh.base_rest_url + '/settings',
143 method: 'post',
144 beforeSend: function ( xhr ) {
145 xhr.setRequestHeader( 'X-WP-Nonce', jpsh.nonce );
146 },
147 data: JSON.stringify( data ),
148 contentType: 'application/json',
149 dataType: 'json',
150 } )
151 .done( function () {
152 JetpackPSH.updateButton( moduleName );
153 JetpackPSH.trackEvent( 'wpa_plugin_search_activate', moduleName );
154 } )
155 .error( function () {
156 $moduleBtn.toggleClass( 'install-now updating-message' );
157 } );
158 },
159
160 // Remove onclick handler, disable loading spinner, update button to redirect to module settings.
161 updateButton: function ( moduleName ) {
162 $.ajax( {
163 url: jpsh.base_rest_url + '/module/' + moduleName,
164 method: 'get',
165 beforeSend: function ( xhr ) {
166 xhr.setRequestHeader( 'X-WP-Nonce', jpsh.nonce );
167 },
168 dataType: 'json',
169 } ).done( function ( response ) {
170 var $moduleBtn = JetpackPSH.$pluginFilter.find( '#plugin-select-activate' );
171 $moduleBtn.prop( 'onclick', null ).off( 'click' );
172 $moduleBtn.toggleClass( 'install-now updating-message' );
173 $moduleBtn.text( jpsh.activated );
174 setTimeout( function () {
175 var url = 'https://jetpack.com/redirect/?source=plugin-hint-learn-' + moduleName,
176 label = jpsh.getStarted,
177 classes = 'jetpack-plugin-search__primary button',
178 track = 'configure';
179
180 // If the feature has options in Jetpack admin UI, link to them.
181 if ( response.options && 0 < Object.keys( response.options ).length ) {
182 url = $moduleBtn.data( 'configure-url' );
183 label = jpsh.manageSettings;
184 classes += ' jetpack-plugin-search__configure';
185 } else {
186 // If it has no options, the Get started button will be displayed so remove the Learn more link if it's there.
187 var learnMore = document.querySelector( '.jetpack-plugin-search__learn-more' );
188 learnMore.parentNode.removeChild( learnMore );
189 classes += ' jetpack-plugin-search__get-started';
190 track = 'get_started';
191 }
192 $moduleBtn.replaceWith(
193 '<a id="plugin-select-settings" class="' +
194 classes +
195 '" href="' +
196 url +
197 '" data-module="' +
198 moduleName +
199 '" data-track="' +
200 track +
201 '">' +
202 label +
203 '</a>'
204 );
205 }, 1000 );
206 } );
207 },
208
209 /**
210 * Start suggesting.
211 */
212 init: function () {
213 if ( JetpackPSH.$pluginFilter.length < 1 ) {
214 return;
215 }
216
217 // Update title to show that the suggestion is from Jetpack.
218 JetpackPSH.updateCardTitle();
219
220 // Update the description and action links.
221 JetpackPSH.moveActionLinks();
222
223 // Replace PSH bottom row on page load
224 JetpackPSH.replaceCardBottom();
225
226 // Listen for changes in plugin search results
227 var resultsObserver = new MutationObserver( JetpackPSH.replaceOnNewResults );
228 resultsObserver.observe( document.getElementById( 'plugin-filter' ), { childList: true } );
229
230 JetpackPSH.$pluginFilter
231 .on( 'click', '.jetpack-plugin-search__dismiss', function ( event ) {
232 event.preventDefault();
233 JetpackPSH.dismiss( $( this ).data( 'module' ) );
234 } )
235 .on( 'click', 'button#plugin-select-activate', function ( event ) {
236 event.preventDefault();
237 JetpackPSH.ajaxActivateModule( $( this ).data( 'module' ) );
238 } )
239 .on( 'click', '.jetpack-plugin-search__primary', function ( event ) {
240 event.preventDefault();
241 var $this = $( this );
242 if ( $this.data( 'track' ) ) {
243 // This catches Purchase, Configure, and Get started. Feature activation is tracked when it ends successfully, in its callback.
244 JetpackPSH.trackEvent(
245 'wpa_plugin_search_' + $this.data( 'track' ),
246 $this.data( 'module' ),
247 $this.get( 0 )
248 );
249 }
250 } )
251 .on( 'click', '.jetpack-plugin-search__learn-more', function ( event ) {
252 event.preventDefault();
253 var $this = $( this );
254 JetpackPSH.trackEvent(
255 'wpa_plugin_search_learn_more',
256 $this.data( 'module' ),
257 $this.get( 0 )
258 );
259 } )
260 .on( 'click', '.jetpack-plugin-search__support_link', function ( event ) {
261 event.preventDefault();
262 var $this = $( this );
263 JetpackPSH.trackEvent(
264 'wpa_plugin_search_support_link',
265 $this.data( 'module' ),
266 $this.get( 0 )
267 );
268 } );
269 },
270 };
271
272 JetpackPSH.init();
273 } )( jQuery, jetpackPluginSearch );
274