6f117f4e9b
Anti-EAV Lint + Quality Gate / anti-eav-lint (pull_request) Successful in 21s
Tests / PHP Lint (pull_request) Successful in 18s
Tests / Unit Tests (pull_request) Successful in 41s
Tests / Integration Tests (pull_request) Successful in 1m25s
Tests / PHPCS (pull_request) Successful in 44s
Tests / PHPStan (pull_request) Successful in 47s
- Archive sweep waits until idx_original_meta exists (a plugin update does not run dbDelta; without the index NOT EXISTS scans the archive per row) - Duplicate archive cleanup runs from WP-CLI only, never in a web activation - Uninstall keeps the LatePoint add-on's tmdo_latepoint_db_version - AJAX save errors stay on screen instead of fading after 2.5 s - Verify: 2 new integration tests; unit 711, integration 612, phpcs 0, stan OK - PR: PR-141 (2.4.2 correctness review)
110 lines
2.8 KiB
JavaScript
110 lines
2.8 KiB
JavaScript
/**
|
|
* WP Data Optimizer — Settings per-section instant save.
|
|
*
|
|
* Each .wpdo-settings-section card has a "儲存此區塊" button that posts only
|
|
* that section's fields via AJAX, updating options without a full page reload.
|
|
*
|
|
* @since 3.0.2
|
|
*/
|
|
/* global wpdoSettings */
|
|
( function () {
|
|
'use strict';
|
|
|
|
if ( typeof wpdoSettings === 'undefined' ) {
|
|
return;
|
|
}
|
|
|
|
const { ajaxUrl, nonce, i18n } = wpdoSettings;
|
|
|
|
/**
|
|
* Collect form fields within a section into a FormData object.
|
|
* Unchecked checkboxes are intentionally omitted (server does isset() ? '1' : '0').
|
|
*
|
|
* @param {HTMLElement} section
|
|
* @returns {FormData}
|
|
*/
|
|
function collectFields( section ) {
|
|
const fd = new FormData();
|
|
section.querySelectorAll( 'input, select, textarea' ).forEach( ( el ) => {
|
|
if ( ! el.name ) {
|
|
return;
|
|
}
|
|
if ( el.type === 'checkbox' ) {
|
|
if ( el.checked ) {
|
|
fd.append( el.name, el.value );
|
|
}
|
|
} else if ( el.type === 'radio' ) {
|
|
if ( el.checked ) {
|
|
fd.append( el.name, el.value );
|
|
}
|
|
} else {
|
|
fd.append( el.name, el.value );
|
|
}
|
|
} );
|
|
return fd;
|
|
}
|
|
|
|
/**
|
|
* Show a status message; success fades out after 2.5s, errors stay.
|
|
*
|
|
* @param {HTMLElement} statusEl
|
|
* @param {string} message
|
|
* @param {boolean} isError
|
|
*/
|
|
function showStatus( statusEl, message, isError ) {
|
|
statusEl.textContent = message;
|
|
statusEl.style.color = isError ? 'var(--color-error, #b03d3d)' : 'var(--color-success, #5a8c5a)';
|
|
statusEl.classList.add( 'visible' );
|
|
clearTimeout( statusEl._wpdo_timer );
|
|
if ( isError ) {
|
|
return;
|
|
}
|
|
statusEl._wpdo_timer = setTimeout( () => {
|
|
statusEl.classList.remove( 'visible' );
|
|
}, 2500 );
|
|
}
|
|
|
|
document.addEventListener( 'click', function ( e ) {
|
|
const btn = e.target.closest( '.wpdo-section-save' );
|
|
if ( ! btn ) {
|
|
return;
|
|
}
|
|
const section = btn.closest( '.wpdo-settings-section' );
|
|
const statusEl = btn.nextElementSibling;
|
|
const sectionKey = section ? section.dataset.section : '';
|
|
if ( ! sectionKey ) {
|
|
return;
|
|
}
|
|
|
|
const originalLabel = btn.textContent;
|
|
btn.disabled = true;
|
|
btn.textContent = i18n.saving;
|
|
|
|
const fd = collectFields( section );
|
|
fd.append( 'action', 'wpdo_save_settings_section' );
|
|
fd.append( '_ajax_nonce', nonce );
|
|
fd.append( 'section', sectionKey );
|
|
|
|
fetch( ajaxUrl, {
|
|
method : 'POST',
|
|
credentials : 'same-origin',
|
|
body : fd,
|
|
} )
|
|
.then( ( r ) => r.json() )
|
|
.then( ( data ) => {
|
|
if ( data.success ) {
|
|
showStatus( statusEl, i18n.saved, false );
|
|
} else {
|
|
showStatus( statusEl, ( data.data && data.data.message ) || i18n.error, true );
|
|
}
|
|
} )
|
|
.catch( () => {
|
|
showStatus( statusEl, i18n.error, true );
|
|
} )
|
|
.finally( () => {
|
|
btn.disabled = false;
|
|
btn.textContent = originalLabel;
|
|
} );
|
|
} );
|
|
} )();
|