/** * Maple Local Fonts - Admin JavaScript * * @package Maple_Local_Fonts */ (function($) { 'use strict'; var MLF = { /** * Preview debounce timer. */ previewTimer: null, /** * Currently loaded preview font. */ currentPreviewFont: null, /** * Initialize the admin functionality. */ init: function() { this.bindEvents(); this.updateFileCount(); }, /** * Bind event handlers. */ bindEvents: function() { // Form submission $('#mlf-import-form').on('submit', this.handleDownload.bind(this)); // Delete button clicks $(document).on('click', '.mlf-delete-btn', this.handleDelete.bind(this)); // Update file count on checkbox change $('#mlf-import-form').on('change', 'input[type="checkbox"]', this.updateFileCount.bind(this)); // Font name input for preview (debounced) $('#mlf-font-name').on('input', this.handleFontNameInput.bind(this)); }, /** * Handle font name input for preview (debounced). * * @param {Event} e Input event. */ handleFontNameInput: function(e) { var fontName = $(e.target).val().trim(); // Clear previous timer if (this.previewTimer) { clearTimeout(this.previewTimer); } // Hide preview if empty if (!fontName) { this.hidePreview(); return; } // Validate font name (only allowed characters) if (!/^[a-zA-Z0-9\s\-]+$/.test(fontName)) { this.hidePreview(); return; } // Debounce: wait 500ms before loading preview this.previewTimer = setTimeout(function() { MLF.loadFontPreview(fontName); }, 500); }, /** * Load font preview from Google Fonts. * * @param {string} fontName Font family name. */ loadFontPreview: function(fontName) { var $section = $('#mlf-preview-section'); var $text = $('#mlf-preview-text'); var $loading = $('#mlf-preview-loading'); var $error = $('#mlf-preview-error'); // Skip if same font already loaded if (this.currentPreviewFont === fontName) { return; } // Show section with loading state $section.show(); $text.hide(); $loading.show(); $error.hide(); // Remove previous preview font link $('#mlf-preview-font-link').remove(); // Build Google Fonts URL for preview (just 400 weight for preview) var fontFamily = fontName.replace(/\s+/g, '+'); var previewUrl = 'https://fonts.googleapis.com/css2?family=' + encodeURIComponent(fontFamily) + ':wght@400&display=swap'; // Create link element var $link = $('', { id: 'mlf-preview-font-link', rel: 'stylesheet', href: previewUrl }); // Handle load success $link.on('load', function() { MLF.currentPreviewFont = fontName; $text.css('font-family', '"' + fontName + '", sans-serif'); $loading.hide(); $text.show(); }); // Handle load error $link.on('error', function() { MLF.currentPreviewFont = null; $loading.hide(); $error.show(); }); // Append to head $('head').append($link); // Fallback timeout (5 seconds) setTimeout(function() { if ($loading.is(':visible')) { // Check if font actually loaded by measuring text width var testSpan = $('').text('test').css({ 'font-family': '"' + fontName + '", monospace', 'position': 'absolute', 'visibility': 'hidden' }).appendTo('body'); var testWidth = testSpan.width(); var fallbackSpan = $('').text('test').css({ 'font-family': 'monospace', 'position': 'absolute', 'visibility': 'hidden' }).appendTo('body'); var fallbackWidth = fallbackSpan.width(); testSpan.remove(); fallbackSpan.remove(); if (testWidth !== fallbackWidth) { // Font loaded successfully MLF.currentPreviewFont = fontName; $text.css('font-family', '"' + fontName + '", sans-serif'); $loading.hide(); $text.show(); } else { // Font failed to load MLF.currentPreviewFont = null; $loading.hide(); $error.show(); } } }, 5000); }, /** * Hide the font preview section. */ hidePreview: function() { this.currentPreviewFont = null; $('#mlf-preview-section').hide(); $('#mlf-preview-font-link').remove(); }, /** * Update the file count display. */ updateFileCount: function() { var weights = $('input[name="weights[]"]:checked').length; var styles = $('input[name="styles[]"]:checked').length; var count = weights * styles; $('#mlf-file-count').text(count); }, /** * Handle font download form submission. * * @param {Event} e Form submit event. */ handleDownload: function(e) { e.preventDefault(); var $form = $('#mlf-import-form'); var $button = $('#mlf-download-btn'); var $spinner = $('#mlf-spinner'); var $message = $('#mlf-message'); // Get form values var fontName = $('#mlf-font-name').val().trim(); var weights = []; var styles = []; $('input[name="weights[]"]:checked').each(function() { weights.push($(this).val()); }); $('input[name="styles[]"]:checked').each(function() { styles.push($(this).val()); }); // Validate if (!fontName) { this.showMessage($message, mapleLocalFontsData.strings.enterFontName, 'error'); return; } if (weights.length === 0) { this.showMessage($message, mapleLocalFontsData.strings.selectWeight, 'error'); return; } if (styles.length === 0) { this.showMessage($message, mapleLocalFontsData.strings.selectStyle, 'error'); return; } // Disable form $form.addClass('mlf-loading'); $button.prop('disabled', true).text(mapleLocalFontsData.strings.downloading); $spinner.addClass('is-active'); $message.hide(); // Send AJAX request $.ajax({ url: mapleLocalFontsData.ajaxUrl, type: 'POST', data: { action: 'mlf_download_font', nonce: mapleLocalFontsData.downloadNonce, font_name: fontName, weights: weights, styles: styles }, success: function(response) { if (response.success) { MLF.showMessage($message, response.data.message, 'success'); // Reload page to show new font setTimeout(function() { window.location.reload(); }, 1500); } else { MLF.showMessage($message, response.data.message || mapleLocalFontsData.strings.error, 'error'); } }, error: function() { MLF.showMessage($message, mapleLocalFontsData.strings.error, 'error'); }, complete: function() { $form.removeClass('mlf-loading'); $button.prop('disabled', false).text($button.data('original-text') || 'Download & Install'); $spinner.removeClass('is-active'); } }); // Store original button text if (!$button.data('original-text')) { $button.data('original-text', $button.text()); } }, /** * Handle font deletion. * * @param {Event} e Click event. */ handleDelete: function(e) { e.preventDefault(); var $button = $(e.currentTarget); var fontId = $button.data('font-id'); var $fontItem = $button.closest('.mlf-font-item'); // Confirm deletion if (!confirm(mapleLocalFontsData.strings.confirmDelete)) { return; } // Disable button $button.prop('disabled', true).text(mapleLocalFontsData.strings.deleting); $fontItem.addClass('mlf-loading'); // Send AJAX request $.ajax({ url: mapleLocalFontsData.ajaxUrl, type: 'POST', data: { action: 'mlf_delete_font', nonce: mapleLocalFontsData.deleteNonce, font_id: fontId }, success: function(response) { if (response.success) { // Remove font item with animation $fontItem.slideUp(300, function() { $(this).remove(); // Check if any fonts remain if ($('.mlf-font-item').length === 0) { $('#mlf-font-list').html( '

No fonts installed yet.

' ); } }); } else { alert(response.data.message || mapleLocalFontsData.strings.error); $button.prop('disabled', false).text('Delete'); $fontItem.removeClass('mlf-loading'); } }, error: function() { alert(mapleLocalFontsData.strings.error); $button.prop('disabled', false).text('Delete'); $fontItem.removeClass('mlf-loading'); } }); }, /** * Show a message to the user. * * @param {jQuery} $element Message element. * @param {string} message Message text. * @param {string} type Message type (success or error). */ showMessage: function($element, message, type) { $element .removeClass('mlf-message-success mlf-message-error') .addClass('mlf-message-' + type) .text(message) .show(); } }; // Initialize on document ready $(document).ready(function() { MLF.init(); }); })(jQuery);