PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.2.2
Jetpack – WP Security, Backup, Speed, & Growth v7.2.2
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 13.9.2 14.0.1 14.1.1 14.2.2 All 502 releases
jetpack / modules / plugin-search / plugin-search.js

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

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