Current File : /home/bdmcricketindia.in/public_html/wp-admin/js/widgets/custom-html-widgets.js
/**
 * @output wp-admin/js/widgets/custom-html-widgets.js
 */

/* global wp */
/* eslint consistent-this: [ "error", "control" ] */
/* eslint no-magic-numbers: ["error", { "ignore": [0,1,-1] }] */

/**
 * @namespace wp.customHtmlWidget
 * @memberOf wp
 */
wp.customHtmlWidgets = ( function( $ ) {
	'use strict';

	var component = {
		idBases: [ 'custom_html' ],
		codeEditorSettings: {},
		l10n: {
			errorNotice: {
				singular: '',
				plural: ''
			}
		}
	};

	component.CustomHtmlWidgetControl = Backbone.View.extend(/** @lends wp.customHtmlWidgets.CustomHtmlWidgetControl.prototype */{

		/**
		 * View events.
		 *
		 * @type {Object}
		 */
		events: {},

		/**
		 * Text widget control.
		 *
		 * @constructs wp.customHtmlWidgets.CustomHtmlWidgetControl
		 * @augments Backbone.View
		 * @abstract
		 *
		 * @param {Object} options - Options.
		 * @param {jQuery} options.el - Control field container element.
		 * @param {jQuery} options.syncContainer - Container element where fields are synced for the server.
		 *
		 * @return {void}
		 */
		initialize: function initialize( options ) {
			var control = this;

			if ( ! options.el ) {
				throw new Error( 'Missing options.el' );
			}
			if ( ! options.syncContainer ) {
				throw new Error( 'Missing options.syncContainer' );
			}

			Backbone.View.prototype.initialize.call( control, options );
			control.syncContainer = options.syncContainer;
			control.widgetIdBase = control.syncContainer.parent().find( '.id_base' ).val();
			control.widgetNumber = control.syncContainer.parent().find( '.widget_number' ).val();
			control.customizeSettingId = 'widget_' + control.widgetIdBase + '[' + String( control.widgetNumber ) + ']';

			control.$el.addClass( 'custom-html-widget-fields' );
			control.$el.html( wp.template( 'widget-custom-html-control-fields' )( { codeEditorDisabled: component.codeEditorSettings.disabled } ) );

			control.errorNoticeContainer = control.$el.find( '.code-editor-error-container' );
			control.currentErrorAnnotations = [];
			control.saveButton = control.syncContainer.add( control.syncContainer.parent().find( '.widget-control-actions' ) ).find( '.widget-control-save, #savewidget' );
			control.saveButton.addClass( 'custom-html-widget-save-button' ); // To facilitate style targeting.

			control.fields = {
				title: control.$el.find( '.title' ),
				content: control.$el.find( '.content' )
			};

			// Sync input fields to hidden sync fields which actually get sent to the server.
			_.each( control.fields, function( fieldInput, fieldName ) {
				fieldInput.on( 'input change', function updateSyncField() {
					var syncInput = control.syncContainer.find( '.sync-input.' + fieldName );
					if ( syncInput.val() !== fieldInput.val() ) {
						syncInput.val( fieldInput.val() );
						syncInput.trigger( 'change' );
					}
				});

				// Note that syncInput cannot be re-used because it will be destroyed with each widget-updated event.
				fieldInput.val( control.syncContainer.find( '.sync-input.' + fieldName ).val() );
			});
		},

		/**
		 * Update input fields from the sync fields.
		 *
		 * This function is called at the widget-updated and widget-synced events.
		 * A field will only be updated if it is not currently focused, to avoid
		 * overwriting content that the user is entering.
		 *
		 * @return {void}
		 */
		updateFields: function updateFields() {
			var control = this, syncInput;

			if ( ! control.fields.title.is( document.activeElement ) ) {
				syncInput = control.syncContainer.find( '.sync-input.title' );
				control.fields.title.val( syncInput.val() );
			}

			/*
			 * Prevent updating content when the editor is focused or if there are current error annotations,
			 * to prevent the editor's contents from getting sanitized as soon as a user removes focus from
			 * the editor. This is particularly important for users who cannot unfiltered_html.
			 */
			control.contentUpdateBypassed = control.fields.content.is( document.activeElement ) || control.editor && control.editor.codemirror.state.focused || 0 !== control.currentErrorAnnotations.length;
			if ( ! control.contentUpdateBypassed ) {
				syncInput = control.syncContainer.find( '.sync-input.content' );
				control.fields.content.val( syncInput.val() );
			}
		},

		/**
		 * Show linting error notice.
		 *
		 * @param {Array} errorAnnotations - Error annotations.
		 * @return {void}
		 */
		updateErrorNotice: function( errorAnnotations ) {
			var control = this, errorNotice, message = '', customizeSetting;

			if ( 1 === errorAnnotations.length ) {
				message = component.l10n.errorNotice.singular.replace( '%d', '1' );
			} else if ( errorAnnotations.length > 1 ) {
				message = component.l10n.errorNotice.plural.replace( '%d', String( errorAnnotations.length ) );
			}

			if ( control.fields.content[0].setCustomValidity ) {
				control.fields.content[0].setCustomValidity( message );
			}

			if ( wp.customize && wp.customize.has( control.customizeSettingId ) ) {
				customizeSetting = wp.customize( control.customizeSettingId );
				customizeSetting.notifications.remove( 'htmlhint_error' );
				if ( 0 !== errorAnnotations.length ) {
					customizeSetting.notifications.add( 'htmlhint_error', new wp.customize.Notification( 'htmlhint_error', {
						message: message,
						type: 'error'
					} ) );
				}
			} else if ( 0 !== errorAnnotations.length ) {
				errorNotice = $( '<div class="inline notice notice-error notice-alt" role="alert"></div>' );
				errorNotice.append( $( '<p></p>', {
					text: message
				} ) );
				control.errorNoticeContainer.empty();
				control.errorNoticeContainer.append( errorNotice );
				control.errorNoticeContainer.slideDown( 'fast' );
				wp.a11y.speak( message );
			} else {
				control.errorNoticeContainer.slideUp( 'fast' );
			}
		},

		/**
		 * Initialize editor.
		 *
		 * @return {void}
		 */
		initializeEditor: function initializeEditor() {
			var control = this, settings;

			if ( component.codeEditorSettings.disabled ) {
				return;
			}

			settings = _.extend( {}, component.codeEditorSettings, {

				/**
				 * Handle tabbing to the field before the editor.
				 *
				 * @ignore
				 *
				 * @return {void}
				 */
				onTabPrevious: function onTabPrevious() {
					control.fields.title.focus();
				},

				/**
				 * Handle tabbing to the field after the editor.
				 *
				 * @ignore
				 *
				 * @return {void}
				 */
				onTabNext: function onTabNext() {
					var tabbables = control.syncContainer.add( control.syncContainer.parent().find( '.widget-position, .widget-control-actions' ) ).find( ':tabbable' );
					tabbables.first().focus();
				},

				/**
				 * Disable save button and store linting errors for use in updateFields.
				 *
				 * @ignore
				 *
				 * @param {Array} errorAnnotations - Error notifications.
				 * @return {void}
				 */
				onChangeLintingErrors: function onChangeLintingErrors( errorAnnotations ) {
					control.currentErrorAnnotations = errorAnnotations;
				},

				/**
				 * Update error notice.
				 *
				 * @ignore
				 *
				 * @param {Array} errorAnnotations - Error annotations.
				 * @return {void}
				 */
				onUpdateErrorNotice: function onUpdateErrorNotice( errorAnnotations ) {
					control.saveButton.toggleClass( 'validation-blocked disabled', errorAnnotations.length > 0 );
					control.updateErrorNotice( errorAnnotations );
				}
			});

			control.editor = wp.codeEditor.initialize( control.fields.content, settings );

			// Improve the editor accessibility.
			$( control.editor.codemirror.display.lineDiv )
				.attr({
					role: 'textbox',
					'aria-multiline': 'true',
					'aria-labelledby': control.fields.content[0].id + '-label',
					'aria-describedby': 'editor-keyboard-trap-help-1 editor-keyboard-trap-help-2 editor-keyboard-trap-help-3 editor-keyboard-trap-help-4'
				});

			// Focus the editor when clicking on its label.
			$( '#' + control.fields.content[0].id + '-label' ).on( 'click', function() {
				control.editor.codemirror.focus();
			});

			control.fields.content.on( 'change', function() {
				if ( this.value !== control.editor.codemirror.getValue() ) {
					control.editor.codemirror.setValue( this.value );
				}
			});
			control.editor.codemirror.on( 'change', function() {
				var value = control.editor.codemirror.getValue();
				if ( value !== control.fields.content.val() ) {
					control.fields.content.val( value ).trigger( 'change' );
				}
			});

			// Make sure the editor gets updated if the content was updated on the server (sanitization) but not updated in the editor since it was focused.
			control.editor.codemirror.on( 'blur', function() {
				if ( control.contentUpdateBypassed ) {
					control.syncContainer.find( '.sync-input.content' ).trigger( 'change' );
				}
			});

			// Prevent hitting Esc from collapsing the widget control.
			if ( wp.customize ) {
				control.editor.codemirror.on( 'keydown', function onKeydown( codemirror, event ) {
					var escKeyCode = 27;
					if ( escKeyCode === event.keyCode ) {
						event.stopPropagation();
					}
				});
			}
		}
	});

	/**
	 * Mapping of widget ID to instances of CustomHtmlWidgetControl subclasses.
	 *
	 * @alias wp.customHtmlWidgets.widgetControls
	 *
	 * @type {Object.<string, wp.textWidgets.CustomHtmlWidgetControl>}
	 */
	component.widgetControls = {};

	/**
	 * Handle widget being added or initialized for the first time at the widget-added event.
	 *
	 * @alias wp.customHtmlWidgets.handleWidgetAdded
	 *
	 * @param {jQuery.Event} event - Event.
	 * @param {jQuery}       widgetContainer - Widget container element.
	 *
	 * @return {void}
	 */
	component.handleWidgetAdded = function handleWidgetAdded( event, widgetContainer ) {
		var widgetForm, idBase, widgetControl, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone, fieldContainer, syncContainer;
		widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen.

		idBase = widgetForm.find( '> .id_base' ).val();
		if ( -1 === component.idBases.indexOf( idBase ) ) {
			return;
		}

		// Prevent initializing already-added widgets.
		widgetId = widgetForm.find( '.widget-id' ).val();
		if ( component.widgetControls[ widgetId ] ) {
			return;
		}

		/*
		 * Create a container element for the widget control fields.
		 * This is inserted into the DOM immediately before the the .widget-content
		 * element because the contents of this element are essentially "managed"
		 * by PHP, where each widget update cause the entire element to be emptied
		 * and replaced with the rendered output of WP_Widget::form() which is
		 * sent back in Ajax request made to save/update the widget instance.
		 * To prevent a "flash of replaced DOM elements and re-initialized JS
		 * components", the JS template is rendered outside of the normal form
		 * container.
		 */
		fieldContainer = $( '<div></div>' );
		syncContainer = widgetContainer.find( '.widget-content:first' );
		syncContainer.before( fieldContainer );

		widgetControl = new component.CustomHtmlWidgetControl({
			el: fieldContainer,
			syncContainer: syncContainer
		});

		component.widgetControls[ widgetId ] = widgetControl;

		/*
		 * Render the widget once the widget parent's container finishes animating,
		 * as the widget-added event fires with a slideDown of the container.
		 * This ensures that the textarea is visible and the editor can be initialized.
		 */
		renderWhenAnimationDone = function() {
			if ( ! ( wp.customize ? widgetContainer.parent().hasClass( 'expanded' ) : widgetContainer.hasClass( 'open' ) ) ) { // Core merge: The wp.customize condition can be eliminated with this change being in core: https://github.com/xwp/wordpress-develop/pull/247/commits/5322387d
				setTimeout( renderWhenAnimationDone, animatedCheckDelay );
			} else {
				widgetControl.initializeEditor();
			}
		};
		renderWhenAnimationDone();
	};

	/**
	 * Setup widget in accessibility mode.
	 *
	 * @alias wp.customHtmlWidgets.setupAccessibleMode
	 *
	 * @return {void}
	 */
	component.setupAccessibleMode = function setupAccessibleMode() {
		var widgetForm, idBase, widgetControl, fieldContainer, syncContainer;
		widgetForm = $( '.editwidget > form' );
		if ( 0 === widgetForm.length ) {
			return;
		}

		idBase = widgetForm.find( '.id_base' ).val();
		if ( -1 === component.idBases.indexOf( idBase ) ) {
			return;
		}

		fieldContainer = $( '<div></div>' );
		syncContainer = widgetForm.find( '> .widget-inside' );
		syncContainer.before( fieldContainer );

		widgetControl = new component.CustomHtmlWidgetControl({
			el: fieldContainer,
			syncContainer: syncContainer
		});

		widgetControl.initializeEditor();
	};

	/**
	 * Sync widget instance data sanitized from server back onto widget model.
	 *
	 * This gets called via the 'widget-updated' event when saving a widget from
	 * the widgets admin screen and also via the 'widget-synced' event when making
	 * a change to a widget in the customizer.
	 *
	 * @alias wp.customHtmlWidgets.handleWidgetUpdated
	 *
	 * @param {jQuery.Event} event - Event.
	 * @param {jQuery}       widgetContainer - Widget container element.
	 * @return {void}
	 */
	component.handleWidgetUpdated = function handleWidgetUpdated( event, widgetContainer ) {
		var widgetForm, widgetId, widgetControl, idBase;
		widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' );

		idBase = widgetForm.find( '> .id_base' ).val();
		if ( -1 === component.idBases.indexOf( idBase ) ) {
			return;
		}

		widgetId = widgetForm.find( '> .widget-id' ).val();
		widgetControl = component.widgetControls[ widgetId ];
		if ( ! widgetControl ) {
			return;
		}

		widgetControl.updateFields();
	};

	/**
	 * Initialize functionality.
	 *
	 * This function exists to prevent the JS file from having to boot itself.
	 * When WordPress enqueues this script, it should have an inline script
	 * attached which calls wp.textWidgets.init().
	 *
	 * @alias wp.customHtmlWidgets.init
	 *
	 * @param {Object} settings - Options for code editor, exported from PHP.
	 *
	 * @return {void}
	 */
	component.init = function init( settings ) {
		var $document = $( document );
		_.extend( component.codeEditorSettings, settings );

		$document.on( 'widget-added', component.handleWidgetAdded );
		$document.on( 'widget-synced widget-updated', component.handleWidgetUpdated );

		/*
		 * Manually trigger widget-added events for media widgets on the admin
		 * screen once they are expanded. The widget-added event is not triggered
		 * for each pre-existing widget on the widgets admin screen like it is
		 * on the customizer. Likewise, the customizer only triggers widget-added
		 * when the widget is expanded to just-in-time construct the widget form
		 * when it is actually going to be displayed. So the following implements
		 * the same for the widgets admin screen, to invoke the widget-added
		 * handler when a pre-existing media widget is expanded.
		 */
		$( function initializeExistingWidgetContainers() {
			var widgetContainers;
			if ( 'widgets' !== window.pagenow ) {
				return;
			}
			widgetContainers = $( '.widgets-holder-wrap:not(#available-widgets)' ).find( 'div.widget' );
			widgetContainers.one( 'click.toggle-widget-expanded', function toggleWidgetExpanded() {
				var widgetContainer = $( this );
				component.handleWidgetAdded( new jQuery.Event( 'widget-added' ), widgetContainer );
			});

			// Accessibility mode.
			if ( document.readyState === 'complete' ) {
				// Page is fully loaded.
				component.setupAccessibleMode();
			} else {
				// Page is still loading.
				$( window ).on( 'load', function() {
					component.setupAccessibleMode();
				});
			}
		});
	};

	return component;
})( jQuery );
blog

blog

1win — официальный сайт букмекерской конторы 1вин.1812

1win — официальный сайт букмекерской конторы 1вин ▶️ ИГРАТЬ Содержимое Официальный сайт букмекерской конторы 1вин Быстрый доступ к ставкам и линиям Преимущества быстрого доступа Преимущества и функции официального сайта 1вин Большой выбор ставок В мире ставок и азарта 1win – это имя, которое ассоциируется с надежностью, быстротой и комфортной игрой. …

Read More »

Mostbet onlayn kazino O‘zbekistonda xavfsizlik va litsenziya.121

Mostbet onlayn kazino O‘zbekistonda – xavfsizlik va litsenziya ▶️ O’YNANG Содержимое Mostbet onlayn kazinoning O‘zbekistondagi litsenziyasi Litsenziya haqida ma’lumot Xavfsizlik choralarining amalga oshirilishi Xavfsizlik choralarining turlari Xavfsizlik choralarini bajarishning afzalliklari Onlayn kazinoda moliyaviy operatsiyalar xavfsizligi Moliyaviy operatsiyalar xavfsizligi texnologiyalari Foydalanuvchilar uchun maslahatlar Mostbet onlayn kazinosining O‘zbekiston bozorida ishtiroki Mostbet onlayn …

Read More »

Mostbet onlayn kazino O‘zbekistonda mobil ilova.393

Mostbet onlayn kazino O‘zbekistonda – mobil ilova ▶️ O’YNANG Содержимое Mostbet mobil ilovasining afzalliklari Mostbet onlayn kazinoda o’yinlar va bonuslar Mostbet mobil ilovasini O‘zbekistonda yuklab olish va o’rnatish Mostbet uz kirish imkoniyati bilan, O‘zbekistonda yashovchi iste’molchilar endi o‘z sevimli kazino o‘yinlarini onlayn rejimda o‘ynashlari mumkin. Kazino online o‘yinlari dunyosi juda …

Read More »

8d25650162e5

Noxwin Gambling enterprise Canada ️ Rating C$a hundred Welcome Extra Blogs Safer, Prompt, and you will Legitimate Casino Financial Options for 2024 Exclusive Crypto Now offers A primary area of amount to your organization is the on the internet gaming world in the China and you can Europe. Video slots …

Read More »

Unique Casino (Avis 2025) Bonus 200% jusqu’à 500.1713

Unique Casino Avis 2025 Profitez d’un Bonus Exclusif de 200% Jusqu’à 500€ ▶️ JOUER Содержимое Unique Casino (Avis 2025) : Découvrez l’Expérience Ultime Bonus Exclusif : 200% Jusqu’à 500€ Pourquoi Choisir Unique Casino en 2025 ? Jeux de Casino Variés et Passionnants Sécurité et Fiabilité à Toute Épreuve Support Client …

Read More »

Los mejores casinos online de España.617

Содержимое ¿Qué es un casino online? ¿Cómo elegir el mejor casino online? Los mejores casinos online para jugadores españoles ¿Cómo elegir el mejor casino online para ti? Seguridad y responsabilidad en los casinos online Mejor casino online: ¿cómo elegir? Los mejores casinos online de España En la actualidad, el mundo …

Read More »

WinSpirit Online Casino Australia Real Money Play.659

WinSpirit Online Casino Australia Your Gateway to Real Money Gaming Excitement ▶️ PLAY Содержимое WinSpirit Online Casino Australia: Your Gateway to Real Money Play Why Choose WinSpirit Online Casino for Real Money Gaming? Explore the Best Casino Games at WinSpirit Australia Secure and Fast Real Money Transactions at WinSpirit Exclusive …

Read More »

1win — регистрация в букмекерской конторе 1вин.1299

Содержимое Шаги регистрации в 1win Как начать играть и получать бонусы в 1win 1win — регистрация в букмекерской конторе 1вин В мире ставок и азарта 1вин является одним из самых популярных букмекеров. Компания была основана в 2018 году и с тех пор стала одним из лидеров на рынке. 1вин предлагает …

Read More »

Casinos online populares en España.1533

Casinos online populares en España ▶️ JUGAR Содержимое Los mejores sitios de casino online en España ¿Qué son los casinos online? Características de los casinos online Tipos de casinos online Los mejores casinos online en España ¿Cómo elegir el mejor casino online para ti? Seguridad y responsabilidad en los casinos …

Read More »