/** * 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 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 );