Files
2026-03-18 14:21:32 -07:00

379 lines
12 KiB
JavaScript

/**
* WP to HTML Admin JavaScript
*/
(function ($) {
'use strict';
var WPToHTML = {
// State
isProcessing: false,
totalPosts: 0,
processedPosts: 0,
results: {
converted: 0,
skipped: 0,
errors: 0,
details: []
},
statusPollInterval: null,
/**
* Initialize
*/
init: function () {
this.bindEvents();
this.startStatusPolling();
},
/**
* Bind event handlers
*/
bindEvents: function () {
$('#wp-to-html-convert-all').on('click', $.proxy(this.startBulkConvert, this));
$('#wp-to-html-clear-cache').on('click', $.proxy(this.clearCache, this));
},
/**
* Start status polling
*/
startStatusPolling: function () {
var self = this;
// Check status immediately
this.checkStatus();
// Poll every 3 seconds
this.statusPollInterval = setInterval(function () {
self.checkStatus();
}, 3000);
},
/**
* Stop status polling
*/
stopStatusPolling: function () {
if (this.statusPollInterval) {
clearInterval(this.statusPollInterval);
this.statusPollInterval = null;
}
},
/**
* Check regeneration status
*/
checkStatus: function () {
var self = this;
$.ajax({
url: wpToHtml.ajaxUrl,
type: 'POST',
data: {
action: 'wp_to_html_get_status',
nonce: wpToHtml.statusNonce
},
success: function (response) {
if (response.success) {
self.updateStatusCard(response.data);
}
}
});
},
/**
* Update the status card UI
*/
updateStatusCard: function (status) {
var $container = $('#wp-to-html-live-status');
if (!$container.length) return;
var html = '';
var strings = wpToHtml.strings;
// Get source label
var sourceLabels = {
'cron': strings.sourceCron,
'admin_bar': strings.sourceAdminBar,
'plugin_update': strings.sourcePluginUpdate,
'settings_page': strings.sourceSettingsPage
};
var sourceLabel = status.source ? (sourceLabels[status.source] || '') : '';
if (status.status === 'running' || status.status === 'pending') {
var statusText = status.status === 'pending' ? strings.statusPending : strings.statusRunning;
html = '<div class="status-running">';
html += '<span class="dashicons dashicons-update spin"></span>';
html += '<span class="status-text">' + statusText + '</span>';
if (sourceLabel) {
html += '<span class="status-source">' + sourceLabel + '</span>';
}
if (status.total && status.total > 0) {
html += '<div class="status-progress">' + status.processed + ' / ' + status.total + ' pages processed</div>';
}
html += '</div>';
} else if (status.status === 'complete') {
html = '<div class="status-complete">';
html += '<span class="dashicons dashicons-yes-alt"></span>';
html += '<span class="status-text">' + strings.statusComplete + '</span>';
html += '<div class="status-details">' + status.converted + ' converted, ' + status.skipped + ' skipped, ' + status.errors + ' errors</div>';
html += '</div>';
} else {
// idle
html = '<div class="status-idle">';
html += '<span class="dashicons dashicons-clock"></span>';
html += '<span class="status-text">' + strings.statusIdle + '</span>';
html += '</div>';
}
$container.html(html);
},
/**
* Start bulk conversion
*/
startBulkConvert: function (e) {
e.preventDefault();
if (this.isProcessing) {
return;
}
this.isProcessing = true;
this.processedPosts = 0;
this.results = {
converted: 0,
skipped: 0,
errors: 0,
details: []
};
// Disable buttons
$('#wp-to-html-convert-all, #wp-to-html-clear-cache').prop('disabled', true);
// Show progress bar
$('#wp-to-html-progress').show();
$('#wp-to-html-results').hide();
this.updateProgress(0, wpToHtml.strings.processing);
// Get total posts count first
this.getTotalPosts();
},
/**
* Get total posts count
*/
getTotalPosts: function () {
var self = this;
$.ajax({
url: wpToHtml.ajaxUrl,
type: 'POST',
data: {
action: 'wp_to_html_get_posts_count',
nonce: wpToHtml.nonce
},
success: function (response) {
if (response.success) {
self.totalPosts = response.data.total;
self.processBatch(0);
} else {
self.handleError(response.data);
}
},
error: function () {
self.handleError(wpToHtml.strings.error);
}
});
},
/**
* Process a batch of posts
*/
processBatch: function (offset) {
var self = this;
$.ajax({
url: wpToHtml.ajaxUrl,
type: 'POST',
data: {
action: 'wp_to_html_bulk_convert',
nonce: wpToHtml.nonce,
offset: offset
},
success: function (response) {
if (response.success) {
// Update results
self.processedPosts += response.data.processed;
self.results.converted += response.data.converted;
self.results.skipped += response.data.skipped;
self.results.errors += response.data.errors;
self.results.details = self.results.details.concat(response.data.details);
// Update progress
var percent = self.totalPosts > 0
? Math.round((self.processedPosts / self.totalPosts) * 100)
: 100;
self.updateProgress(percent, self.processedPosts + ' / ' + self.totalPosts);
// Continue or finish
if (response.data.has_more) {
self.processBatch(response.data.next_offset);
} else {
self.finishBulkConvert();
}
} else {
self.handleError(response.data);
}
},
error: function () {
self.handleError(wpToHtml.strings.error);
}
});
},
/**
* Finish bulk conversion
*/
finishBulkConvert: function () {
this.isProcessing = false;
// Update progress to complete
this.updateProgress(100, wpToHtml.strings.complete);
// Show results
this.showResults();
// Re-enable buttons
$('#wp-to-html-convert-all, #wp-to-html-clear-cache').prop('disabled', false);
// Refresh status immediately
this.checkStatus();
},
/**
* Update progress bar
*/
updateProgress: function (percent, text) {
$('.wp-to-html-progress-fill').css('width', percent + '%');
$('.wp-to-html-progress-text').text(text);
},
/**
* Show results
*/
showResults: function () {
var html = '<div class="result-summary">';
html += '<div class="result-stat converted"><span class="number">' + this.results.converted + '</span><span class="label">Converted</span></div>';
html += '<div class="result-stat skipped"><span class="number">' + this.results.skipped + '</span><span class="label">Skipped</span></div>';
html += '<div class="result-stat errors"><span class="number">' + this.results.errors + '</span><span class="label">Errors</span></div>';
html += '</div>';
if (this.results.details.length > 0) {
html += '<div class="result-details">';
// Show up to 50 items
var items = this.results.details.slice(0, 50);
for (var i = 0; i < items.length; i++) {
var item = items[i];
var icon = 'yes-alt';
var statusClass = item.status;
if (item.status === 'skipped') {
icon = 'warning';
} else if (item.status === 'error') {
icon = 'dismiss';
}
html += '<div class="result-item ' + statusClass + '">';
html += '<span class="dashicons dashicons-' + icon + '"></span>';
html += '<strong>' + this.escapeHtml(item.title) + '</strong>';
html += '<span class="message">' + this.escapeHtml(item.message) + '</span>';
html += '</div>';
}
if (this.results.details.length > 50) {
html += '<p><em>Showing first 50 results...</em></p>';
}
html += '</div>';
}
$('#wp-to-html-results').html(html).show();
},
/**
* Clear cache
*/
clearCache: function (e) {
e.preventDefault();
if (this.isProcessing) {
return;
}
if (!confirm(wpToHtml.strings.confirmClear)) {
return;
}
this.isProcessing = true;
$('#wp-to-html-convert-all, #wp-to-html-clear-cache').prop('disabled', true);
var self = this;
$.ajax({
url: wpToHtml.ajaxUrl,
type: 'POST',
data: {
action: 'wp_to_html_clear_cache',
nonce: wpToHtml.nonce
},
success: function (response) {
self.isProcessing = false;
$('#wp-to-html-convert-all, #wp-to-html-clear-cache').prop('disabled', false);
if (response.success) {
alert(response.data.message);
location.reload();
} else {
self.handleError(response.data);
}
},
error: function () {
self.isProcessing = false;
$('#wp-to-html-convert-all, #wp-to-html-clear-cache').prop('disabled', false);
self.handleError(wpToHtml.strings.error);
}
});
},
/**
* Handle error
*/
handleError: function (message) {
this.isProcessing = false;
$('#wp-to-html-convert-all, #wp-to-html-clear-cache').prop('disabled', false);
$('#wp-to-html-progress').hide();
alert(message);
},
/**
* Escape HTML
*/
escapeHtml: function (text) {
var div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
};
// Initialize on document ready
$(document).ready(function () {
WPToHTML.init();
});
})(jQuery);