/** * 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 = '
'; html += ''; html += '' + statusText + ''; if (sourceLabel) { html += '' + sourceLabel + ''; } if (status.total && status.total > 0) { html += '
' + status.processed + ' / ' + status.total + ' pages processed
'; } html += '
'; } else if (status.status === 'complete') { html = '
'; html += ''; html += '' + strings.statusComplete + ''; html += '
' + status.converted + ' converted, ' + status.skipped + ' skipped, ' + status.errors + ' errors
'; html += '
'; } else { // idle html = '
'; html += ''; html += '' + strings.statusIdle + ''; html += '
'; } $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 = '
'; html += '
' + this.results.converted + 'Converted
'; html += '
' + this.results.skipped + 'Skipped
'; html += '
' + this.results.errors + 'Errors
'; html += '
'; if (this.results.details.length > 0) { html += '
'; // 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 += '
'; html += ''; html += '' + this.escapeHtml(item.title) + ''; html += '' + this.escapeHtml(item.message) + ''; html += '
'; } if (this.results.details.length > 50) { html += '

Showing first 50 results...

'; } html += '
'; } $('#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);