HEX
Server: LiteSpeed
System: Linux premium221.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User: madepabj (2566)
PHP: 8.3.26
Disabled: NONE
Upload Files
File: //proc/self/root/var/softaculous/sitepad/editor/site-data/plugins/siteseo-pro/assets/js/metabox.js
jQuery(document).ready(function($){

	// video thumbnail upload
	$(document).on('click', '.siteseo-video-thumbnail-upload', function(e){
    e.preventDefault();
    var button = $(this);
    var frame = wp.media({
            title: 'Select or Upload Video Thumbnail',
            button: {
              text: 'Use this image'
            },
            multiple: false
      });
       
        frame.on('select', function() {
            var attachment = frame.state().get('selection').first().toJSON();
            button.prev('input').val(attachment.url);
        });
        
        frame.open();
	});
	
	$(document).on('click', '#siteseo_validate_schema', function(e){
		e.preventDefault();

		// Fetch Schema
		var schemaContentWrap = $('.siteseo_schema_preview #siteseo_raw_schema');
		if(!schemaContentWrap.length){
			schemaContentWrap = $('.siteseo_schema_preview');
		}

		let schemaContent = '';
		
		// This is to ensure we dont end up having 2 values of the schema.
		if(schemaContentWrap.length > 1){
			schemaContent = schemaContentWrap.eq(0).text();
		} else {
			schemaContent = schemaContentWrap.text();
		}

		let $form = $('<form>', {
			'method': 'POST',
			'action': 'https://search.google.com/test/rich-results',
			'target': '_blank'
		}),
		$input = $('<input>', {
			'type': 'hidden',
			'name': 'code_snippet',
			'value': schemaContent
		});

		$form.append($input);
		$("body").append($form);

		$form.submit();
		$form.remove();
	});
	
  // Custom schema json invalid
	$(document.body).on('blur', '.siteseo_structured_data_custom', function(e){
		e.preventDefault();
		let json_str = $(this).val().trim(),
		error_box = $('.siteseo-json-error');

		if(json_str === ''){
			error_box.hide(); // empty allowed
			return;
		}

		try {
			JSON.parse(json_str);
      error_box.hide();
		} catch(e){
			error_box.text("⚠ Invalid JSON: " + e.message);
			error_box.show();
		}
	});
	
	$(document).on('change', '.siteseo_structured_data_type', function(e){
		e.preventDefault();
		
		let schemaType = $(this).val(),
		propertiesContainer = $('.siteseo-metabox-schema'),
		customSchemaContainer = $('.siteseo_custom_schema_container'),
		propertiesDiv = $('.siteseo-schema-properties');
		preview = $('.siteseo-schema-preview');

		$('.siteseo_structured_data_type').val(schemaType);
		
		propertiesDiv.empty();
		
		if(schemaType === ''){
			propertiesContainer.hide();
			customSchemaContainer.hide();
			preview.hide();
			$('.siteseo_schema_preview').html('');
			$('#siteseo_raw_schema').text('');
			return;
		}
	   
		if(schemaType === 'CustomSchema'){
			propertiesContainer.hide();
			preview.show();
			customSchemaContainer.show();
			updateCustomSchemaPreview();
			return;
		} else{
			propertiesContainer.show();
			customSchemaContainer.hide();
			preview.show();
		}
		
		// schemas load
		let properties = structuredDataMetabox.propertyTemplates[schemaType] || {};
		// Create form fields for each property
		$.each(properties, function(property, defaultValue){
			var label = property.replace(/([a-z])([A-Z])/g, '$1 $2');
			label = label.charAt(0).toUpperCase() + label.slice(1);

			let field = '',
			is_textarea_fields = ['description', 'instructions', 'reviewBody', 'questions', 'step', 'ingredients', 'recipeInstructions', 'courseDescription', 'bookDescription', 'softwareRequirements', 'menu'],
			is_date_type_fields = ['datePublished', 'dateModified', 'uploadDate', 'startDate', 'endDate', 'foundingDate', 'releaseDate'];
			
			if(is_textarea_fields.includes(property)){
				field = $('<textarea/>').attr({ name: 'schema_properties[' + property + ']', id: 'siteseo_schema_property_' + property, rows: 3, class: 'widefat'}).val(defaultValue);
			} else if (is_date_type_fields.includes(property)){
				field = $('<input/>').attr({ type: 'datetime-local', name: 'schema_properties[' + property + ']', id: 'siteseo_schema_property_' + property,
				class: 'widefat'}).val(defaultValue);
			} else {
				field = $('<input/>').attr({ type: 'text', name: 'schema_properties[' + property + ']', id: 'siteseo_schema_property_' + property,
				class: 'widefat'}).val(defaultValue);
			}
			
			$('<p/>')
				.append($('<label/>').attr('for', 'siteseo_schema_property_' + property).text(label + ':'))
				.append(field)
				.appendTo(propertiesDiv);
			});
			
			// preview update
			updatePreview();
			$(document).on('input', '.siteseo-schema-properties input, #schema_properties textarea', updatePreview);
	});
	
	// preview function
	function updatePreview(){
		var schemaType = $('.siteseo_structured_data_type').val();
		if(schemaType === 'CustomSchema'){
			updateCustomSchemaPreview();
			return;
		}

		var schemaData = {
			'@context': 'https://schema.org',
			'@type': schemaType
		};
	   
		$('.siteseo-schema-properties input, .siteseo-schema-properties textarea').each(function(){
			var propertyName = $(this).attr('name').match(/\[(.*?)\]/)[1];
			var propertyValue = $(this).val();

			if(propertyValue !== ''){
			schemaData[propertyName] = propertyValue;
			}
		});
	   
		var jsonString = JSON.stringify(schemaData, null, 2);
		$('#siteseo_raw_schema').text(jsonString);
	   
	   // Make sure highlighter element exists
		if($('.siteseo_schema_preview .siteseo_highlighter').length === 0){
		   $('.siteseo_schema_preview').html('<div id="siteseo_highlighter" class="siteseo_highlighter"></div><div id="siteseo_raw_schema" style="display:none;"></div>');
		}
	   
		$('.siteseo_schema_preview .siteseo_highlighter').html(highlightJson(jsonString));
	}
	
	// Custom schema preview
	function updateCustomSchemaPreview(){
		var customSchema = $('.siteseo_structured_data_custom').val() || '';
		$('#siteseo_raw_schema').text(customSchema);
	   
		// highlighter element exists
		if($('.siteseo_schema_preview .siteseo_highlighter').length === 0){
			$('.siteseo_schema_preview').html('<div id="siteseo_highlighter" class="siteseo_highlighter"></div><div id="siteseo_raw_schema" style="display:none;"></div>');
		}
	   
		try{
			
			if(customSchema.trim()){
				var jsonObj = JSON.parse(customSchema);
				$('.siteseo_schema_preview .siteseo_highlighter').html(highlightJson(jsonObj));
			} else{
				$('.siteseo_schema_preview .siteseo_highlighter').html('');
			}
		} catch(e){
			
			$('.siteseo_schema_preview .siteseo_highlighter').text(customSchema);
		}
	}
   
	// as per schema change update preview
	$(document).on('input', '.siteseo_structured_data_custom', updateCustomSchemaPreview);
   
	// Initial preview update
	if($('.siteseo_structured_data_type').val() !== ''){
		if($('.siteseo_structured_data_type').val() === 'CustomSchema'){
			updateCustomSchemaPreview();
		} else{
			updatePreview();
			$(document).on('input', '.siteseo-schema-properties input, .siteseo-schema-properties textarea', updatePreview);
		}
	}
	
	/*** Refresh tokens ***/
	$(document).on('click', '.siteseo-ai-refresh-tokens', function(e){
		e.preventDefault();
		e.stopPropagation();
		let token_container = $(this).closest(".siteseo-ai-token-count");
		token_container.addClass("siteseo-loading");
 
		$('.siteseo-ai-token-badge').fadeOut(200).fadeIn(200);
	
        $.ajax({
            url: siteseo_pro.ajax_url,
            method: "POST",
            data: {
                action: "siteseo_pro_refresh_tokens",
                nonce: siteseo_pro.nonce,
            },
            success: function(res){
                if(!res.success){
                    if(res.data){
                        snackbar(res.data);
                        return;
                    }
                    snackbar("Something went wrong fetching token data");
                    return;
                }
                update_tokens(res.data);
            },
            error: function(){
                snackbar("Error refreshing tokens");
            },
            complete: function(){
                token_container.removeClass("siteseo-loading");
            }
        });
    });
	
	function snackbar(msg){
		if(!msg){
			msg = 'Something went wrong!';
		}

		snack_bar = $('.siteseo-ai-snackbar');
		snack_bar.text(msg);
		snack_bar.show();
		setTimeout(function(){ snack_bar.hide() }, 3500);
	}
  	
	/** update tokens **/
	function update_tokens(remaining_tokens){
		let formatted_tokens = remaining_tokens < 0 ? 0 : parseInt(remaining_tokens).toLocaleString('en'),
		token_badge = $('.siteseo-ai-token-badge');
		
		if(token_badge.length === 0){
    
			$('.siteseo-ai-token-count').prepend(
				'<span class="siteseo-ai-token-badge">Tokens Remaining ' + formatted_tokens + '</span>' +
				'<span class="dashicons dashicons-image-rotate siteseo-ai-refresh-tokens" id="siteseo-ai-refresh-tokens" title="Refresh tokens"></span>' + '<hr />'
			);
		} else{
			let show_buy_link = remaining_tokens < 900 ? '<br/><a href="'+siteseo_pro.buy_link+'" target="_blank" class="siteseo-ai-buy-tokens">Buy AI Tokens</a>' : '';
			token_badge.html('Tokens Remaining ' + formatted_tokens + show_buy_link);
		}
	}
	
	// Open modal
	$(document).on('click', '.siteseo-ai-modal-open', function(e){
		e.preventDefault();
		let context = $(this).data('context') || 0,
		$modal = $('.siteseo-ai-modal-overlay');
		
		if(typeof siteseo_universal !== 'undefined'){
			$modal.data('context', context).show();
		} else{
			
			if(window.parent && window.parent !== window){
				let $parentModal = window.parent.jQuery('.siteseo-ai-modal-overlay');

				if($parentModal.length){
					$parentModal.data('context', context).show();
					add_input_fields();
					return;
				}
			}
			      
			$modal.data('context', context).show();
		}
		
		// Update input fileds on tigger ai output
		add_input_fields();
	});
	
	// Close modal
	$('#siteseo-ai-close-modal').on('click', function(){
		$('.siteseo-ai-modal-overlay').hide();
	});

	// Close when clicking outside
	$(document).on('click', '.siteseo-ai-modal-overlay', function(e){
		if($(e.target).is('.siteseo-ai-modal-overlay')){
			let $modal = $('.siteseo-ai-modal-overlay');
			if($modal.is(':visible')){
				$modal.hide();
			}
		}
	});

	/** AI **/
	$('.siteseo-ai-generate').on('submit', function(e){
		e.preventDefault();
		
		let context = $('#siteseo-ai').data('context'),
		generate_title = $('input[name="generate_title"]').is(':checked'),
		generate_desc = $('input[name="generate_desc"]').is(':checked');
		
		$('.siteseo-ai-placeholder').remove();
		$('.siteseo-ai-error').remove();

		// Handling Universal metabox
		let universal_metabox = document.querySelector('#siteseo-iframe-universal-metabox');
		if(typeof siteseo_universal !== 'undefined' && context.length === 0 && universal_metabox && universal_metabox.contentWindow){
			let universal_metabox_doc = universal_metabox.contentWindow.document,
			$universal_metabox_visible = $(universal_metabox_doc).find('.siteseo-ai-modal-open:visible');
			
			if($universal_metabox_visible.length){
				context = $universal_metabox_visible.data('context');
			}
		}

		let focus_keyword = $('.siteseo-ai-modal-body .siteseo-ai-input[type="text"]').eq(0).val(),
		post_brief = $('.siteseo-ai-modal-body textarea').val(),
		tone = $('.siteseo-ai-modal-body select').eq(0).val(),
		audience = $('.siteseo-ai-modal-body select').eq(1).val(),
		language = $('#siteseo-ai-language-select').val(),
		num_titles = $('.siteseo-ai-modal-body input[type="number"]').val(),
		spinner = $('.siteseo-ai-spinner');
		
		if(!focus_keyword){
			$('.siteseo-ai-error-msg').html('<div class="siteseo-ai-error">Please enter the focus keyword.</div>');
			return;
		}
		
		if(focus_keyword.length < 4){
			$('.siteseo-ai-error-msg').html('<div class="siteseo-ai-error">Focus keyword should be at least 4 characters long.</div>');
			return;
		}
		
		if(!post_brief){
			$('.siteseo-ai-error-msg').html('<div class="siteseo-ai-error">Please enter the post summary.</div>');
			return;
		}
		
		if(post_brief.length < 9){
			$('.siteseo-ai-error-msg').html('<div class="siteseo-ai-error">Post summary should be at least 9 characters long.</div>');
			return;
		}
		
		if(!generate_title && !generate_desc){
			$('.siteseo-ai-error-msg').html('<div class="siteseo-ai-error">Please select at least one option (title or description) to proceed..</div>');
			return;
		}
		
		$('.siteseo-ai-error').remove();
		
		spinner.addClass('siteseo-ai-spinner-active');
		
		let $button = $(this);
    
		$('.siteseo-generate-animation').addClass('siteseo-ai-shimmer');

		let prompt = (generate_title || generate_desc) ? build_prompt(focus_keyword, post_brief, tone, audience, language, num_titles, context, generate_title, generate_desc) : null;
		
		if(!prompt){
			return;
		}

		$.ajax({
			url: siteseo_pro.ajax_url,
			type: 'POST',
			data: {
				action: 'siteseo_pro_ai_generate',
				prompt: prompt,
				nonce: siteseo_pro.nonce
			}
		})
		.then(function(response){
			if(!response.success){
				throw response.data;
			}

			if(response.data && response.data.remaining_tokens){
				update_tokens(response.data.remaining_tokens);
			}

			return response.data.ai;
		})
		.then(function(response){
			spinner.removeClass('siteseo-ai-spinner-active');
			$button.prop('disabled', false);

			if(!response.titles && generate_title && !generate_desc){
				throw 'Unable to generate title';
			} else if(!response.descriptions && generate_desc && !generate_title){
				throw 'Unable to generate description';
			} else if(!response.titles && !response.descriptions && generate_desc && generate_title){
				throw 'Unable to generate title and description';
			}

			process_ai_response(response, generate_title, generate_desc);
		})
		.catch(function(error) {
			spinner.removeClass('siteseo-ai-spinner-active');
			$button.prop('disabled', false);
			handle_error($button, error);
		});
	});
	
	function build_prompt(focus_keyword, post_brief, tone, audience, lang, num, context, is_title = false, is_desc = false){
		// Return early if nothing is requested.
		if(!is_title && !is_desc){
			return '';
		}

		// Use a simple map for platform context for easier maintenance.
		const platform_map = {
			og: 'OpenGraph (Facebook)',
			twitter: 'X (Twitter)',
		};
		const platform_context = platform_map[context] || 'web page';

		// Dynamically build the parts of the prompt.
		const generate_parts = [];
		const length_instructions = [];
		const format_object = {};

		if(is_title){
			generate_parts.push('title');
			length_instructions.push('each title must be between 50 and 60 characters');
			format_object.titles = ['string', 'string']; // Example structure
		}

		if(is_desc){
			generate_parts.push('description');
			length_instructions.push('each description must be between 150 and 160 characters');
			format_object.descriptions = ['string', 'string']; // Example structure
		}

		const generate = generate_parts.join(' and ');
		const content_length = `The length of ${length_instructions.join(', and ')}.`;
		const format = JSON.stringify(format_object);

		// Building the final prompt.
		return `Generate exactly ${num} SEO ${platform_context} ${generate} suggestions for a blog post with the following details:
- Focus Keyword: ${focus_keyword}
- Post Brief: ${post_brief}
- Tone: ${tone}
- Target Audience: ${audience}
- Language: ${lang}

It should be optimized for ${platform_context}, engaging, and ${content_length}
Return the response in json format like ${format} and do not include any extra text or explanation — only the raw JSON.`;
	}

	function process_ai_response(response, generate_title, generate_desc){
		let titles = [];
		let descriptions = [];

		let title_target, desc_target,
		copy_icon_svg = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>',
		use_icon_svg = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>';
		
		// Process if title res valid
		if(typeof response.titles != 'undefined' && response.titles.length > 0){
			titles = response.titles;
		}

		// Process desc res valid
		if(typeof response.descriptions != 'undefined' && response.descriptions.length > 0){
			descriptions = response.descriptions;
		}
    
		let title_html = '',
		desc_html = '',
		error_msg = '';

		// Show tabs
		if(titles.length > 0){
			// Count existing titles plus new ones
			let existingTitlesCount = $('.siteseo-ai-outputs-titles .siteseo-ai-item').length,
			title_tab = $('.siteseo-ai-tab-btn[data-tab="siteseo-titles-tab"]');
			title_tab.show().addClass('active');
			title_tab.find('.siteseo-ai-tab-stat').text(existingTitlesCount + titles.length);

			titles.forEach(function(title){
				if(title.trim()){
					title_html += `
					<div class="siteseo-ai-item">
						<div class="siteseo-ai-item-content">${title.trim()}</div>
						<div class="siteseo-ai-item-actions">
							<button class="siteseo-ai-copy-btn" data-text="${title.trim()}">
								${copy_icon_svg} Copy
							</button>
							<button class="siteseo-ai-use-btn" id="siteseo-ai-titles" data-text="${title.trim()}">
								${use_icon_svg} Use This
							</button>
						</div>
					</div>`;
				}
			});

		} else {
			if(generate_title){
				let error_msg = titles < 1 ? 'No titles were generated' : '';
				title_html += `<div class="siteseo-ai-error">${error_msg}</div>`;
			}
		}
		
		if(descriptions.length > 0){
			// Count existing descriptions plus new ones
			let existingDescCount = $('.siteseo-ai-outputs-desc .siteseo-ai-item').length;
			desc_tab = $('.siteseo-ai-tab-btn[data-tab="siteseo-descriptions-tab"]');
			
			desc_tab.show().addClass('active');
			desc_tab.find('.siteseo-ai-tab-stat').text(existingDescCount + descriptions.length);
			
			descriptions.forEach(function(desc){
				if(desc.trim()){
					desc_html += `
					<div class="siteseo-ai-item">
						<div class="siteseo-ai-item-content">${desc.trim()}</div>
						<div class="siteseo-ai-item-actions">
							<button class="siteseo-ai-copy-btn" data-text="${desc.trim()}">
								${copy_icon_svg} Copy
							</button>
							<button class="siteseo-ai-use-btn" id="siteseo-ai-desc" data-text="${desc.trim()}">
								${use_icon_svg} Use This
							</button>
						</div>
					</div>`;
				}
			});
		} else {
			if(generate_desc){
				let error_msg = descriptions < 1 ? 'No descriptions were generated' : '';
				desc_html += `<div class="siteseo-ai-error">${error_msg}</div>`;
			}
		}
		
		$('.siteseo-ai-tabs').show(); // Show the tabs
		$('.siteseo-generate-animation').removeClass('siteseo-ai-shimmer');
		
		if(title_html){
			$('.siteseo-ai-outputs-titles').prepend(title_html);
		}
		
		if(desc_html){
			$('.siteseo-ai-outputs-desc').prepend(desc_html);
		}
		
		add_input_fields();

		if(generate_title || generate_desc){
			$('.siteseo-ai-tab-btn').off('click').on('click', function(){
				$('.siteseo-ai-tab-btn').removeClass('active');
				$(this).addClass('active');
				
				let tab_to_show = $(this).data('tab');
				$('.siteseo-ai-tab-content').removeClass('active');
				$('#' + tab_to_show).addClass('active');
			});
			
			// activate tab
			if(generate_title && generate_desc){
				$('.siteseo-ai-tab-btn[data-tab="siteseo-titles-tab"]').click();
			} else if(generate_title){
				$('.siteseo-ai-tab-btn[data-tab="siteseo-titles-tab"]').click();
			} else if (generate_desc){
				$('.siteseo-ai-tab-btn[data-tab="siteseo-descriptions-tab"]').click();
			}
		}

		//copy and use buttons reset
		$('.siteseo-ai-copy-btn').off('click').on('click', function(){
			if($(this).hasClass('siteseo-ai-copy-btn')){
				let text = $(this).data('text');
				navigator.clipboard.writeText(text).then(function(){
					let $btn = $(this);
					$btn.html(`${use_icon_svg} Copied!`);
					setTimeout(function(){
						$btn.html(`${copy_icon_svg} Copy`);
					}, 2000);
				}.bind(this));
			} 
		});
		
		$('.siteseo-ai-use-btn').on('click', function(){
			let text = $(this).data('text'),
				target = $(this).data('target'),
				context = $(this).closest('.siteseo-ai-modal-overlay').data('context');

			// For universal metabox
			let universal_metabox = document.querySelector('#siteseo-iframe-universal-metabox');
			if(universal_metabox && universal_metabox.contentWindow){
				let universal_metabox_doc = universal_metabox.contentWindow.document;
				let universal_jQuery = universal_metabox.contentWindow.jQuery;

				let actual_target;
				switch(context){
					case 'og':
						actual_target = 'siteseo_social_fb_title_meta';
						if($(this).attr('id') === 'siteseo-ai-desc') {
							actual_target = 'siteseo_social_fb_desc_meta';
						}
						break;
					case 'twitter':
						actual_target = 'siteseo_social_twitter_title_meta';
						if($(this).attr('id') === 'siteseo-ai-desc') {
							actual_target = 'siteseo_social_twitter_desc_meta';
						}
						break;
					default:
						actual_target = 'siteseo_titles_title_meta';
						if($(this).attr('id') === 'siteseo-ai-desc') {
							actual_target = 'siteseo_titles_desc_meta';
						}
				}

				let $universal_metabox_input = universal_jQuery(universal_metabox_doc).find('#' + actual_target);
				if($universal_metabox_input.length){
					$universal_metabox_input.val(text);
					$universal_metabox_input.trigger('input');
				}
			} else {
				// For regular metabox
				let $input = $('#' + target);
				if($input.length){
					$input.val(text).trigger('input');
				}
			}
				
			let $btn = $(this);
			$btn.html(`${use_icon_svg} Applied!`);
			setTimeout(function(){
				$btn.html(`${use_icon_svg} Use This`);
			}, 2000);
		});
	}
	
	function add_input_fields(){
		
		let $modal = $('.siteseo-ai-modal-open:visible');
		let	context = $modal.data('context');
		
		if(!context){
			let $modal = jQuery('.siteseo-ai-modal-open:visible');
			context = $modal.data('context');
		}
		
		let title_target, desc_target;
		switch(context){
			case 'og':
				title_target = 'siteseo_social_fb_title_meta';
				desc_target = 'siteseo_social_fb_desc_meta';
				break;
			case 'twitter':
				title_target = 'siteseo_social_twitter_title_meta';
				desc_target = 'siteseo_social_twitter_desc_meta';
				break;
			default:
				title_target = 'siteseo_titles_title_meta';
				desc_target = 'siteseo_titles_desc_meta';
		}
		
		// Update all title buttons
		$('.siteseo-ai-use-btn[id="siteseo-ai-titles"]').each(function(){
			$(this).data('target', title_target);
		});
		
		// Update all description buttons
		$('.siteseo-ai-use-btn[id="siteseo-ai-desc"]').each(function(){
			$(this).data('target', desc_target);
		});
	}
	
	function handle_error($button, error){
		$button.prop('disabled', false);
		$('.siteseo-ai-error-msg').html('<div class="siteseo-ai-error">Error: ' + error + '</div>');
		$('.siteseo-generate-animation').removeClass('siteseo-ai-shimmer');
	}

	// Tab switch
	$('.siteseo-tab').on('click', function(){
		$('.siteseo-tab').removeClass('active');
		$(this).addClass('active');
		
		let tab = $(this).data('tab');
		$('.siteseo-ai-tab-content').removeClass('active');
		$('.siteseo-ai-tab-content[data-tab="' + tab + '"]').addClass('active');
	});
	
});