Current File : /home/bdmcricketindia.in/public_html/wp-admin/js/theme-plugin-editor.js
/**
 * @output wp-admin/js/theme-plugin-editor.js
 */

/* eslint no-magic-numbers: ["error", { "ignore": [-1, 0, 1] }] */

if ( ! window.wp ) {
	window.wp = {};
}

wp.themePluginEditor = (function( $ ) {
	'use strict';
	var component, TreeLinks,
		__ = wp.i18n.__, _n = wp.i18n._n, sprintf = wp.i18n.sprintf;

	component = {
		codeEditor: {},
		instance: null,
		noticeElements: {},
		dirty: false,
		lintErrors: []
	};

	/**
	 * Initialize component.
	 *
	 * @since 4.9.0
	 *
	 * @param {jQuery}         form - Form element.
	 * @param {Object}         settings - Settings.
	 * @param {Object|boolean} settings.codeEditor - Code editor settings (or `false` if syntax highlighting is disabled).
	 * @return {void}
	 */
	component.init = function init( form, settings ) {

		component.form = form;
		if ( settings ) {
			$.extend( component, settings );
		}

		component.noticeTemplate = wp.template( 'wp-file-editor-notice' );
		component.noticesContainer = component.form.find( '.editor-notices' );
		component.submitButton = component.form.find( ':input[name=submit]' );
		component.spinner = component.form.find( '.submit .spinner' );
		component.form.on( 'submit', component.submit );
		component.textarea = component.form.find( '#newcontent' );
		component.textarea.on( 'change', component.onChange );
		component.warning = $( '.file-editor-warning' );
		component.docsLookUpButton = component.form.find( '#docs-lookup' );
		component.docsLookUpList = component.form.find( '#docs-list' );

		if ( component.warning.length > 0 ) {
			component.showWarning();
		}

		if ( false !== component.codeEditor ) {
			/*
			 * Defer adding notices until after DOM ready as workaround for WP Admin injecting
			 * its own managed dismiss buttons and also to prevent the editor from showing a notice
			 * when the file had linting errors to begin with.
			 */
			_.defer( function() {
				component.initCodeEditor();
			} );
		}

		$( component.initFileBrowser );

		$( window ).on( 'beforeunload', function() {
			if ( component.dirty ) {
				return __( 'The changes you made will be lost if you navigate away from this page.' );
			}
			return undefined;
		} );

		component.docsLookUpList.on( 'change', function() {
			var option = $( this ).val();
			if ( '' === option ) {
				component.docsLookUpButton.prop( 'disabled', true );
			} else {
				component.docsLookUpButton.prop( 'disabled', false );
			}
		} );
	};

	/**
	 * Set up and display the warning modal.
	 *
	 * @since 4.9.0
	 * @return {void}
	 */
	component.showWarning = function() {
		// Get the text within the modal.
		var rawMessage = component.warning.find( '.file-editor-warning-message' ).text();
		// Hide all the #wpwrap content from assistive technologies.
		$( '#wpwrap' ).attr( 'aria-hidden', 'true' );
		// Detach the warning modal from its position and append it to the body.
		$( document.body )
			.addClass( 'modal-open' )
			.append( component.warning.detach() );
		// Reveal the modal and set focus on the go back button.
		component.warning
			.removeClass( 'hidden' )
			.find( '.file-editor-warning-go-back' ).trigger( 'focus' );
		// Get the links and buttons within the modal.
		component.warningTabbables = component.warning.find( 'a, button' );
		// Attach event handlers.
		component.warningTabbables.on( 'keydown', component.constrainTabbing );
		component.warning.on( 'click', '.file-editor-warning-dismiss', component.dismissWarning );
		// Make screen readers announce the warning message after a short delay (necessary for some screen readers).
		setTimeout( function() {
			wp.a11y.speak( wp.sanitize.stripTags( rawMessage.replace( /\s+/g, ' ' ) ), 'assertive' );
		}, 1000 );
	};

	/**
	 * Constrain tabbing within the warning modal.
	 *
	 * @since 4.9.0
	 * @param {Object} event jQuery event object.
	 * @return {void}
	 */
	component.constrainTabbing = function( event ) {
		var firstTabbable, lastTabbable;

		if ( 9 !== event.which ) {
			return;
		}

		firstTabbable = component.warningTabbables.first()[0];
		lastTabbable = component.warningTabbables.last()[0];

		if ( lastTabbable === event.target && ! event.shiftKey ) {
			firstTabbable.focus();
			event.preventDefault();
		} else if ( firstTabbable === event.target && event.shiftKey ) {
			lastTabbable.focus();
			event.preventDefault();
		}
	};

	/**
	 * Dismiss the warning modal.
	 *
	 * @since 4.9.0
	 * @return {void}
	 */
	component.dismissWarning = function() {

		wp.ajax.post( 'dismiss-wp-pointer', {
			pointer: component.themeOrPlugin + '_editor_notice'
		});

		// Hide modal.
		component.warning.remove();
		$( '#wpwrap' ).removeAttr( 'aria-hidden' );
		$( 'body' ).removeClass( 'modal-open' );
	};

	/**
	 * Callback for when a change happens.
	 *
	 * @since 4.9.0
	 * @return {void}
	 */
	component.onChange = function() {
		component.dirty = true;
		component.removeNotice( 'file_saved' );
	};

	/**
	 * Submit file via Ajax.
	 *
	 * @since 4.9.0
	 * @param {jQuery.Event} event - Event.
	 * @return {void}
	 */
	component.submit = function( event ) {
		var data = {}, request;
		event.preventDefault(); // Prevent form submission in favor of Ajax below.
		$.each( component.form.serializeArray(), function() {
			data[ this.name ] = this.value;
		} );

		// Use value from codemirror if present.
		if ( component.instance ) {
			data.newcontent = component.instance.codemirror.getValue();
		}

		if ( component.isSaving ) {
			return;
		}

		// Scroll to the line that has the error.
		if ( component.lintErrors.length ) {
			component.instance.codemirror.setCursor( component.lintErrors[0].from.line );
			return;
		}

		component.isSaving = true;
		component.textarea.prop( 'readonly', true );
		if ( component.instance ) {
			component.instance.codemirror.setOption( 'readOnly', true );
		}

		component.spinner.addClass( 'is-active' );
		request = wp.ajax.post( 'edit-theme-plugin-file', data );

		// Remove previous save notice before saving.
		if ( component.lastSaveNoticeCode ) {
			component.removeNotice( component.lastSaveNoticeCode );
		}

		request.done( function( response ) {
			component.lastSaveNoticeCode = 'file_saved';
			component.addNotice({
				code: component.lastSaveNoticeCode,
				type: 'success',
				message: response.message,
				dismissible: true
			});
			component.dirty = false;
		} );

		request.fail( function( response ) {
			var notice = $.extend(
				{
					code: 'save_error',
					message: __( 'An error occurred while saving your changes. Please try again. If the problem persists, you may need to manually update the file via FTP.' )
				},
				response,
				{
					type: 'error',
					dismissible: true
				}
			);
			component.lastSaveNoticeCode = notice.code;
			component.addNotice( notice );
		} );

		request.always( function() {
			component.spinner.removeClass( 'is-active' );
			component.isSaving = false;

			component.textarea.prop( 'readonly', false );
			if ( component.instance ) {
				component.instance.codemirror.setOption( 'readOnly', false );
			}
		} );
	};

	/**
	 * Add notice.
	 *
	 * @since 4.9.0
	 *
	 * @param {Object}   notice - Notice.
	 * @param {string}   notice.code - Code.
	 * @param {string}   notice.type - Type.
	 * @param {string}   notice.message - Message.
	 * @param {boolean}  [notice.dismissible=false] - Dismissible.
	 * @param {Function} [notice.onDismiss] - Callback for when a user dismisses the notice.
	 * @return {jQuery} Notice element.
	 */
	component.addNotice = function( notice ) {
		var noticeElement;

		if ( ! notice.code ) {
			throw new Error( 'Missing code.' );
		}

		// Only let one notice of a given type be displayed at a time.
		component.removeNotice( notice.code );

		noticeElement = $( component.noticeTemplate( notice ) );
		noticeElement.hide();

		noticeElement.find( '.notice-dismiss' ).on( 'click', function() {
			component.removeNotice( notice.code );
			if ( notice.onDismiss ) {
				notice.onDismiss( notice );
			}
		} );

		wp.a11y.speak( notice.message );

		component.noticesContainer.append( noticeElement );
		noticeElement.slideDown( 'fast' );
		component.noticeElements[ notice.code ] = noticeElement;
		return noticeElement;
	};

	/**
	 * Remove notice.
	 *
	 * @since 4.9.0
	 *
	 * @param {string} code - Notice code.
	 * @return {boolean} Whether a notice was removed.
	 */
	component.removeNotice = function( code ) {
		if ( component.noticeElements[ code ] ) {
			component.noticeElements[ code ].slideUp( 'fast', function() {
				$( this ).remove();
			} );
			delete component.noticeElements[ code ];
			return true;
		}
		return false;
	};

	/**
	 * Initialize code editor.
	 *
	 * @since 4.9.0
	 * @return {void}
	 */
	component.initCodeEditor = function initCodeEditor() {
		var codeEditorSettings, editor;

		codeEditorSettings = $.extend( {}, component.codeEditor );

		/**
		 * Handle tabbing to the field before the editor.
		 *
		 * @since 4.9.0
		 *
		 * @return {void}
		 */
		codeEditorSettings.onTabPrevious = function() {
			$( '#templateside' ).find( ':tabbable' ).last().trigger( 'focus' );
		};

		/**
		 * Handle tabbing to the field after the editor.
		 *
		 * @since 4.9.0
		 *
		 * @return {void}
		 */
		codeEditorSettings.onTabNext = function() {
			$( '#template' ).find( ':tabbable:not(.CodeMirror-code)' ).first().trigger( 'focus' );
		};

		/**
		 * Handle change to the linting errors.
		 *
		 * @since 4.9.0
		 *
		 * @param {Array} errors - List of linting errors.
		 * @return {void}
		 */
		codeEditorSettings.onChangeLintingErrors = function( errors ) {
			component.lintErrors = errors;

			// Only disable the button in onUpdateErrorNotice when there are errors so users can still feel they can click the button.
			if ( 0 === errors.length ) {
				component.submitButton.toggleClass( 'disabled', false );
			}
		};

		/**
		 * Update error notice.
		 *
		 * @since 4.9.0
		 *
		 * @param {Array} errorAnnotations - Error annotations.
		 * @return {void}
		 */
		codeEditorSettings.onUpdateErrorNotice = function onUpdateErrorNotice( errorAnnotations ) {
			var noticeElement;

			component.submitButton.toggleClass( 'disabled', errorAnnotations.length > 0 );

			if ( 0 !== errorAnnotations.length ) {
				noticeElement = component.addNotice({
					code: 'lint_errors',
					type: 'error',
					message: sprintf(
						/* translators: %s: Error count. */
						_n(
							'There is %s error which must be fixed before you can update this file.',
							'There are %s errors which must be fixed before you can update this file.',
							errorAnnotations.length
						),
						String( errorAnnotations.length )
					),
					dismissible: false
				});
				noticeElement.find( 'input[type=checkbox]' ).on( 'click', function() {
					codeEditorSettings.onChangeLintingErrors( [] );
					component.removeNotice( 'lint_errors' );
				} );
			} else {
				component.removeNotice( 'lint_errors' );
			}
		};

		editor = wp.codeEditor.initialize( $( '#newcontent' ), codeEditorSettings );
		editor.codemirror.on( 'change', component.onChange );

		// Improve the editor accessibility.
		$( editor.codemirror.display.lineDiv )
			.attr({
				role: 'textbox',
				'aria-multiline': 'true',
				'aria-labelledby': 'theme-plugin-editor-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.
		$( '#theme-plugin-editor-label' ).on( 'click', function() {
			editor.codemirror.focus();
		});

		component.instance = editor;
	};

	/**
	 * Initialization of the file browser's folder states.
	 *
	 * @since 4.9.0
	 * @return {void}
	 */
	component.initFileBrowser = function initFileBrowser() {

		var $templateside = $( '#templateside' );

		// Collapse all folders.
		$templateside.find( '[role="group"]' ).parent().attr( 'aria-expanded', false );

		// Expand ancestors to the current file.
		$templateside.find( '.notice' ).parents( '[aria-expanded]' ).attr( 'aria-expanded', true );

		// Find Tree elements and enhance them.
		$templateside.find( '[role="tree"]' ).each( function() {
			var treeLinks = new TreeLinks( this );
			treeLinks.init();
		} );

		// Scroll the current file into view.
		$templateside.find( '.current-file:first' ).each( function() {
			if ( this.scrollIntoViewIfNeeded ) {
				this.scrollIntoViewIfNeeded();
			} else {
				this.scrollIntoView( false );
			}
		} );
	};

	/* jshint ignore:start */
	/* jscs:disable */
	/* eslint-disable */

	/**
	 * Creates a new TreeitemLink.
	 *
	 * @since 4.9.0
	 * @class
	 * @private
	 * @see {@link https://www.w3.org/TR/wai-aria-practices-1.1/examples/treeview/treeview-2/treeview-2b.html|W3C Treeview Example}
	 * @license W3C-20150513
	 */
	var TreeitemLink = (function () {
		/**
		 *   This content is licensed according to the W3C Software License at
		 *   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
		 *
		 *   File:   TreeitemLink.js
		 *
		 *   Desc:   Treeitem widget that implements ARIA Authoring Practices
		 *           for a tree being used as a file viewer
		 *
		 *   Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt
		 */

		/**
		 *   @constructor
		 *
		 *   @desc
		 *       Treeitem object for representing the state and user interactions for a
		 *       treeItem widget
		 *
		 *   @param node
		 *       An element with the role=tree attribute
		 */

		var TreeitemLink = function (node, treeObj, group) {

			// Check whether node is a DOM element.
			if (typeof node !== 'object') {
				return;
			}

			node.tabIndex = -1;
			this.tree = treeObj;
			this.groupTreeitem = group;
			this.domNode = node;
			this.label = node.textContent.trim();
			this.stopDefaultClick = false;

			if (node.getAttribute('aria-label')) {
				this.label = node.getAttribute('aria-label').trim();
			}

			this.isExpandable = false;
			this.isVisible = false;
			this.inGroup = false;

			if (group) {
				this.inGroup = true;
			}

			var elem = node.firstElementChild;

			while (elem) {

				if (elem.tagName.toLowerCase() == 'ul') {
					elem.setAttribute('role', 'group');
					this.isExpandable = true;
					break;
				}

				elem = elem.nextElementSibling;
			}

			this.keyCode = Object.freeze({
				RETURN: 13,
				SPACE: 32,
				PAGEUP: 33,
				PAGEDOWN: 34,
				END: 35,
				HOME: 36,
				LEFT: 37,
				UP: 38,
				RIGHT: 39,
				DOWN: 40
			});
		};

		TreeitemLink.prototype.init = function () {
			this.domNode.tabIndex = -1;

			if (!this.domNode.getAttribute('role')) {
				this.domNode.setAttribute('role', 'treeitem');
			}

			this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
			this.domNode.addEventListener('click', this.handleClick.bind(this));
			this.domNode.addEventListener('focus', this.handleFocus.bind(this));
			this.domNode.addEventListener('blur', this.handleBlur.bind(this));

			if (this.isExpandable) {
				this.domNode.firstElementChild.addEventListener('mouseover', this.handleMouseOver.bind(this));
				this.domNode.firstElementChild.addEventListener('mouseout', this.handleMouseOut.bind(this));
			}
			else {
				this.domNode.addEventListener('mouseover', this.handleMouseOver.bind(this));
				this.domNode.addEventListener('mouseout', this.handleMouseOut.bind(this));
			}
		};

		TreeitemLink.prototype.isExpanded = function () {

			if (this.isExpandable) {
				return this.domNode.getAttribute('aria-expanded') === 'true';
			}

			return false;

		};

		/* EVENT HANDLERS */

		TreeitemLink.prototype.handleKeydown = function (event) {
			var tgt = event.currentTarget,
				flag = false,
				_char = event.key,
				clickEvent;

			function isPrintableCharacter(str) {
				return str.length === 1 && str.match(/\S/);
			}

			function printableCharacter(item) {
				if (_char == '*') {
					item.tree.expandAllSiblingItems(item);
					flag = true;
				}
				else {
					if (isPrintableCharacter(_char)) {
						item.tree.setFocusByFirstCharacter(item, _char);
						flag = true;
					}
				}
			}

			this.stopDefaultClick = false;

			if (event.altKey || event.ctrlKey || event.metaKey) {
				return;
			}

			if (event.shift) {
				if (event.keyCode == this.keyCode.SPACE || event.keyCode == this.keyCode.RETURN) {
					event.stopPropagation();
					this.stopDefaultClick = true;
				}
				else {
					if (isPrintableCharacter(_char)) {
						printableCharacter(this);
					}
				}
			}
			else {
				switch (event.keyCode) {
					case this.keyCode.SPACE:
					case this.keyCode.RETURN:
						if (this.isExpandable) {
							if (this.isExpanded()) {
								this.tree.collapseTreeitem(this);
							}
							else {
								this.tree.expandTreeitem(this);
							}
							flag = true;
						}
						else {
							event.stopPropagation();
							this.stopDefaultClick = true;
						}
						break;

					case this.keyCode.UP:
						this.tree.setFocusToPreviousItem(this);
						flag = true;
						break;

					case this.keyCode.DOWN:
						this.tree.setFocusToNextItem(this);
						flag = true;
						break;

					case this.keyCode.RIGHT:
						if (this.isExpandable) {
							if (this.isExpanded()) {
								this.tree.setFocusToNextItem(this);
							}
							else {
								this.tree.expandTreeitem(this);
							}
						}
						flag = true;
						break;

					case this.keyCode.LEFT:
						if (this.isExpandable && this.isExpanded()) {
							this.tree.collapseTreeitem(this);
							flag = true;
						}
						else {
							if (this.inGroup) {
								this.tree.setFocusToParentItem(this);
								flag = true;
							}
						}
						break;

					case this.keyCode.HOME:
						this.tree.setFocusToFirstItem();
						flag = true;
						break;

					case this.keyCode.END:
						this.tree.setFocusToLastItem();
						flag = true;
						break;

					default:
						if (isPrintableCharacter(_char)) {
							printableCharacter(this);
						}
						break;
				}
			}

			if (flag) {
				event.stopPropagation();
				event.preventDefault();
			}
		};

		TreeitemLink.prototype.handleClick = function (event) {

			// Only process click events that directly happened on this treeitem.
			if (event.target !== this.domNode && event.target !== this.domNode.firstElementChild) {
				return;
			}

			if (this.isExpandable) {
				if (this.isExpanded()) {
					this.tree.collapseTreeitem(this);
				}
				else {
					this.tree.expandTreeitem(this);
				}
				event.stopPropagation();
			}
		};

		TreeitemLink.prototype.handleFocus = function (event) {
			var node = this.domNode;
			if (this.isExpandable) {
				node = node.firstElementChild;
			}
			node.classList.add('focus');
		};

		TreeitemLink.prototype.handleBlur = function (event) {
			var node = this.domNode;
			if (this.isExpandable) {
				node = node.firstElementChild;
			}
			node.classList.remove('focus');
		};

		TreeitemLink.prototype.handleMouseOver = function (event) {
			event.currentTarget.classList.add('hover');
		};

		TreeitemLink.prototype.handleMouseOut = function (event) {
			event.currentTarget.classList.remove('hover');
		};

		return TreeitemLink;
	})();

	/**
	 * Creates a new TreeLinks.
	 *
	 * @since 4.9.0
	 * @class
	 * @private
	 * @see {@link https://www.w3.org/TR/wai-aria-practices-1.1/examples/treeview/treeview-2/treeview-2b.html|W3C Treeview Example}
	 * @license W3C-20150513
	 */
	TreeLinks = (function () {
		/*
		 *   This content is licensed according to the W3C Software License at
		 *   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
		 *
		 *   File:   TreeLinks.js
		 *
		 *   Desc:   Tree widget that implements ARIA Authoring Practices
		 *           for a tree being used as a file viewer
		 *
		 *   Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt
		 */

		/*
		 *   @constructor
		 *
		 *   @desc
		 *       Tree item object for representing the state and user interactions for a
		 *       tree widget
		 *
		 *   @param node
		 *       An element with the role=tree attribute
		 */

		var TreeLinks = function (node) {
			// Check whether node is a DOM element.
			if (typeof node !== 'object') {
				return;
			}

			this.domNode = node;

			this.treeitems = [];
			this.firstChars = [];

			this.firstTreeitem = null;
			this.lastTreeitem = null;

		};

		TreeLinks.prototype.init = function () {

			function findTreeitems(node, tree, group) {

				var elem = node.firstElementChild;
				var ti = group;

				while (elem) {

					if ((elem.tagName.toLowerCase() === 'li' && elem.firstElementChild.tagName.toLowerCase() === 'span') || elem.tagName.toLowerCase() === 'a') {
						ti = new TreeitemLink(elem, tree, group);
						ti.init();
						tree.treeitems.push(ti);
						tree.firstChars.push(ti.label.substring(0, 1).toLowerCase());
					}

					if (elem.firstElementChild) {
						findTreeitems(elem, tree, ti);
					}

					elem = elem.nextElementSibling;
				}
			}

			// Initialize pop up menus.
			if (!this.domNode.getAttribute('role')) {
				this.domNode.setAttribute('role', 'tree');
			}

			findTreeitems(this.domNode, this, false);

			this.updateVisibleTreeitems();

			this.firstTreeitem.domNode.tabIndex = 0;

		};

		TreeLinks.prototype.setFocusToItem = function (treeitem) {

			for (var i = 0; i < this.treeitems.length; i++) {
				var ti = this.treeitems[i];

				if (ti === treeitem) {
					ti.domNode.tabIndex = 0;
					ti.domNode.focus();
				}
				else {
					ti.domNode.tabIndex = -1;
				}
			}

		};

		TreeLinks.prototype.setFocusToNextItem = function (currentItem) {

			var nextItem = false;

			for (var i = (this.treeitems.length - 1); i >= 0; i--) {
				var ti = this.treeitems[i];
				if (ti === currentItem) {
					break;
				}
				if (ti.isVisible) {
					nextItem = ti;
				}
			}

			if (nextItem) {
				this.setFocusToItem(nextItem);
			}

		};

		TreeLinks.prototype.setFocusToPreviousItem = function (currentItem) {

			var prevItem = false;

			for (var i = 0; i < this.treeitems.length; i++) {
				var ti = this.treeitems[i];
				if (ti === currentItem) {
					break;
				}
				if (ti.isVisible) {
					prevItem = ti;
				}
			}

			if (prevItem) {
				this.setFocusToItem(prevItem);
			}
		};

		TreeLinks.prototype.setFocusToParentItem = function (currentItem) {

			if (currentItem.groupTreeitem) {
				this.setFocusToItem(currentItem.groupTreeitem);
			}
		};

		TreeLinks.prototype.setFocusToFirstItem = function () {
			this.setFocusToItem(this.firstTreeitem);
		};

		TreeLinks.prototype.setFocusToLastItem = function () {
			this.setFocusToItem(this.lastTreeitem);
		};

		TreeLinks.prototype.expandTreeitem = function (currentItem) {

			if (currentItem.isExpandable) {
				currentItem.domNode.setAttribute('aria-expanded', true);
				this.updateVisibleTreeitems();
			}

		};

		TreeLinks.prototype.expandAllSiblingItems = function (currentItem) {
			for (var i = 0; i < this.treeitems.length; i++) {
				var ti = this.treeitems[i];

				if ((ti.groupTreeitem === currentItem.groupTreeitem) && ti.isExpandable) {
					this.expandTreeitem(ti);
				}
			}

		};

		TreeLinks.prototype.collapseTreeitem = function (currentItem) {

			var groupTreeitem = false;

			if (currentItem.isExpanded()) {
				groupTreeitem = currentItem;
			}
			else {
				groupTreeitem = currentItem.groupTreeitem;
			}

			if (groupTreeitem) {
				groupTreeitem.domNode.setAttribute('aria-expanded', false);
				this.updateVisibleTreeitems();
				this.setFocusToItem(groupTreeitem);
			}

		};

		TreeLinks.prototype.updateVisibleTreeitems = function () {

			this.firstTreeitem = this.treeitems[0];

			for (var i = 0; i < this.treeitems.length; i++) {
				var ti = this.treeitems[i];

				var parent = ti.domNode.parentNode;

				ti.isVisible = true;

				while (parent && (parent !== this.domNode)) {

					if (parent.getAttribute('aria-expanded') == 'false') {
						ti.isVisible = false;
					}
					parent = parent.parentNode;
				}

				if (ti.isVisible) {
					this.lastTreeitem = ti;
				}
			}

		};

		TreeLinks.prototype.setFocusByFirstCharacter = function (currentItem, _char) {
			var start, index;
			_char = _char.toLowerCase();

			// Get start index for search based on position of currentItem.
			start = this.treeitems.indexOf(currentItem) + 1;
			if (start === this.treeitems.length) {
				start = 0;
			}

			// Check remaining slots in the menu.
			index = this.getIndexFirstChars(start, _char);

			// If not found in remaining slots, check from beginning.
			if (index === -1) {
				index = this.getIndexFirstChars(0, _char);
			}

			// If match was found...
			if (index > -1) {
				this.setFocusToItem(this.treeitems[index]);
			}
		};

		TreeLinks.prototype.getIndexFirstChars = function (startIndex, _char) {
			for (var i = startIndex; i < this.firstChars.length; i++) {
				if (this.treeitems[i].isVisible) {
					if (_char === this.firstChars[i]) {
						return i;
					}
				}
			}
			return -1;
		};

		return TreeLinks;
	})();

	/* jshint ignore:end */
	/* jscs:enable */
	/* eslint-enable */

	return component;
})( jQuery );

/**
 * Removed in 5.5.0, needed for back-compatibility.
 *
 * @since 4.9.0
 * @deprecated 5.5.0
 *
 * @type {object}
 */
wp.themePluginEditor.l10n = wp.themePluginEditor.l10n || {
	saveAlert: '',
	saveError: '',
	lintError: {
		alternative: 'wp.i18n',
		func: function() {
			return {
				singular: '',
				plural: ''
			};
		}
	}
};

wp.themePluginEditor.l10n = window.wp.deprecateL10nObject( 'wp.themePluginEditor.l10n', wp.themePluginEditor.l10n, '5.5.0' );
BDM Cricket India: tips, teams, tournaments

Recent Posts

– Официальный сайт Pinco Casino.5445

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

Read More »

1Win Azerbaijan – İdman Mərcləri və Casino saytı.3459

1Win Azerbaijan – İdman Mərcləri və Casino saytı ▶️ OYNA Содержимое 1Win Azerbaijan haqqında məlumatlar 1Win Azerbaijanın məqsədi Idman mərcələrindən istifadə edən məsləhətlər 1Win Casino saytı haqqında məlumatlar Idman mərcələrindən və casino saytı ilə bağlı məlumatlar Idman mərcəzlərindən məlumatlar Casino saytı ilə bağlı məlumatlar 1Win Azerbaycan – bu idman mərcəzi …

Read More »

Najlepsze Kasyna Online w Polsce w 2025.11288

Najlepsze Kasyna Online w Polsce w 2025 ▶️ GRAĆ Содержимое Wybór Kasyna Online Wskazówki przy wyborze kasyna online Regulamin Kasyna Online Zasady gry Warunki udziału w grach Wskazówki dla Graczy Wskazówki dla Graczy Wstęp do Najlepszych Kasyn Online w Polsce w 2025 Najlepsze Kasyna Online w Polsce w 2025 Regulacje …

Read More »

Gioco Plinko nei casinò online.1418

Gioco Plinko nei casinò online ▶️ GIOCARE Содержимое Le caratteristiche del gioco Plinko Le caratteristiche chiave del gioco Plinko Le strategie per vincere al Gioco Plinko nei casinò online Analizzare il campo di gioco Utilizzare le strategie di lancio Le migliori opzioni per giocare online Il gioco plinko è un …

Read More »

CASHlib Casinos in Deutschland – Was bieten sie?

CASHlib Casinos gewinnen in Deutschland immer mehr an Bedeutung. Diese Casinos ermöglichen es Spielern, anonym und sicher mit Prepaid-Guthaben zu bezahlen – ganz ohne Bankverbindung oder Kreditkarte. Besonders für Nutzer, die auf Datenschutz und schnelle Transaktionen Wert legen, sind sie eine interessante Alternative.

Was bieten CASHlib Casinos?

  • Schnelle und anonyme Einzahlungen ohne Registrierung bei Drittanbietern
  • Breites Spielangebot von Slots bis zu Live-Dealer-Spielen
  • Regelmäßige Aktionen wie Freispiele und Cashback
  • Attraktive Willkommensboni für neue Spieler
  • EU-lizenzierte Anbieter mit hohen Sicherheitsstandards

Ein großer Vorteil von CASHlib ist, dass keine sensiblen Bankdaten im Casino hinterlegt werden müssen. Die Gutscheine sind online oder in vielen Verkaufsstellen erhältlich und können sofort verwendet werden. Dadurch entfällt auch die Notwendigkeit, persönliche Daten bei Einzahlungen preiszugeben – ein echter Pluspunkt für sicherheitsbewusste Spieler.

Viele spielothekgermany.com/de/spielothek/cashlib-casinos/ bieten zudem mobile Kompatibilität, einfache Menüführung und professionellen Spielerschutz. Wer nach einem unkomplizierten Zahlungsweg mit solider Auswahl an Spielen und Bonusangeboten sucht, wird bei diesen Plattformen fündig. Die Kombination aus Bequemlichkeit, Sicherheit und einem attraktiven Bonusangebot macht CASHlib Casinos zu einer beliebten Wahl für deutsche Nutzer.

slot 7