chore: initial snapshot of 2meet-data-optimizer v0.1.0
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* WP Data Optimizer — Admin JS (native fetch, no jQuery)
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
( function () {
|
||||
'use strict';
|
||||
|
||||
var WPDO = window.wpdoAdmin || {};
|
||||
var i18n = WPDO.i18n || {};
|
||||
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
function () {
|
||||
bindFlushCacheButtons();
|
||||
bindStatusRefresh();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Announce a message via the shared aria-live region.
|
||||
* Falls back to creating the region on first call.
|
||||
*/
|
||||
function announce( message ) {
|
||||
var region = document.getElementById( 'wpdo-aria-live' );
|
||||
if ( ! region ) {
|
||||
region = document.createElement( 'div' );
|
||||
region.id = 'wpdo-aria-live';
|
||||
region.className = 'wpdo-sr-only';
|
||||
region.setAttribute( 'role', 'status' );
|
||||
region.setAttribute( 'aria-live', 'polite' );
|
||||
region.setAttribute( 'aria-atomic', 'true' );
|
||||
document.body.appendChild( region );
|
||||
}
|
||||
region.textContent = '';
|
||||
setTimeout(
|
||||
function () {
|
||||
region.textContent = message; },
|
||||
50
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an inline admin notice at the top of .wpdo-wrap.
|
||||
* Dismissable by user. Replaces legacy alert() for errors.
|
||||
*/
|
||||
function showNotice( message, type ) {
|
||||
type = type || 'error';
|
||||
var wrap = document.querySelector( '.wpdo-wrap' );
|
||||
if ( ! wrap ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var notice = document.createElement( 'div' );
|
||||
notice.className = 'notice notice-' + type + ' is-dismissible';
|
||||
notice.setAttribute( 'role', type === 'error' ? 'alert' : 'status' );
|
||||
|
||||
var p = document.createElement( 'p' );
|
||||
p.textContent = message;
|
||||
notice.appendChild( p );
|
||||
|
||||
var dismiss = document.createElement( 'button' );
|
||||
dismiss.type = 'button';
|
||||
dismiss.className = 'notice-dismiss';
|
||||
dismiss.setAttribute( 'aria-label', i18n.dismiss || 'Dismiss' );
|
||||
dismiss.addEventListener(
|
||||
'click',
|
||||
function () {
|
||||
notice.remove();
|
||||
}
|
||||
);
|
||||
notice.appendChild( dismiss );
|
||||
|
||||
// Insert after the H1 so it appears at the top of the content area.
|
||||
var h1 = wrap.querySelector( 'h1' );
|
||||
if ( h1 && h1.nextSibling ) {
|
||||
wrap.insertBefore( notice, h1.nextSibling );
|
||||
} else {
|
||||
wrap.prepend( notice );
|
||||
}
|
||||
|
||||
announce( message );
|
||||
}
|
||||
|
||||
/**
|
||||
* POST to admin-ajax.php using native fetch + FormData.
|
||||
* Returns a Promise resolving to the parsed JSON response.
|
||||
*/
|
||||
function wpdoAjax( actionType, data ) {
|
||||
var body = new FormData();
|
||||
body.append( 'action', 'wpdo_admin_action' );
|
||||
body.append( 'nonce', WPDO.nonce || '' );
|
||||
body.append( 'action_type', actionType );
|
||||
Object.keys( data || {} ).forEach(
|
||||
function ( key ) {
|
||||
body.append( key, data[ key ] );
|
||||
}
|
||||
);
|
||||
|
||||
return fetch(
|
||||
WPDO.ajaxUrl,
|
||||
{
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
body: body,
|
||||
}
|
||||
)
|
||||
.then(
|
||||
function ( res ) {
|
||||
if ( ! res.ok ) {
|
||||
throw new Error( 'HTTP ' + res.status );
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush cache button handler — delegated click listener.
|
||||
*/
|
||||
function bindFlushCacheButtons() {
|
||||
document.addEventListener(
|
||||
'click',
|
||||
function ( e ) {
|
||||
var btn = e.target.closest( '.wpdo-flush-cache' );
|
||||
if ( ! btn ) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
var postType = btn.getAttribute( 'data-post-type' );
|
||||
if ( ! postType ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var originalLabel = btn.textContent;
|
||||
btn.disabled = true;
|
||||
btn.textContent = i18n.flushing || 'Flushing…';
|
||||
announce( btn.textContent );
|
||||
|
||||
wpdoAjax( 'flush_cache', { post_type: postType } )
|
||||
.then(
|
||||
function ( response ) {
|
||||
if ( response && response.success ) {
|
||||
btn.textContent = i18n.flushed || 'Flushed!';
|
||||
announce( btn.textContent );
|
||||
setTimeout(
|
||||
function () {
|
||||
btn.disabled = false;
|
||||
btn.textContent = i18n.flushLabel || originalLabel;
|
||||
},
|
||||
2000
|
||||
);
|
||||
} else {
|
||||
btn.disabled = false;
|
||||
btn.textContent = i18n.flushLabel || originalLabel;
|
||||
var msg = ( response && response.data ) ? String( response.data ) : ( i18n.error || 'Unknown error' );
|
||||
showNotice( msg, 'error' );
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
function () {
|
||||
btn.disabled = false;
|
||||
btn.textContent = i18n.flushLabel || originalLabel;
|
||||
showNotice( i18n.error || 'Request failed.', 'error' );
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-refresh module status on the Dashboard tab (every 30s).
|
||||
*/
|
||||
function bindStatusRefresh() {
|
||||
var isDashboard = document.querySelector( '.wpdo-wrap' )
|
||||
&& window.location.search.indexOf( 'tab=dashboard' ) !== -1;
|
||||
if ( ! isDashboard ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var timer = setInterval(
|
||||
function () {
|
||||
if ( ! document.hidden ) {
|
||||
refreshStatus();
|
||||
}
|
||||
},
|
||||
30000
|
||||
);
|
||||
|
||||
window.addEventListener(
|
||||
'beforeunload',
|
||||
function () {
|
||||
clearInterval( timer );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function refreshStatus() {
|
||||
wpdoAjax( 'module_status', {} )
|
||||
.then(
|
||||
function ( response ) {
|
||||
if ( ! response || ! response.success || ! response.data ) {
|
||||
return;
|
||||
}
|
||||
var data = response.data;
|
||||
var changed = 0;
|
||||
var changedSummaries = [];
|
||||
|
||||
document.querySelectorAll( '.wpdo-state' ).forEach(
|
||||
function ( el ) {
|
||||
var row = el.closest( 'tr' );
|
||||
var codeEl = row ? row.querySelector( 'code' ) : null;
|
||||
if ( ! codeEl ) {
|
||||
return;
|
||||
}
|
||||
var module = codeEl.textContent;
|
||||
if ( ! module || ! ( module in data ) ) {
|
||||
return;
|
||||
}
|
||||
var newState = data[ module ];
|
||||
if ( el.textContent === newState ) {
|
||||
return;
|
||||
}
|
||||
el.textContent = newState;
|
||||
el.className = 'wpdo-state wpdo-state-' + newState;
|
||||
changed++;
|
||||
changedSummaries.push( module + ' → ' + newState );
|
||||
}
|
||||
);
|
||||
|
||||
if ( changed > 0 ) {
|
||||
announce( changedSummaries.join( '、' ) );
|
||||
}
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
function () {
|
||||
// Fail silently on polling — user will see the stale state; not worth a notice.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
} )();
|
||||
Reference in New Issue
Block a user