Make your WordPress site irresistible. Natural SEO attraction with: - robots.txt management - sitemap.xml generation - LLMs.txt support - Google integration (Analytics, Search Console, Tag Manager) - Schema.org structured data - Open Graph / Twitter Card meta tags - AMP support - Visual elements gallery - Built-in backup/restore module Includes build.sh and .distignore for WordPress-installable release ZIPs.
485 lines
21 KiB
JavaScript
485 lines
21 KiB
JavaScript
/**
|
|
* TigerStyle Heat Admin JavaScript
|
|
*/
|
|
|
|
// Tab switching functionality - Available immediately
|
|
window.switchTab = function(evt, tabName) {
|
|
var i, tabcontent, tablinks;
|
|
tabcontent = document.getElementsByClassName("tab-content");
|
|
for (i = 0; i < tabcontent.length; i++) {
|
|
tabcontent[i].classList.remove("active");
|
|
}
|
|
tablinks = document.getElementsByClassName("nav-tab");
|
|
for (i = 0; i < tablinks.length; i++) {
|
|
tablinks[i].classList.remove("nav-tab-active");
|
|
}
|
|
document.getElementById(tabName).classList.add("active");
|
|
evt.currentTarget.classList.add("nav-tab-active");
|
|
};
|
|
|
|
jQuery(document).ready(function($) {
|
|
|
|
// SEO Health Checker functionality
|
|
window.runSEOHealthCheck = function() {
|
|
const button = document.getElementById('seo-health-check-btn');
|
|
if (!button) return;
|
|
|
|
const originalText = button.textContent;
|
|
|
|
// Update button state
|
|
button.textContent = tigerstyleSEO.strings.runningAnalysis;
|
|
button.disabled = true;
|
|
|
|
// Show loading indicator
|
|
const loadingDiv = document.createElement('div');
|
|
loadingDiv.id = 'seo-loading';
|
|
loadingDiv.innerHTML = '<div style="text-align: center; padding: 20px;"><div class="spinner is-active" style="float: none; margin: 0 auto;"></div><p>Analyzing SEO health...</p></div>';
|
|
|
|
const resultsContainer = document.getElementById('seo-health-results');
|
|
if (resultsContainer) {
|
|
resultsContainer.innerHTML = '';
|
|
resultsContainer.appendChild(loadingDiv);
|
|
}
|
|
|
|
// Make AJAX request
|
|
$.ajax({
|
|
url: tigerstyleSEO.ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'seo_health_check',
|
|
nonce: tigerstyleSEO.nonce
|
|
},
|
|
success: function(response) {
|
|
button.textContent = originalText;
|
|
button.disabled = false;
|
|
|
|
if (response.success && resultsContainer) {
|
|
displaySEOResults(response.data);
|
|
} else {
|
|
showError(tigerstyleSEO.strings.analysisFailed);
|
|
}
|
|
},
|
|
error: function() {
|
|
button.textContent = originalText;
|
|
button.disabled = false;
|
|
showError(tigerstyleSEO.strings.networkError);
|
|
}
|
|
});
|
|
};
|
|
|
|
function displaySEOResults(data) {
|
|
const resultsContainer = document.getElementById('seo-health-results');
|
|
if (!resultsContainer) return;
|
|
|
|
let html = '<div class="seo-results-container">';
|
|
html += '<div class="seo-score-display" style="text-align: center; margin-bottom: 30px;">';
|
|
html += '<h3>SEO Health Score: ' + Math.round((data.score / data.max_score) * 100) + '%</h3>';
|
|
html += '</div>';
|
|
|
|
if (data.recommendations && data.recommendations.length > 0) {
|
|
html += '<div class="seo-section"><h3>Recommendations</h3>';
|
|
data.recommendations.forEach(function(item) {
|
|
html += createSEOItem(item);
|
|
});
|
|
html += '</div>';
|
|
}
|
|
|
|
html += '</div>';
|
|
resultsContainer.innerHTML = html;
|
|
}
|
|
|
|
function createSEOItem(item) {
|
|
let html = '<div class="seo-item" style="border: 1px solid #ddd; border-radius: 5px; padding: 15px; margin-bottom: 10px;">';
|
|
html += '<h4>' + item.title + '</h4>';
|
|
html += '<p>' + item.description + '</p>';
|
|
if (item.action && item.action.url) {
|
|
html += '<a href="' + item.action.url + '" class="button button-primary">' + item.action.text + '</a>';
|
|
}
|
|
html += '</div>';
|
|
return html;
|
|
}
|
|
|
|
function showError(message) {
|
|
const resultsContainer = document.getElementById('seo-health-results');
|
|
if (resultsContainer) {
|
|
resultsContainer.innerHTML = '<div class="notice notice-error"><p>' + message + '</p></div>';
|
|
}
|
|
}
|
|
|
|
// Cache Analysis functionality
|
|
$('#analyze-cache-btn').on('click', function() {
|
|
const button = $(this);
|
|
const originalText = button.text();
|
|
const loadingDiv = $('#cache-analysis-loading');
|
|
const resultsDiv = $('#cache-analysis-results');
|
|
|
|
// Update button state
|
|
button.text('Analyzing...').prop('disabled', true);
|
|
loadingDiv.show();
|
|
resultsDiv.hide().empty();
|
|
|
|
// Make AJAX request
|
|
$.ajax({
|
|
url: tigerstyleSEO.ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_analyze_cache',
|
|
nonce: tigerstyleSEO.cache_analysis_nonce
|
|
},
|
|
success: function(response) {
|
|
button.text(originalText).prop('disabled', false);
|
|
loadingDiv.hide();
|
|
|
|
if (response.success) {
|
|
displayCacheAnalysisResults(response.data);
|
|
resultsDiv.show();
|
|
} else {
|
|
showCacheAnalysisError('Analysis failed. Please try again.');
|
|
}
|
|
},
|
|
error: function() {
|
|
button.text(originalText).prop('disabled', false);
|
|
loadingDiv.hide();
|
|
showCacheAnalysisError('Network error. Please check your connection and try again.');
|
|
}
|
|
});
|
|
});
|
|
|
|
function displayCacheAnalysisResults(data) {
|
|
const resultsDiv = $('#cache-analysis-results');
|
|
|
|
let html = '<div class="cache-analysis-container">';
|
|
|
|
// Summary section
|
|
html += '<div class="cache-summary" style="background: #f0f8ff; border: 1px solid #007cba; border-radius: 5px; padding: 20px; margin-bottom: 20px;">';
|
|
html += '<h4>📊 Analysis Summary</h4>';
|
|
html += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 15px;">';
|
|
html += '<div><strong>Total Content Size:</strong><br><span style="color: #007cba; font-size: 18px;">' + data.total_size_formatted + '</span></div>';
|
|
html += '<div><strong>Potential Savings:</strong><br><span style="color: #46b450; font-size: 18px;">' + data.potential_savings_formatted + '</span></div>';
|
|
html += '<div><strong>Compression Ratio:</strong><br><span style="color: #46b450; font-size: 18px;">' + data.savings_percentage + '%</span></div>';
|
|
html += '</div></div>';
|
|
|
|
// Compression estimates
|
|
if (data.compression_estimates) {
|
|
html += '<div class="compression-estimates" style="margin-bottom: 25px;">';
|
|
html += '<h4>🎯 Compression Method Comparison</h4>';
|
|
html += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; margin-top: 10px;">';
|
|
|
|
Object.values(data.compression_estimates).forEach(function(estimate) {
|
|
html += '<div style="padding: 15px; background: #f9f9f9; border-radius: 5px; border-left: 4px solid #007cba;">';
|
|
html += '<strong>' + estimate.method + '</strong><br>';
|
|
html += '<span style="color: #666;">Compression: ' + estimate.ratio + '%</span><br>';
|
|
html += '<span style="color: #46b450; font-weight: bold;">Saves: ' + estimate.savings_formatted + '</span>';
|
|
html += '</div>';
|
|
});
|
|
|
|
html += '</div></div>';
|
|
}
|
|
|
|
// Pages analysis
|
|
if (data.pages && data.pages.length > 0) {
|
|
html += '<div class="pages-analysis" style="margin-bottom: 25px;">';
|
|
html += '<h4>📄 Page Analysis</h4>';
|
|
html += '<div style="overflow-x: auto;">';
|
|
html += '<table class="wp-list-table widefat fixed striped" style="margin-top: 10px;">';
|
|
html += '<thead><tr><th>Page</th><th>Size</th><th>Compression Ratio</th><th>Potential Savings</th></tr></thead>';
|
|
html += '<tbody>';
|
|
|
|
data.pages.forEach(function(page) {
|
|
html += '<tr>';
|
|
html += '<td><strong>' + page.title + '</strong><br><small style="color: #666;">' + page.url + '</small></td>';
|
|
html += '<td>' + page.size_formatted + '</td>';
|
|
html += '<td><span style="color: #46b450;">' + page.compression_ratio + '%</span></td>';
|
|
html += '<td><span style="color: #46b450; font-weight: bold;">' + page.savings_formatted + '</span></td>';
|
|
html += '</tr>';
|
|
});
|
|
|
|
html += '</tbody></table></div></div>';
|
|
}
|
|
|
|
// Assets analysis
|
|
if (data.assets && data.assets.length > 0) {
|
|
html += '<div class="assets-analysis" style="margin-bottom: 25px;">';
|
|
html += '<h4>🗂️ Static Assets Analysis</h4>';
|
|
html += '<div style="overflow-x: auto;">';
|
|
html += '<table class="wp-list-table widefat fixed striped" style="margin-top: 10px;">';
|
|
html += '<thead><tr><th>File</th><th>Type</th><th>Size</th><th>Compression Ratio</th><th>Potential Savings</th></tr></thead>';
|
|
html += '<tbody>';
|
|
|
|
data.assets.forEach(function(asset) {
|
|
html += '<tr>';
|
|
html += '<td><strong>' + asset.filename + '</strong></td>';
|
|
html += '<td><span class="asset-type-' + asset.type.toLowerCase() + '">' + asset.type + '</span></td>';
|
|
html += '<td>' + asset.size_formatted + '</td>';
|
|
html += '<td><span style="color: #46b450;">' + asset.compression_ratio + '%</span></td>';
|
|
html += '<td><span style="color: #46b450; font-weight: bold;">' + asset.savings_formatted + '</span></td>';
|
|
html += '</tr>';
|
|
});
|
|
|
|
html += '</tbody></table></div></div>';
|
|
}
|
|
|
|
// Recommendations
|
|
html += '<div class="cache-recommendations" style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 5px; padding: 20px;">';
|
|
html += '<h4>💡 Recommendations</h4>';
|
|
html += '<ul style="margin: 10px 0 0 20px;">';
|
|
html += '<li><strong>Enable Compression:</strong> Turn on the compression system above to automatically compress all content.</li>';
|
|
html += '<li><strong>Use Auto Mode:</strong> The automatic Brotli + Gzip fallback provides the best compatibility and performance.</li>';
|
|
html += '<li><strong>Monitor Performance:</strong> Check the statistics regularly to track your bandwidth savings.</li>';
|
|
if (data.savings_percentage > 60) {
|
|
html += '<li><strong>Excellent Potential:</strong> Your site has high compression potential! Enable compression for significant performance gains.</li>';
|
|
}
|
|
html += '</ul></div>';
|
|
|
|
html += '</div>';
|
|
|
|
resultsDiv.html(html);
|
|
}
|
|
|
|
function showCacheAnalysisError(message) {
|
|
const resultsDiv = $('#cache-analysis-results');
|
|
resultsDiv.html('<div class="notice notice-error" style="margin: 0;"><p>' + message + '</p></div>').show();
|
|
}
|
|
|
|
// AI Provider functionality
|
|
$('.test-api-key').on('click', function() {
|
|
const button = $(this);
|
|
const provider = button.data('provider');
|
|
const originalText = button.text();
|
|
const resultsDiv = $('#provider-results-' + provider);
|
|
|
|
button.text('Testing...').prop('disabled', true);
|
|
resultsDiv.html('<div class="notice notice-info"><p>Testing API key...</p></div>');
|
|
|
|
$.ajax({
|
|
url: tigerstyleSEO.ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_test_api_key',
|
|
provider_name: provider,
|
|
nonce: tigerstyleSEO.ai_nonce || tigerstyleSEO.nonce
|
|
},
|
|
success: function(response) {
|
|
button.text(originalText).prop('disabled', false);
|
|
|
|
if (response.success) {
|
|
resultsDiv.html('<div class="notice notice-success"><p>' + response.message + '</p></div>');
|
|
// Refresh the page to show updated models
|
|
setTimeout(function() {
|
|
location.reload();
|
|
}, 2000);
|
|
} else {
|
|
resultsDiv.html('<div class="notice notice-error"><p>Error: ' + response.error + '</p></div>');
|
|
}
|
|
},
|
|
error: function() {
|
|
button.text(originalText).prop('disabled', false);
|
|
resultsDiv.html('<div class="notice notice-error"><p>Network error. Please try again.</p></div>');
|
|
}
|
|
});
|
|
});
|
|
|
|
$('.refresh-models').on('click', function() {
|
|
const button = $(this);
|
|
const provider = button.data('provider');
|
|
const originalText = button.text();
|
|
const resultsDiv = $('#provider-results-' + provider);
|
|
|
|
button.text('Refreshing...').prop('disabled', true);
|
|
resultsDiv.html('<div class="notice notice-info"><p>Refreshing models...</p></div>');
|
|
|
|
$.ajax({
|
|
url: tigerstyleSEO.ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_refresh_models',
|
|
provider_name: provider,
|
|
nonce: tigerstyleSEO.ai_nonce || tigerstyleSEO.nonce
|
|
},
|
|
success: function(response) {
|
|
button.text(originalText).prop('disabled', false);
|
|
|
|
if (response.success) {
|
|
resultsDiv.html('<div class="notice notice-success"><p>' + response.message + '</p></div>');
|
|
// Refresh the page to show updated models
|
|
setTimeout(function() {
|
|
location.reload();
|
|
}, 2000);
|
|
} else {
|
|
resultsDiv.html('<div class="notice notice-error"><p>Error: ' + response.error + '</p></div>');
|
|
}
|
|
},
|
|
error: function() {
|
|
button.text(originalText).prop('disabled', false);
|
|
resultsDiv.html('<div class="notice notice-error"><p>Network error. Please try again.</p></div>');
|
|
}
|
|
});
|
|
});
|
|
|
|
$('.delete-provider').on('click', function() {
|
|
const button = $(this);
|
|
const provider = button.data('provider');
|
|
|
|
if (!confirm('Are you sure you want to delete the "' + provider + '" provider? This action cannot be undone.')) {
|
|
return;
|
|
}
|
|
|
|
const originalText = button.text();
|
|
button.text('Deleting...').prop('disabled', true);
|
|
|
|
$.ajax({
|
|
url: tigerstyleSEO.ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_delete_api_key',
|
|
provider_name: provider,
|
|
nonce: tigerstyleSEO.ai_nonce || tigerstyleSEO.nonce
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
// Remove the provider card from the page
|
|
button.closest('.provider-card').fadeOut(function() {
|
|
$(this).remove();
|
|
});
|
|
} else {
|
|
button.text(originalText).prop('disabled', false);
|
|
alert('Error: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
button.text(originalText).prop('disabled', false);
|
|
alert('Network error. Please try again.');
|
|
}
|
|
});
|
|
});
|
|
|
|
$('.model-toggle').on('change', function() {
|
|
const checkbox = $(this);
|
|
const provider = checkbox.data('provider');
|
|
const model = checkbox.data('model');
|
|
const enabled = checkbox.is(':checked');
|
|
|
|
// Create a hidden form and submit it
|
|
const form = $('<form method="post" action="' + tigerstyleSEO.ajaxurl.replace('admin-ajax.php', 'admin-post.php') + '">');
|
|
form.append('<input type="hidden" name="action" value="update_ai_provider_settings">');
|
|
form.append('<input type="hidden" name="ai_action" value="toggle_model">');
|
|
form.append('<input type="hidden" name="provider_name" value="' + provider + '">');
|
|
form.append('<input type="hidden" name="model_id" value="' + model + '">');
|
|
if (enabled) {
|
|
form.append('<input type="hidden" name="enabled" value="1">');
|
|
}
|
|
form.append('<input type="hidden" name="ai_provider_nonce" value="' + (tigerstyleSEO.ai_nonce || tigerstyleSEO.nonce) + '">');
|
|
|
|
$('body').append(form);
|
|
form.submit();
|
|
});
|
|
|
|
// AI Chat Interface functionality
|
|
$('#ai-chat-provider').on('change', function() {
|
|
const hasProvider = $(this).val() !== '';
|
|
$('#ai-chat-send').prop('disabled', !hasProvider);
|
|
|
|
if (hasProvider) {
|
|
$('#ai-chat-status').text('Ready to chat with ' + $(this).find('option:selected').text());
|
|
} else {
|
|
$('#ai-chat-status').text('');
|
|
}
|
|
});
|
|
|
|
$('#ai-chat-clear').on('click', function() {
|
|
$('#ai-chat-messages').html('<div class="chat-message system-message" style="color: #666; font-style: italic;">💡 Ask me anything about SEO, content optimization, meta tags, or website improvement!</div>');
|
|
});
|
|
|
|
$('#ai-chat-send').on('click', function() {
|
|
sendChatMessage();
|
|
});
|
|
|
|
$('#ai-chat-input').on('keypress', function(e) {
|
|
if (e.which === 13 && e.ctrlKey) { // Ctrl+Enter
|
|
sendChatMessage();
|
|
}
|
|
});
|
|
|
|
function sendChatMessage() {
|
|
const provider = $('#ai-chat-provider').val();
|
|
const message = $('#ai-chat-input').val().trim();
|
|
|
|
if (!provider || !message) {
|
|
return;
|
|
}
|
|
|
|
const [providerName, modelId] = provider.split('|');
|
|
|
|
// Add user message to chat
|
|
addChatMessage('user', message);
|
|
$('#ai-chat-input').val('');
|
|
|
|
// Show loading
|
|
const loadingId = 'loading_' + Date.now();
|
|
addChatMessage('assistant', '<div id="' + loadingId + '" style="display: flex; align-items: center; gap: 10px;"><div class="spinner is-active" style="float: none; margin: 0;"></div>Thinking...</div>');
|
|
|
|
// Send AJAX request
|
|
$.ajax({
|
|
url: tigerstyleSEO.ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_ai_chat',
|
|
provider_name: providerName,
|
|
model_id: modelId,
|
|
message: message,
|
|
nonce: tigerstyleSEO.ai_nonce || tigerstyleSEO.nonce
|
|
},
|
|
success: function(response) {
|
|
$('#' + loadingId).closest('.chat-message').remove();
|
|
|
|
if (response.success) {
|
|
addChatMessage('assistant', response.data.response);
|
|
} else {
|
|
addChatMessage('error', 'Error: ' + (response.data || 'Failed to get response'));
|
|
}
|
|
},
|
|
error: function() {
|
|
$('#' + loadingId).closest('.chat-message').remove();
|
|
addChatMessage('error', 'Network error. Please try again.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function addChatMessage(sender, content) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
let messageClass = 'chat-message';
|
|
let senderIcon = '';
|
|
let senderLabel = '';
|
|
|
|
switch(sender) {
|
|
case 'user':
|
|
messageClass += ' user-message';
|
|
senderIcon = '🙋♀️';
|
|
senderLabel = 'You';
|
|
break;
|
|
case 'assistant':
|
|
messageClass += ' assistant-message';
|
|
senderIcon = '🤖';
|
|
senderLabel = 'AI Assistant';
|
|
break;
|
|
case 'error':
|
|
messageClass += ' error-message';
|
|
senderIcon = '⚠️';
|
|
senderLabel = 'Error';
|
|
break;
|
|
}
|
|
|
|
const messageHtml = '<div class="' + messageClass + '" style="margin-bottom: 15px; padding: 10px; border-radius: 5px; ' +
|
|
(sender === 'user' ? 'background: #e3f2fd; margin-left: 20px;' :
|
|
sender === 'error' ? 'background: #ffebee; border-left: 3px solid #f44336;' :
|
|
'background: white; border: 1px solid #e0e0e0;') + '">' +
|
|
'<div style="font-size: 12px; color: #666; margin-bottom: 5px;">' +
|
|
'<strong>' + senderIcon + ' ' + senderLabel + '</strong> <span style="float: right;">' + timestamp + '</span>' +
|
|
'</div>' +
|
|
'<div style="line-height: 1.5;">' + content + '</div>' +
|
|
'</div>';
|
|
|
|
$('#ai-chat-messages').append(messageHtml);
|
|
$('#ai-chat-messages').scrollTop($('#ai-chat-messages')[0].scrollHeight);
|
|
}
|
|
}); |