/**
* Simple Custom Post Order — optional "Order" column.
*
* Type an absolute position into a row's Order field and press Enter (or blur);
* the item jumps to that position across the whole list, regardless of which
* paginated page you're on. Posts same-origin to the reorder endpoint.
*
* Enabled by the "Order column" setting (off by default).
*
* Error handling mirrors the drag-and-drop sorter (scporder-sortablejs.js):
* tolerate stray output from other plugins, transparently refresh an expired
* nonce and retry, retry once on a network blip, and report the server's own
* message instead of one generic string for every failure. Before 2.8.6 this
* script did none of that — a long-open list screen, a PHP notice printed by
* another plugin, or a permissions problem all surfaced as the same
* "Couldn't update the order" alert with no way to tell them apart.
*/
( function () {
'use strict';
var vars = window.scpoOrderCol;
if ( ! vars ) {
return;
}
// Always resolve to the current page's origin (proxies / ports / https).
function endpoint() {
try {
var u = new URL( vars.ajax_url, window.location.href );
u.protocol = window.location.protocol;
u.host = window.location.host;
return u.toString();
} catch ( e ) {
return vars.ajax_url;
}
}
function post( body ) {
return fetch( endpoint(), {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body,
} );
}
/**
* Fetch a fresh reorder nonce so this save (and later ones) use a valid one.
* The endpoint is authenticated and deliberately nonce-less — a stale nonce
* is the very reason we're calling it.
*/
function refreshNonce( done ) {
post( 'action=scpo_refresh_nonce' )
.then( function ( res ) {
return res.ok ? res.json() : null;
} )
.then( function ( json ) {
if ( json && json.success && json.data && json.data.nonce ) {
vars.nonce = json.data.nonce;
done( true );
} else {
done( false );
}
} )
.catch( function () {
done( false );
} );
}
function fail( input, message ) {
input.classList.remove( 'is-saving' );
window.alert( message || vars.error );
}
function commit( input, opts ) {
var id = input.getAttribute( 'data-id' );
var pos = parseInt( input.value, 10 );
if ( ! id || ! pos || pos < 1 ) {
return;
}
opts = opts || { netRetries: 1, nonceRefreshed: false };
input.classList.add( 'is-saving' );
var body = new URLSearchParams();
body.set( 'action', 'scpo_set_position' );
body.set( 'id', id );
body.set( 'position', pos );
body.set( 'nonce', vars.nonce );
post( body.toString() )
.then( function ( res ) {
return res.text().then( function ( text ) {
var json = null;
try {
json = JSON.parse( text );
} catch ( e ) {} // tolerate stray output from other plugins
// A plugin printing a notice before the JSON used to make this
// look like a failure even though the order had been saved.
// Recover the payload from anywhere in the body.
if ( ! json ) {
var brace = text.indexOf( '{' );
if ( brace > -1 ) {
try {
json = JSON.parse( text.slice( brace ) );
} catch ( e2 ) {}
}
}
return {
ok: !! ( json && json.success ),
// admin-ajax answers "-1" when the nonce is stale/invalid.
staleNonce: text.trim() === '-1' || text.slice( -2 ).trim() === '-1',
message: json && json.data && json.data.message ? json.data.message : '',
};
} );
} )
.then( function ( r ) {
if ( r.ok ) {
// Reload so every row's number + pagination reflect the new order.
window.location.reload();
return;
}
// Expired nonce (long-open screen / short nonce_life): fetch a fresh
// one and retry the save exactly once — invisible to the user.
if ( r.staleNonce && ! opts.nonceRefreshed ) {
refreshNonce( function ( refreshed ) {
if ( refreshed ) {
commit( input, { netRetries: 1, nonceRefreshed: true } );
} else {
fail( input, vars.expired );
}
} );
return;
}
if ( r.staleNonce ) {
fail( input, vars.expired );
return;
}
// Genuine rejection — show what the server actually said
// ("Permission denied.", "Invalid item.") rather than a generic string.
fail( input, r.message );
} )
.catch( function () {
// Transient/network error (offline, blip): retry once, then give up.
if ( opts.netRetries > 0 ) {
setTimeout( function () {
commit( input, {
netRetries: opts.netRetries - 1,
nonceRefreshed: opts.nonceRefreshed,
} );
}, 800 );
return;
}
fail( input, vars.network );
} );
}
// `change` covers blur and Enter on number inputs.
document.addEventListener( 'change', function ( e ) {
var input = e.target;
if ( input && input.classList && input.classList.contains( 'scpo-order-input' ) ) {
commit( input );
}
} );
// Enter shouldn't submit any surrounding form; commit instead.
document.addEventListener( 'keydown', function ( e ) {
var input = e.target;
if ( e.key === 'Enter' && input && input.classList && input.classList.contains( 'scpo-order-input' ) ) {
e.preventDefault();
commit( input );
}
} );
} )();
Warning: Cannot modify header information - headers already sent by (output started at /home/u254154228/domains/pakknitloom.com/public_html/wp-content/themes/hello-elementor/functions.php:1) in /home/u254154228/domains/pakknitloom.com/public_html/wp-includes/pluggable.php on line 1531
Warning: Cannot modify header information - headers already sent by (output started at /home/u254154228/domains/pakknitloom.com/public_html/wp-content/themes/hello-elementor/functions.php:1) in /home/u254154228/domains/pakknitloom.com/public_html/wp-includes/pluggable.php on line 1534