112 lines
3.3 KiB
JavaScript
112 lines
3.3 KiB
JavaScript
/**
|
|
* S1 SEO Meta — Admin Scripts
|
|
* Live character counter with colour feedback.
|
|
* Supports both regular textareas and TinyMCE editors (wp_editor).
|
|
*/
|
|
( function ( $ ) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Update a counter element with the current length and apply colour classes.
|
|
*
|
|
* @param {jQuery} $counter The <span> element showing the count.
|
|
* @param {number} len Current character length.
|
|
* @param {number} soft Ideal upper boundary (turns amber above this).
|
|
* @param {number} hard Hard limit (turns red at or above this).
|
|
*/
|
|
function updateCounter( $counter, len, soft, hard ) {
|
|
$counter.text( len );
|
|
$counter
|
|
.removeClass( 's1-count-ok s1-count-warn s1-count-over' )
|
|
.addClass(
|
|
len >= hard ? 's1-count-over' :
|
|
len >= soft ? 's1-count-warn' :
|
|
len > 0 ? 's1-count-ok' : ''
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get content from TinyMCE editor or fallback to textarea.
|
|
*
|
|
* @param {string} editorId The ID of the editor/textarea.
|
|
* @return {string} The editor content.
|
|
*/
|
|
function getEditorContent( editorId ) {
|
|
if ( typeof tinymce !== 'undefined' && tinymce.get( editorId ) ) {
|
|
return tinymce.get( editorId ).getContent();
|
|
}
|
|
return $( '#' + editorId ).val() || '';
|
|
}
|
|
|
|
/**
|
|
* Count characters in HTML content (strips tags).
|
|
*
|
|
* @param {string} html HTML content.
|
|
* @return {number} Character count without HTML tags.
|
|
*/
|
|
function countTextChars( html ) {
|
|
var tempDiv = document.createElement( 'div' );
|
|
tempDiv.innerHTML = html;
|
|
return tempDiv.textContent || tempDiv.innerText || '';
|
|
}
|
|
|
|
function initCounters() {
|
|
// Title field (always regular input)
|
|
var $titleInput = $( '#s1_seo_title' );
|
|
var $titleCounter = $( '#s1_seo_title_count' );
|
|
|
|
if ( $titleInput.length && $titleCounter.length ) {
|
|
// Initialise on page load.
|
|
updateCounter( $titleCounter, $titleInput.val().length, 50, 60 );
|
|
|
|
$titleInput.on( 'input', function () {
|
|
updateCounter( $titleCounter, $( this ).val().length, 50, 60 );
|
|
} );
|
|
}
|
|
|
|
// Description field (may be TinyMCE or textarea)
|
|
var $descCounter = $( '#s1_seo_desc_count' );
|
|
|
|
if ( $descCounter.length ) {
|
|
var editorId = 's1_seo_description';
|
|
var initialContent = getEditorContent( editorId );
|
|
var initialCount = countTextChars( initialContent ).length;
|
|
|
|
// Initialise on page load.
|
|
updateCounter( $descCounter, initialCount, 120, 160 );
|
|
|
|
// Handle TinyMCE editor changes
|
|
if ( typeof tinymce !== 'undefined' ) {
|
|
tinymce.on( 'AddEditor', function( e ) {
|
|
if ( e.editor.id === editorId ) {
|
|
e.editor.on( 'keyup change', function() {
|
|
var content = e.editor.getContent();
|
|
var count = countTextChars( content ).length;
|
|
updateCounter( $descCounter, count, 120, 160 );
|
|
} );
|
|
}
|
|
} );
|
|
|
|
// If editor already exists
|
|
if ( tinymce.get( editorId ) ) {
|
|
tinymce.get( editorId ).on( 'keyup change', function() {
|
|
var content = tinymce.get( editorId ).getContent();
|
|
var count = countTextChars( content ).length;
|
|
updateCounter( $descCounter, count, 120, 160 );
|
|
} );
|
|
}
|
|
}
|
|
|
|
// Fallback for regular textarea
|
|
$( '#' + editorId ).on( 'input', function () {
|
|
var content = $( this ).val();
|
|
var count = countTextChars( content ).length;
|
|
updateCounter( $descCounter, count, 120, 160 );
|
|
} );
|
|
}
|
|
}
|
|
|
|
$( document ).ready( initCounters );
|
|
|
|
} )( jQuery );
|