Current File : /home/honehdyv/readbtooom.com/wp-content/plugins/autodescription/lib/js/le.js |
/**
* This file holds The SEO Framework plugin's JS code for WordPress List Edit adjustments.
* Serve JavaScript as an addition, not as an ends or means.
*
* @author Sybre Waaijer <https://cyberwire.nl/>
* @link <https://wordpress.org/plugins/autodescription/>
*/
/**
* The SEO Framework plugin
* Copyright (C) 2019 - 2023 Sybre Waaijer, CyberWire B.V. (https://cyberwire.nl/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
'use strict';
/**
* Holds tsfLe values in an object to avoid polluting global namespace.
*
* @since 4.0.0
*
* @constructor
*/
window.tsfLe = function() {
let dispatchTimeout;
/**
* Dispatches Le update event.
*
* @since 4.0.5
* @access private
*
* @function
*/
const _dispatchUpdate = () => {
clearTimeout( dispatchTimeout );
dispatchTimeout = setTimeout( () => {
document.dispatchEvent( new Event( 'tsfLeUpdated' ) );
}, 50 ); // 20fps
}
/**
* Runs after a list edit item has been updated.
*
* @since 4.0.0
* @access private
*
* @function
*/
const _updated = () => {
tsfTT?.triggerReset();
}
/**
* Sets inline post values for quick-edit.
*
* @since 4.0.0
* @access private
*
* @function
* @param {string} id
*/
const _setInlinePostValues = id => {
const data = JSON.parse( document.getElementById( `tsfLeData[${id}]` )?.dataset.le || 0 ) || {};
for ( const option in data ) {
const element = document.getElementById( 'autodescription-quick[%s]'.replace( '%s', option ) );
if ( ! element ) continue;
if ( data[ option ].isSelect ) {
tsf.selectByValue( element, data[ option ].value );
// Do `sprintf( 'Default (%s)', x.default )`.
const _default = element.querySelector( '[value="0"]' );
if ( _default )
_default.innerHTML = _default.innerHTML.replace( '%s', tsf.escapeString( tsf.decodeEntities( data[ option ].default ) ) );
} else {
element.value = tsf.decodeEntities( data[ option ].value );
if ( data[ option ].placeholder )
element.placeholder = tsf.decodeEntities( data[ option ].placeholder );
}
}
}
/**
* Sets inline term values for quick-edit.
* Copy of _setInlinePostValues(), for now.
*
* @since 4.0.0
* @access private
*
* @function
* @param {string} id
*/
const _setInlineTermValues = id => _setInlinePostValues( id );
/**
* Returns the postdata element, or an empty object.
*
* @since 4.1.4
* @access private
*
* @function
* @param {string} id
* @return {object}
*/
const _getPostData = id => JSON.parse(
document.getElementById( `tsfLePostData[${id}]` )?.dataset.lePostData || 0
) || {};
/**
* Sets private/protected visibility state.
*
* @since 4.1.0
* @access private
*
* @function
* @param {Event} event
*/
const _setTitleVisibilityPrefix = event => {
let target = ( event.originalEvent || event ).target,
titleId = target.dataset.tsfTitleId,
prefixValue = '',
visibility = 'public';
if ( 'keep_private' === target.name ) {
visibility = target.checked ? 'private' : 'public';
} else {
visibility = target.value && target.value.length ? 'password' : 'public';
}
switch ( visibility ) {
case 'password':
prefixValue = tsfTitle.protectedPrefix;
break;
case 'private':
prefixValue = tsfTitle.privatePrefix;
break;
default:
case 'public':
prefixValue = '';
break;
}
tsfTitle.updateStateOf( titleId, 'prefixValue', prefixValue );
}
/**
* Sets default title state.
*
* @since 4.1.0
* @since 4.1.4 Is now considerate of additionsForcedDisabled/additionsForceEnabled
* @access private
*
* @function
* @param {Event} event
*/
const _setDefaultTitle = event => {
const target = ( event.originalEvent || event ).target,
titleId = target.dataset?.tsfTitleId,
inputTitle = target.value?.trim() || '',
termPrefix = target.dataset?.termPrefix?.trim() || '';
let defaultTitle = tsfTitle.stripTitleTags ? tsf.stripTags( inputTitle ) : inputTitle;
defaultTitle ||= tsfTitle.untitledTitle;
if ( termPrefix.length ) {
if ( window.isRtl ) {
defaultTitle = `${defaultTitle} ${termPrefix}`;
} else {
defaultTitle = `${termPrefix} ${defaultTitle}`;
}
}
// TODO figure out if this is necessary. tsfTitle also escapes...
defaultTitle = tsf.escapeString( tsf.decodeEntities( defaultTitle.trim() ) );
tsfTitle.updateStateOf( titleId, 'defaultTitle', defaultTitle );
}
/**
* Augments and binds inline title input values for quick-edit.
*
* @since 4.1.0
* @access private
*
* @function
* @param {string} id
*/
const _prepareTitleInput = id => {
const titleId = 'autodescription-quick[doctitle]',
titleInput = document.getElementById( titleId );
if ( ! titleInput ) return;
// Reset and rebuild. Map won't be affected.
tsfTitle.setInputElement( titleInput );
const data = JSON.parse( document.getElementById( `tsfLeTitleData[${id}]` )?.dataset.leTitle || 0 );
if ( data ) {
tsfTitle.updateStateOf( titleId, 'allowReferenceChange', ! data.refTitleLocked );
tsfTitle.updateStateOf( titleId, 'defaultTitle', data.defaultTitle.trim() );
tsfTitle.updateStateOf( titleId, 'addAdditions', data.addAdditions );
tsfTitle.updateStateOf( titleId, 'additionValue', data.additionValue.trim() );
tsfTitle.updateStateOf( titleId, 'additionPlacement', data.additionPlacement );
}
let inlineEdit = document.getElementById( `edit-${id}` );
// inlineEdit is a wrapper of a clone of a template (#inline-edit). So, we must specifically target the cloned wrapper.
if ( inlineEdit ) { // this test should never return false...
inlineEdit.querySelectorAll( '[name=post_password]' ).forEach( element => {
element.dataset.tsfTitleId = titleId;
element.addEventListener( 'input', _setTitleVisibilityPrefix );
element.dispatchEvent( new CustomEvent( 'input' ) );
} );
inlineEdit.querySelectorAll( '[name=keep_private]' ).forEach( element => {
element.dataset.tsfTitleId = titleId;
element.addEventListener( 'click', _setTitleVisibilityPrefix );
element.dispatchEvent( new CustomEvent( 'click' ) );
} );
//= The homepage listens to a static preset value. Update all others.
// Post titles. TODO Should we use class "ptitle" instead?
inlineEdit.querySelectorAll( '[name=post_title]' ).forEach( element => {
element.dataset.tsfTitleId = titleId;
// tsfTitle shouldn't be aware of this--since we remove the prefix on-input.
// element.dataset.termPrefix = termPrefix;
if ( ! _getPostData( id ).isFront ) {
element.addEventListener( 'input', _setDefaultTitle );
element.dispatchEvent( new CustomEvent( 'input' ) );
}
} );
// Term titles. TODO Should we use class "ptitle" instead?
inlineEdit.querySelectorAll( '[name=name]' ).forEach( element => {
element.dataset.tsfTitleId = titleId;
// tsfTitle shouldn't be aware of this--since we remove the prefix on-input.
element.dataset.termPrefix = data.termPrefix || '';
element.addEventListener( 'input', _setDefaultTitle );
element.dispatchEvent( new CustomEvent( 'input' ) );
} );
}
tsfTT?.triggerReset();
}
/**
* Augments and binds inline description input values for quick-edit.
*
* @since 4.1.0
* @access private
*
* @function
* @param {string} id
*/
const _prepareDescriptionInput = id => {
const descId = 'autodescription-quick[description]',
descInput = document.getElementById( descId );
if ( ! descInput ) return;
// Reset and rebuild. Map won't be affected.
tsfDescription.setInputElement( descInput );
const data = JSON.parse( document.getElementById( `tsfLeDescriptionData[${id}]` )?.dataset.leDescription || 0 );
if ( data ) {
tsfDescription.updateStateOf( descId, 'allowReferenceChange', ! data.refDescriptionLocked );
tsfDescription.updateStateOf( descId, 'defaultDescription', data.defaultDescription.trim() );
}
tsfTT.triggerReset();
}
/**
* Initializes List-edit listeners on ready.
*
* @since 4.0.0
* @access private
*
* @function
*/
const _setListeners = () => {
document.addEventListener( 'tsfLeDispatchUpdate', _dispatchUpdate );
document.addEventListener( 'tsfLeUpdated', _updated );
}
/**
* Hijacks the quick and bulk-edit listeners.
*
* NOTE: The bulk-editor doesn't need adjusting, yet.
* Moreover, the bulk-edit doesn't have a "save" callback, because it's
* not using AJAX to save data.
*
* @since 4.0.0
* @access private
*
* @function
*/
const _hijackListeners = () => {
let _oldInlineEditPost,
_oldInlineEditTax;
_oldInlineEditPost = window.inlineEditPost?.edit;
if ( _oldInlineEditPost ) {
window.inlineEditPost.edit = function( id ) {
let ret = _oldInlineEditPost.apply( this, arguments );
if ( 'object' === typeof id )
id = window.inlineEditPost?.getId( id );
if ( ! id ) return ret;
_setInlinePostValues( id );
_prepareTitleInput( id );
_prepareDescriptionInput( id );
window.tsfC?.resetCounterListener();
return ret;
}
}
_oldInlineEditTax = window.inlineEditTax?.edit;
if ( _oldInlineEditTax ) {
window.inlineEditTax.edit = function( id ) {
let ret = _oldInlineEditTax.apply( this, arguments );
if ( 'object' === typeof id )
id = window.inlineEditTax?.getId( id );
if ( ! id ) return ret;
_setInlineTermValues( id );
_prepareTitleInput( id );
_prepareDescriptionInput( id );
window.tsfC?.resetCounterListener();
return ret;
}
}
}
return {
/**
* Initialises all aspects of the scripts.
* You shouldn't call this.
*
* @since 4.0.0
* @access protected
*
* @function
*/
load: () => {
document.body.addEventListener( 'tsf-onload', _setListeners );
document.body.addEventListener( 'tsf-onload', _hijackListeners );
}
};
}();
window.tsfLe.load();