initial commit

This commit is contained in:
rodolfomartinez 2026-01-30 22:33:40 -05:00
parent d066133bd4
commit e6f71e3706
55 changed files with 11928 additions and 0 deletions

View file

@ -0,0 +1,354 @@
/**
* Maple Local Fonts - Admin Styles
*
* @package Maple_Local_Fonts
*/
/* Container */
.mlf-wrap {
max-width: 900px;
}
.mlf-container {
margin-top: 20px;
}
/* Sections */
.mlf-section {
background: #fff;
border: 1px solid #c3c4c7;
border-radius: 4px;
padding: 20px;
margin-bottom: 20px;
}
.mlf-section h2 {
margin-top: 0;
padding-bottom: 10px;
border-bottom: 1px solid #c3c4c7;
}
/* Form */
.mlf-form-row {
margin-bottom: 20px;
}
.mlf-form-row label {
display: block;
font-weight: 600;
margin-bottom: 8px;
}
.mlf-form-row input[type="text"] {
width: 100%;
max-width: 400px;
padding: 8px 12px;
}
.mlf-form-row .description {
margin-top: 8px;
color: #646970;
font-style: italic;
}
/* Checkbox Grid */
.mlf-checkbox-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 10px;
}
.mlf-checkbox-grid-small {
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
max-width: 300px;
}
.mlf-checkbox-label {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
background: #f6f7f7;
border: 1px solid #dcdcde;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.15s ease;
}
.mlf-checkbox-label:hover {
background: #f0f0f1;
}
.mlf-checkbox-label input[type="checkbox"] {
margin: 0;
}
.mlf-checkbox-label input[type="checkbox"]:checked + span {
font-weight: 600;
}
/* File Count */
.mlf-form-row-info {
padding: 12px 16px;
background: #f0f6fc;
border: 1px solid #c5d9ed;
border-radius: 4px;
}
.mlf-file-count {
color: #2271b1;
}
.mlf-file-count strong {
font-size: 1.1em;
}
/* Font Preview */
.mlf-preview-section {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #dcdcde;
}
.mlf-preview-box {
background: #fff;
border: 1px solid #dcdcde;
border-radius: 4px;
padding: 24px;
min-height: 100px;
position: relative;
}
.mlf-preview-text {
display: flex;
flex-direction: column;
gap: 16px;
}
.mlf-preview-sample {
display: block;
line-height: 1.4;
}
.mlf-preview-heading {
font-size: 28px;
}
.mlf-preview-paragraph {
font-size: 16px;
color: #50575e;
}
.mlf-preview-loading {
display: flex;
align-items: center;
gap: 10px;
color: #646970;
padding: 20px 0;
}
.mlf-preview-loading .spinner {
float: none;
margin: 0;
}
.mlf-preview-error {
color: #b32d2e;
padding: 20px 0;
text-align: center;
}
/* Submit Row */
.mlf-form-row-submit {
display: flex;
align-items: center;
gap: 12px;
}
.mlf-form-row-submit .spinner {
float: none;
margin: 0;
}
/* Messages */
.mlf-message {
padding: 12px 16px;
border-radius: 4px;
margin-top: 16px;
}
.mlf-message-success {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
}
.mlf-message-error {
background: #f8d7da;
border: 1px solid #f5c6cb;
color: #721c24;
}
/* Font List */
.mlf-font-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.mlf-font-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: #f6f7f7;
border: 1px solid #dcdcde;
border-radius: 4px;
}
.mlf-font-info {
flex: 1;
}
.mlf-font-name {
margin: 0 0 4px 0;
font-size: 1.1em;
}
.mlf-font-variants {
margin: 0;
color: #646970;
font-size: 0.9em;
}
.mlf-font-actions {
margin-left: 20px;
}
.mlf-delete-btn {
color: #b32d2e;
border-color: #b32d2e;
}
.mlf-delete-btn:hover {
background: #b32d2e;
color: #fff;
border-color: #b32d2e;
}
.mlf-delete-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* No Fonts Message */
.mlf-no-fonts {
color: #646970;
font-style: italic;
padding: 20px;
text-align: center;
background: #f6f7f7;
border-radius: 4px;
}
/* Info Box */
.mlf-info-box {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px;
background: #f0f6fc;
border: 1px solid #c5d9ed;
border-radius: 4px;
}
.mlf-info-box .dashicons {
color: #2271b1;
margin-top: 2px;
}
.mlf-info-box p {
margin: 0;
color: #1d2327;
}
.mlf-info-box a {
color: #2271b1;
text-decoration: none;
}
.mlf-info-box a:hover {
text-decoration: underline;
}
/* Classic Theme Info Box */
.mlf-info-box-classic {
flex-direction: row;
align-items: flex-start;
background: #fcf9e8;
border-color: #d4b106;
}
.mlf-info-box-classic .dashicons {
color: #9d7e05;
}
.mlf-classic-theme-info {
flex: 1;
}
.mlf-classic-theme-info p {
margin: 0 0 12px 0;
}
.mlf-classic-theme-info p:last-child {
margin-bottom: 0;
}
.mlf-classic-theme-info .description {
color: #646970;
font-style: italic;
margin-top: 12px;
}
.mlf-code-example {
background: #1d2327;
color: #f0f0f1;
padding: 12px 16px;
border-radius: 4px;
font-family: Consolas, Monaco, monospace;
font-size: 12px;
line-height: 1.6;
overflow-x: auto;
white-space: pre;
margin: 12px 0;
}
/* Loading State */
.mlf-loading {
opacity: 0.6;
pointer-events: none;
}
/* Responsive */
@media screen and (max-width: 782px) {
.mlf-checkbox-grid {
grid-template-columns: repeat(2, 1fr);
}
.mlf-font-item {
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
.mlf-font-actions {
margin-left: 0;
}
}
@media screen and (max-width: 480px) {
.mlf-checkbox-grid {
grid-template-columns: 1fr;
}
}

View file

@ -0,0 +1,354 @@
/**
* 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 = $('<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 = $('<span>').text('test').css({
'font-family': '"' + fontName + '", monospace',
'position': 'absolute',
'visibility': 'hidden'
}).appendTo('body');
var testWidth = testSpan.width();
var fallbackSpan = $('<span>').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(
'<p class="mlf-no-fonts">No fonts installed yet.</p>'
);
}
});
} 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);

View file

@ -0,0 +1,5 @@
<?php
// Silence is golden.
if (!defined('ABSPATH')) {
exit;
}