221 lines
6.3 KiB
JavaScript
221 lines
6.3 KiB
JavaScript
/**
|
|
* Handles the options in the language switcher nav menu metabox.
|
|
*
|
|
* @package Polylang
|
|
*/
|
|
|
|
const pllNavMenu = {
|
|
/**
|
|
* The element wrapping the menu elements.
|
|
*
|
|
* @member {HTMLElement|null}
|
|
*/
|
|
wrapper: null,
|
|
|
|
/**
|
|
* Init.
|
|
*/
|
|
init: () => {
|
|
if ( document.readyState !== 'loading' ) {
|
|
pllNavMenu.ready();
|
|
} else {
|
|
document.addEventListener( 'DOMContentLoaded', pllNavMenu.ready );
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Called when the DOM is ready. Attaches the events to the wrapper.
|
|
*/
|
|
ready: () => {
|
|
pllNavMenu.wrapper = document.getElementById( 'menu-to-edit' );
|
|
|
|
if ( ! pllNavMenu.wrapper ) {
|
|
return;
|
|
}
|
|
|
|
pllNavMenu.wrapper.addEventListener( 'click', pllNavMenu.printMetabox );
|
|
pllNavMenu.wrapper.addEventListener( 'change', pllNavMenu.ensureContent );
|
|
pllNavMenu.wrapper.addEventListener( 'change', pllNavMenu.showHideRows );
|
|
},
|
|
|
|
printMetabox: {
|
|
/**
|
|
* Event callback that prints our checkboxes in the language switcher.
|
|
*
|
|
* @param {Event} event The event.
|
|
*/
|
|
handleEvent: ( event ) => {
|
|
if ( ! event.target.classList.contains( 'item-edit' ) ) {
|
|
// Not clicking on a Edit arrow button.
|
|
return;
|
|
}
|
|
|
|
const metabox = event.target.closest( '.menu-item' ).querySelector( '.menu-item-settings' );
|
|
|
|
if ( ! metabox?.id ) {
|
|
// Should not happen.
|
|
return;
|
|
}
|
|
|
|
if ( ! metabox.querySelectorAll( 'input[value="#pll_switcher"][type=text]' ).length ) {
|
|
// Not our metabox, or already replaced.
|
|
return;
|
|
}
|
|
|
|
// Remove default fields we don't need.
|
|
[ ...metabox.children ].forEach( ( el ) => {
|
|
if ( 'P' === el.nodeName && ! el.classList.contains( 'field-move' ) ) {
|
|
el.remove();
|
|
}
|
|
} );
|
|
|
|
const t = pllNavMenu.printMetabox;
|
|
const itemId = Number( metabox.id.replace( 'menu-item-settings-', '' ) );
|
|
|
|
metabox.append( t.createHiddenInput( 'title', itemId, pll_data.title ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
|
metabox.append( t.createHiddenInput( 'url', itemId, '#pll_switcher' ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
|
metabox.append( t.createHiddenInput( 'pll-detect', itemId, 1 ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
|
|
|
const ids = Array( 'hide_if_no_translation', 'hide_current', 'force_home', 'show_flags', 'show_names', 'dropdown' ); // Reverse order.
|
|
const isValDefined = typeof( pll_data.val[ itemId ] ) !== 'undefined';
|
|
|
|
ids.forEach( ( optionName ) => {
|
|
// Create the checkbox's wrapper.
|
|
const inputWrapper = t.createElement( 'p', { class: 'description' } );
|
|
|
|
if ( 'hide_current' === optionName && isValDefined && 1 === pll_data.val[ itemId ].dropdown ) {
|
|
// Hide the `hide_current` checkbox if `dropdown` is checked.
|
|
inputWrapper.classList.add( 'hidden' );
|
|
}
|
|
|
|
metabox.prepend( inputWrapper ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
|
|
|
// Create the checkbox's label.
|
|
const inputId = `edit-menu-item-${ optionName }-${ itemId }`;
|
|
const label = t.createElement( 'label', { 'for': inputId } );
|
|
label.innerText = ` ${ pll_data.strings[ optionName ] }`;
|
|
|
|
inputWrapper.append( label ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
|
|
|
// Create the checkbox.
|
|
const cb = t.createElement( 'input', {
|
|
type: 'checkbox',
|
|
id: inputId,
|
|
name: `menu-item-${ optionName }[${ itemId }]`,
|
|
value: 1,
|
|
} );
|
|
|
|
if ( ( isValDefined && 1 === pll_data.val[ itemId ][ optionName ] ) || ( ! isValDefined && 'show_names' === optionName ) ) { // `show_names` as default value.
|
|
cb.checked = true;
|
|
}
|
|
|
|
label.prepend( cb ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Creates and returns a `<input type=hidden"/>` element.
|
|
*
|
|
* @param {string} id An identifier for this input. It will be part of the final `id` attribute.
|
|
* @param {number} itemId The ID of the menu element (post ID).
|
|
* @param {string|number} value The input's value.
|
|
* @return {HTMLElement} The input element.
|
|
*/
|
|
createHiddenInput: ( id, itemId, value ) => {
|
|
return pllNavMenu.printMetabox.createElement( 'input', {
|
|
type: 'hidden',
|
|
id: `edit-menu-item-${ id }-${ itemId }`,
|
|
name: `menu-item-${ id }[${ itemId }]`,
|
|
value: value,
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Creates and returns an element.
|
|
*
|
|
* @param {string} type Element's type.
|
|
* @param {Object} atts Element's attributes.
|
|
* @return {HTMLElement} The element.
|
|
*/
|
|
createElement: ( type, atts ) => {
|
|
const el = document.createElement( type );
|
|
for ( const [ key, value ] of Object.entries( atts ) ) {
|
|
el.setAttribute( key, value );
|
|
}
|
|
return el;
|
|
},
|
|
},
|
|
|
|
ensureContent: {
|
|
regExpr: new RegExp( /^edit-menu-item-show_(names|flags)-(\d+)$/ ),
|
|
|
|
/**
|
|
* Event callback that disallows unchecking both `show_names` and `show_flags`.
|
|
*
|
|
* @param {Event} event The event.
|
|
*/
|
|
handleEvent: ( event ) => {
|
|
if ( ! event.target.id || event.target.checked ) {
|
|
// Now checked, nothing to do.
|
|
return;
|
|
}
|
|
|
|
const matches = event.target.id.match( pllNavMenu.ensureContent.regExpr );
|
|
|
|
if ( ! matches ) {
|
|
// Not the checkbox we want.
|
|
return;
|
|
}
|
|
|
|
// Check the other checkbox.
|
|
const [ , type, id ] = matches;
|
|
const otherType = 'names' === type ? 'flags' : 'names';
|
|
document.getElementById( `edit-menu-item-show_${ otherType }-${ id }` ).checked = true;
|
|
},
|
|
},
|
|
|
|
showHideRows: {
|
|
regExpr: new RegExp( /^edit-menu-item-dropdown-(\d+)$/ ),
|
|
|
|
/**
|
|
* Event callback that shows or hides the `hide_current` checkbox when `dropdown` is checked.
|
|
*
|
|
* @param {Event} event The event.
|
|
*/
|
|
handleEvent: ( event ) => {
|
|
if ( ! event.target.id ) {
|
|
// Not the checkbox we want.
|
|
return;
|
|
}
|
|
|
|
const matches = event.target.id.match( pllNavMenu.showHideRows.regExpr );
|
|
|
|
if ( ! matches ) {
|
|
// Not the checkbox we want.
|
|
return;
|
|
}
|
|
|
|
const hideCb = document.getElementById( `edit-menu-item-hide_current-${ matches[1] }` );
|
|
|
|
if ( ! hideCb ) {
|
|
// Should not happen.
|
|
return;
|
|
}
|
|
|
|
const description = hideCb.closest( '.description' );
|
|
|
|
// Hide or show.
|
|
description.classList.toggle( 'hidden', event.target.checked );
|
|
|
|
if ( event.target.checked ) {
|
|
// Uncheck after hiding.
|
|
hideCb.checked = false;
|
|
hideCb.dispatchEvent( new Event( 'change' ) );
|
|
}
|
|
},
|
|
},
|
|
};
|
|
|
|
pllNavMenu.init();
|
|
|