-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use AJAX for activating features / plugins in Performance Lab #1646
Changes from 11 commits
47f3938
9d97f59
6f172ad
337da6c
58c37d9
a59909d
f9faaea
770d462
e6710a3
c3d3588
fdf7e0b
b3ecc98
c713e47
1ebe323
c134fe2
369487f
d84e9bd
9bee27e
ce217ba
fa5d869
3a333ae
6250658
a8d89a8
c593ae6
e0691bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/** | ||
* Handles activation of Performance Features (Plugins) using AJAX. | ||
*/ | ||
|
||
/* global perflabPluginActivateAjaxData */ | ||
( function () { | ||
// @ts-ignore | ||
const { i18n, a11y } = wp; | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const { __ } = i18n; | ||
|
||
/** | ||
* Handles click events on elements with the class 'perflab-install-active-plugin'. | ||
* | ||
* This asynchronous function listens for click events on the document and executes | ||
* the provided callback function if triggered. | ||
* | ||
* @param {MouseEvent} event - The click event object that is triggered when the user clicks on the document. | ||
* | ||
* @return {Promise<void>} - The asynchronous function returns a promise that resolves to void. | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
async function handlePluginActivationClick( event ) { | ||
const target = /** @type {HTMLElement} */ ( event.target ); | ||
|
||
if ( ! target.classList.contains( 'perflab-install-active-plugin' ) ) { | ||
return; | ||
} | ||
|
||
// Prevent the default link behavior. | ||
event.preventDefault(); | ||
|
||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
target.classList.add( 'updating-message' ); | ||
target.textContent = __( 'Activating…', 'performance-lab' ); | ||
target.style.pointerEvents = 'none'; | ||
target.parentElement.style.cursor = 'not-allowed'; | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
a11y.speak( __( 'Activating…', 'performance-lab' ) ); | ||
|
||
const pluginSlug = target.getAttribute( 'data-plugin-slug' ).trim(); | ||
b1ink0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Send an AJAX POST request to activate the plugin. | ||
try { | ||
const response = await fetch( | ||
// @ts-ignore | ||
perflabPluginActivateAjaxData.ajaxUrl, | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
method: 'POST', | ||
credentials: 'same-origin', | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
body: new URLSearchParams( { | ||
action: 'perflab_install_activate_plugin', | ||
slug: pluginSlug, | ||
// @ts-ignore | ||
_ajax_nonce: perflabPluginActivateAjaxData.nonce, | ||
} ), | ||
} | ||
); | ||
|
||
const responseData = await response.json(); | ||
|
||
if ( ! responseData.success ) { | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
target.classList.remove( 'updating-message' ); | ||
target.textContent = __( 'Activate', 'performance-lab' ); | ||
target.style.pointerEvents = ''; | ||
target.parentElement.style.cursor = ''; | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return; | ||
} | ||
|
||
const newButton = document.createElement( 'button' ); | ||
|
||
newButton.type = 'button'; | ||
newButton.className = 'button button-disabled'; | ||
newButton.disabled = true; | ||
newButton.textContent = __( 'Active', 'performance-lab' ); | ||
target.parentElement.style.cursor = ''; | ||
|
||
target.parentNode.replaceChild( newButton, target ); | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const pluginSettingsURL = responseData?.data?.pluginSettingsURL; | ||
|
||
const actionButtonList = document.querySelector( | ||
`.plugin-card-${ pluginSlug } .plugin-action-buttons` | ||
); | ||
|
||
if ( pluginSettingsURL && actionButtonList ) { | ||
const listItem = document.createElement( 'li' ); | ||
const anchor = document.createElement( 'a' ); | ||
|
||
anchor.setAttribute( 'href', pluginSettingsURL ); | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
anchor.textContent = __( 'Settings', 'performance-lab' ); | ||
|
||
listItem.appendChild( anchor ); | ||
actionButtonList.appendChild( listItem ); | ||
} | ||
} catch ( error ) { | ||
target.classList.remove( 'updating-message' ); | ||
target.textContent = __( 'Activate', 'performance-lab' ); | ||
target.style.pointerEvents = ''; | ||
target.parentElement.style.cursor = ''; | ||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
westonruter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Attach the event listener. | ||
document.addEventListener( 'click', handlePluginActivationClick ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this add a listener for the entire I feel like that would be a more reasonable choice, as it avoids having the listener fire for more or less every click on the page. Since the buttons are present in the HTML response from the beginning, I don't see a need for listening on |
||
} )(); |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, in #1646 (comment) I just posed this change as a possibility but then recommended against it since it would only account for Speculative Loading. It wouldn't account for other plugins that have delayed bootstrapping. So to address the problem of accessing the settings link after a plugin is activated, I think the best solution is to make another request specifically to an endpoint that exposes the settings link URLs. Aside: I think the REST API would be better for this instead of admin-ajax. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need these enqueue now? as it already added through new script dependancy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove it as it is not being used anywhere other than the AJAX script as it already added in its dependancy. Should I remove it then?