npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

editorpjem

v1.0.10

Published

Editor de texto enriquecido local para el Poder Judicial del Estado de México

Downloads

33

Readme

EditorPJEM

Descripción

EditorPJEM es un editor simple de texto enriquecido completamente local. Incluye sanitización automática de HTML para prevenir ataques XSS.

Características

  • Sanitización automática - Previene ataques XSS automáticamente
  • Funcionalidades completas - Negrita, cursiva, tablas, listas, alineación, etc.
  • Fácil implementación
  • Estilos personalizables - Altura, clases CSS, colores de iconos
  • Toolbar responsivo - Se adapta automáticamente al ancho de pantalla
  • Múltiples instancias - Soporte para varios editores en la misma página
  • Menú "Más herramientas" - Agrupa herramientas cuando no hay espacio
  • Valores por defecto - Funciona sin configuración adicional
  • Placeholder personalizable - Texto de ayuda personalizable
  • Límite de caracteres - Control de longitud con contador visual
  • Contador inteligente - Cambia de color según se acerca al límite

📦 Instalación

Instalación desde npm

npm install editorpjem

Uso con npm

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="node_modules/editorpjem/editorPJEM/editorPJEM.css">
</head>
<body>
    <textarea id="miEditor"></textarea>
    
    <script src="node_modules/editorpjem/editorPJEM/editorPJEM.js"></script>
    <script>
        var editor = initEDITORPJEM('miEditor', {
            height: 300,
            placeholder: 'Escribe aquí...'
        });
    </script>
</body>
</html>

Implementación con Archivos Locales

1. Incluir archivos CSS y JS

<!-- Incluir en el <head> o antes del cierre del </body> -->
<link rel="stylesheet" href="js/editorPJEM/editorPJEM/editorPJEM.css">
<script src="js/editorPJEM/editorPJEM/editorPJEM.js"></script>
<script src="js/editorPJEM/editorPJEM.js"></script>

2. Crear el textarea

<textarea id="miEditor" name="miEditor" placeholder="Escribe aquí..."></textarea>

3. Inicializar el editor

$(document).ready(function() {
    setTimeout(function() {
        if (typeof EDITORPJEM !== 'undefined') {
            // Configuración básica (usa valores por defecto)
            var editor = initEDITORPJEM('miEditor');
            
            // O con configuración personalizada
            var editor = initEDITORPJEM('miEditor', {
                height: 200,           // Altura en píxeles (por defecto: 200px)
                useClass: null,        // Clase CSS personalizada (por defecto: null)
                placeholder: 'Escribe aquí...',  // Texto de ayuda (por defecto: null)
                maxLength: 1000        // Límite de caracteres (por defecto: null)
            });
            
            // Opcional: Guardar contenido al enviar formulario
            $('form').on('submit', function() {
                if (editor) {
                    $('#miEditor').val(editor.getData());
                }
            });
        }
    }, 500);
});

Valores por Defecto

Si no se especifican parámetros, el editor usa estos valores por defecto:

  • height: 200 píxeles
  • useClass: null (sin clase personalizada)
  • placeholder: null (sin placeholder)
  • maxLength: null (sin límite de caracteres)

Configuración Mínima

// Editor con configuración mínima (usa todos los valores por defecto)
var editor = initEDITORPJEM('miEditor');

// Equivale a:
var editor = initEDITORPJEM('miEditor', {
    height: 200,      // Altura por defecto
    useClass: null,   // Sin clase personalizada
    placeholder: null, // Sin placeholder
    maxLength: null   // Sin límite de caracteres
});

Sanitización Automática

Sanitización Completa

El editor sanitiza automáticamente el contenido en todos los puntos de entrada y salida:

1. Al obtener contenido (getData())

var editor = EDITORPJEM.instances['miEditor'];
var contenidoLimpio = editor.getData(); // Ya está sanitizado

2. Al establecer contenido (setData())

editor.setData(contenidoHTML); // Se sanitiza automáticamente

3. Al cargar desde BD (loadData())

editor.loadData(contenidoDeBD); // Se sanitiza automáticamente

4. Al pegar contenido

  • Todo el contenido pegado se sanitiza automáticamente
  • Se filtran scripts, eventos y elementos maliciosos

Sanitización Manual (Opcional)

Si necesitas sanitizar contenido manualmente:

// Opción 1: Usar función global
var contenidoLimpio = sanitizeHTML(contenidoHTML);

// Opción 2: Usar función estática
var contenidoLimpio = EDITORPJEM.sanitizeHTML(contenidoHTML);

Ejemplo completo con sanitización de BD

// Al cargar datos desde la base de datos
$.ajax({
    url: 'obtener_datos.php',
    success: function(datos) {
        // Sanitizar contenido antes de cargarlo
        var contenidoLimpio = sanitizeHTML(datos.contenido);
        $('#miEditor').val(contenidoLimpio);
        
        // Inicializar editor con contenido limpio
        var editor = initEDITORPJEM('miEditor');
    }
});

Configuración Avanzada

Opciones de configuración

var editor = initEDITORPJEM('miEditor', {
    height: 300,           // Altura del editor en píxeles
    useClass: 'mi-clase',  // Clase CSS personalizada para el editor
    placeholder: 'Escribe aquí...',  // Texto placeholder
    maxLength: 1000       // Límite máximo de caracteres
});

Estilos Personalizados

1. Altura Personalizada

// Editor con altura personalizada
var editor = initEDITORPJEM('miEditor', {
    height: 400  // Altura en píxeles
});

// Si no se especifica height, usa el valor por defecto (200px)
var editor = initEDITORPJEM('miEditor'); // Altura por defecto

2. Clases CSS Personalizadas

// Editor con clase personalizada
var editor = initEDITORPJEM('miEditor', {
    useClass: 'editor-dark-mode'  // Aplica la clase al contenedor
});

// Si no se especifica useClass, usa estilos por defecto
var editor = initEDITORPJEM('miEditor'); // Sin clase personalizada

Nota: Cuando se especifica useClass, el editor aplica automáticamente:

  • {useClass} al contenedor principal
  • {useClass}-toolbar a la barra de herramientas
  • {useClass}-editor al área de edición

3. Colores de Iconos Personalizados

// Editor con iconos de color personalizado usando clases CSS
var editor = initEDITORPJEM('miEditor', {
    useClass: 'mi-editor'  // Aplica clases CSS personalizadas
});

Personalización con clases CSS:

/* Personalizar colores del editor */
.mi-editor-toolbar {
    background-color: #dc3545 !important;  /* Fondo de la barra */
}

.mi-editor-iconColor {
    color: #ffffff !important;  /* Color de iconos */
}

.mi-editor-counterBackground {
    background-color: #dc3545 !important;  /* Fondo del contador */
}

.mi-editor-counterTextColor {
    color: #ffffff !important;  /* Texto del contador */
}

4. Ejemplo Completo con Estilos

// Editor con configuración completa
var editor = initEDITORPJEM('miEditor', {
    height: 300,                    // Altura personalizada
    useClass: 'editor-dark-mode',   // Clase CSS personalizada
    placeholder: 'Escribe aquí...', // Texto de ayuda
    maxLength: 1000                // Límite de caracteres
});

5. CSS Personalizado

/* Estilos para el editor personalizado */
.editor-dark-mode {
    border: 2px solid #333;
    border-radius: 8px;
}

.editor-dark-mode-toolbar {
    background: #2d3748;
    border-bottom: 1px solid #4a5568;
}

.editor-dark-mode-editor {
    background: #1a202c;
    color: #ffffff;
    min-height: 300px;
}

/* Editor con tema personalizado */
.editor-personalizado {
    border: 2px solid #ffc107;
    border-radius: 8px;
}

.editor-personalizado-toolbar {
    background: #ffc107;
    border-bottom: 1px solid #e0a800;
}

.editor-personalizado-editor {
    background: #fff3cd;
    color: #856404;
}

6. Menú Responsivo Automático

El editor incluye un menú responsivo que se adapta automáticamente al ancho de pantalla:

  • Pantallas grandes: Todas las herramientas visibles
  • Pantallas pequeñas: Herramientas menos usadas se mueven al menú "Más"
  • Colores automáticos: El menú hereda los colores del toolbar
  • Iconos consistentes: Los iconos del menú usan el mismo iconColor del toolbar
// El menú responsivo se configura automáticamente
var editor = initEDITORPJEM('miEditor', {
    useClass: 'editor-dark-mode',
    iconColor: '#ffffff'  // Los iconos del menú también serán blancos
});

7. Placeholder Personalizado

// Editor con placeholder
var editor = initEDITORPJEM('miEditor', {
    placeholder: 'Escribe tu contenido aquí...'
});

// Si no se especifica placeholder, no se muestra texto de ayuda
var editor = initEDITORPJEM('miEditor'); // Sin placeholder

8. Límite de Caracteres con Contador

// Editor con límite de caracteres
var editor = initEDITORPJEM('miEditor', {
    maxLength: 500  // Máximo 500 caracteres
});

// El contador muestra: "0 / 500"
// Cambia de color cuando se acerca al límite (90%)
// Cambia a rojo cuando se alcanza el límite

// Si no se especifica maxLength, no hay límite ni contador
var editor = initEDITORPJEM('miEditor'); // Sin límite

9. Configuración del Menú Responsivo

El menú responsivo se configura automáticamente basándose en:

  1. Color de fondo: Se extrae automáticamente del toolbar
  2. Color de iconos: Usa el mismo iconColor del toolbar
  3. Color de texto: Se calcula automáticamente para contraste
  4. Color de borde: Se deriva del color de fondo
// Ejemplo: Editor con menú automático
var editor = initEDITORPJEM('miEditor', {
    useClass: 'editor-dark-mode',  // Toolbar oscuro
    iconColor: '#ffffff'           // Iconos blancos
});

// El menú tendrá:
// - Fondo: Color del toolbar (oscuro)
// - Iconos: Blancos (iconColor)
// - Texto: Blanco (contraste automático)
// - Borde: Color derivado del fondo

Funciones disponibles

// Obtener instancia del editor
var editor = EDITORPJEM.getInstance('miEditor');

// Obtener contenido sanitizado
var contenido = editor.getData();

// Establecer contenido
editor.setData('<p>Nuevo contenido</p>');

// Limpiar contenido del editor
editor.clear();

// Resetear editor completamente (contenido + historial)
editor.reset();

// Resetear solo el historial (mantener contenido)
editor.resetHistory();

// Limpiar editor específico (función global)
clearEDITORPJEM('miEditor');

// Sanitizar HTML manualmente
var htmlLimpio = EDITORPJEM.sanitizeHTML(htmlMalicioso);

Configuración del Menú Responsivo

El menú responsivo se configura automáticamente basándose en:

  1. Color de fondo: Se extrae automáticamente del toolbar
  2. Color de iconos: Usa el mismo iconColor del toolbar
  3. Color de texto: Se calcula automáticamente para contraste
  4. Color de borde: Se deriva del color de fondo
// Ejemplo: Editor con menú automático
var editor = initEDITORPJEM('miEditor', {
    useClass: 'editor-dark-mode',  // Toolbar oscuro
    iconColor: '#ffffff'           // Iconos blancos
});

// El menú tendrá:
// - Fondo: Color del toolbar (oscuro)
// - Iconos: Blancos (iconColor)
// - Texto: Blanco (contraste automático)
// - Borde: Color derivado del fondo

Funciones de Reset

reset() - Reset Completo

Limpia completamente el editor y reinicia su historial:

// Resetear editor completamente
editor.reset();
// - Limpia todo el contenido
// - Reinicia el historial (undo/redo)
// - Actualiza contador de caracteres
// - Actualiza estado de la barra de herramientas

resetHistory() - Reset Solo Historial

Reinicia únicamente el historial manteniendo el contenido:

// Resetear solo el historial
editor.resetHistory();
// - Mantiene el contenido actual
// - Reinicia el historial (undo/redo)
// - Útil para cargar nuevos datos sin perder contenido

Casos de Uso

1. Limpiar Formulario

// Al limpiar un formulario
function limpiarFormulario() {
    if (EDITORPJEM.instances['miEditor']) {
        EDITORPJEM.instances['miEditor'].reset();
    }
}

2. Cargar Nuevos Datos

// Al cargar datos desde base de datos
function cargarDatos(datos) {
    var editor = EDITORPJEM.instances['miEditor'];
    editor.reset();  // Limpiar completamente
    editor.setData(datos.contenido);  // Cargar nuevos datos
}

3. Reset Solo Historial

// Cuando se necesita mantener contenido pero reiniciar historial
function reiniciarHistorial() {
    var editor = EDITORPJEM.instances['miEditor'];
    editor.resetHistory();  // Solo reinicia historial
}

Diferencias entre reset() y resetHistory()

| Función | Contenido | Historial | Uso Recomendado | |---------|-----------|-----------|-----------------| | reset() | ❌ Limpia | ❌ Reinicia | Limpiar formulario, cargar nuevos datos | | resetHistory() | ✅ Mantiene | ❌ Reinicia | Evitar interferencia entre registros |

Cuándo usar cada función

Usar reset() cuando:

  • Limpiar un formulario completamente
  • Cargar nuevos datos desde base de datos
  • Reiniciar el editor a su estado inicial

Usar resetHistory() cuando:

  • Evitar que undo muestre contenido de registros anteriores
  • Mantener el contenido actual pero reiniciar el historial
  • Prevenir interferencia entre consultas de diferentes registros

Etiquetas HTML Permitidas

El editor permite las siguientes etiquetas HTML:

  • Texto: p, h1, h2, h3, h4, h5, h6
  • Formato: strong, b, em, i, u, s, strike
  • Listas: ul, ol, li
  • Tablas: table, thead, tbody, tr, th, td
  • Otros: div, span, br, blockquote

Atributos Permitidos

  • style, class, border, cellpadding, cellspacing, colspan, rowspan, align

Seguridad

  • XSS Prevention: Elimina automáticamente scripts maliciosos
  • Event Handler Removal: Remueve todos los event handlers (onclick, onerror, etc.)
  • URL Sanitization: Limpia URLs javascript:, data:, vbscript:
  • CSS Expression Removal: Elimina expresiones CSS peligrosas
  • Tag Whitelist: Solo permite etiquetas HTML seguras
  • Word/Office Cleanup: Limpia automáticamente contenido de Microsoft Word/Office
    • Remueve comentarios CSS de Word
    • Elimina estilos MSO (Microsoft Office)
    • Remueve estilos específicos de Word (font-size en pt, line-height en %, etc.)

Solución de Problemas

El editor no aparece

  1. Verificar que los archivos CSS y JS se cargan correctamente
  2. Verificar que el textarea tiene un ID único
  3. Revisar la consola del navegador para errores

Contenido no se guarda

  1. Asegurarse de que se llama editor.getData() antes de enviar el formulario
  2. Verificar que el textarea original tiene el atributo name

Errores de sanitización

  1. El editor incluye manejo de errores automático
  2. Si hay error, devuelve texto plano sin HTML

Ejemplos Prácticos

Ejemplo 1: Editor Básico

// Editor con configuración por defecto
var editor = initEDITORPJEM('miEditor');
// - Altura: 200px
// - Sin clase personalizada
// - Iconos negros

Ejemplo 2: Editor con Altura Personalizada

// Editor más alto para contenido extenso
var editor = initEDITORPJEM('miEditor', {
    height: 400
});

Ejemplo 3: Editor con Tema Oscuro

// Editor con tema oscuro
var editor = initEDITORPJEM('miEditor', {
    height: 300,
    useClass: 'editor-dark-mode',
    iconColor: '#ffffff'
});

Ejemplo 4: Editor con Tema de Desarrollo

// Editor con tema de desarrollo
var editor = initEDITORPJEM('miEditor', {
    height: 250,
    useClass: 'editor-desarrollo',
    iconColor: 'red'
});

Ejemplo 5: Editor con Placeholder y Límite

// Editor con placeholder y límite de caracteres
var editor = initEDITORPJEM('miEditor', {
    height: 300,
    placeholder: 'Escribe tu contenido aquí...',
    maxLength: 1000
});

Ejemplo 6: Editor con Contador Personalizado

// Editor con colores personalizados del contador
var editor = initEDITORPJEM('miEditor', {
    height: 300,
    maxLength: 500,
    counterBackground: '#e3f2fd',  // Fondo azul claro
    counterTextColor: '#1976d2'   // Texto azul
});

Ejemplo 7: Múltiples Editores

// Editor principal
var editor1 = initEDITORPJEM('editor1', {
    height: 200
});

// Editor secundario con tema personalizado
var editor2 = initEDITORPJEM('editor2', {
    height: 150,
    useClass: 'editor-dark-mode',
    iconColor: '#ffffff'
});

// Editor terciario con tema de desarrollo
var editor3 = initEDITORPJEM('editor3', {
    height: 150,
    useClass: 'editor-personalizado',
    iconColor: 'red'
});

// Editor con placeholder y límite
var editor4 = initEDITORPJEM('editor4', {
    height: 200,
    placeholder: 'Escribe aquí...',
    maxLength: 500
});

Ejemplo 8: Uso de Funciones de Reset

// Función para limpiar formulario
function limpiarFormulario() {
    // Resetear todos los editores
    if (EDITORPJEM.instances['editor1']) {
        EDITORPJEM.instances['editor1'].reset();
    }
    if (EDITORPJEM.instances['editor2']) {
        EDITORPJEM.instances['editor2'].reset();
    }
}

// Función para cargar datos desde BD
function cargarDatos(datos) {
    var editor = EDITORPJEM.instances['miEditor'];
    editor.reset();  // Limpiar completamente
    editor.setData(datos.contenido);  // Cargar nuevos datos
}

// Función para reiniciar historial sin perder contenido
function reiniciarHistorial() {
    var editor = EDITORPJEM.instances['miEditor'];
    editor.resetHistory();  // Solo reinicia historial
}

Funciones de Control de Estado

disabled()

Desactiva completamente el editor y todos sus controles.

editor.disabled();

Características:

  • Desactiva el área de edición (contentEditable = false)
  • Desactiva todos los botones del toolbar
  • Reduce la opacidad del editor

enabled()

Activa el editor y todos sus controles.

editor.enabled();

Características:

  • Activa el área de edición (contentEditable = true)
  • Activa todos los botones del toolbar
  • Restaura el cursor normal
  • Restaura la opacidad completa del editor
  • Actualiza el estado del toolbar

Ejemplo de Uso

// Desactivar el editor
editor.disabled();

// Activar el editor
editor.enabled();

Ejemplo Completo

Ver editorPJEM/ejemplo.html para un ejemplo completo de implementación con múltiples editores, estilos personalizados, funciones de reset y control de estado.

Soporte

Para problemas o mejoras, contactar al equipo de desarrollo de la subdireccion de sistemas informaticos laborales.


📦 Instalación desde npm

Instalación

npm install editorpjem

Uso con npm

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="node_modules/editorpjem/editorPJEM/editorPJEM.css">
</head>
<body>
    <textarea id="miEditor"></textarea>
    
    <script src="node_modules/editorpjem/editorPJEM/editorPJEM.js"></script>
    <script>
        var editor = initEDITORPJEM('miEditor', {
            height: 300,
            placeholder: 'Escribe aquí...'
        });
    </script>
</body>
</html>

Configuración con npm

var editor = initEDITORPJEM('miEditor', {
    height: 300,                    // Altura del editor
    useClass: 'mi-clase',          // Clase CSS personalizada
    placeholder: 'Escribe aquí...', // Texto de ayuda
    maxLength: 1000                // Límite de caracteres
});

📄 Licencia

MIT License - Ver LICENSE para más detalles.

👨‍💻 Desarrollador

Ing. Elesbaán Enrique Campos Domínguez

Desarrollado para el Poder Judicial del Estado de México

📞 Soporte npm

🏛️ Institución

Poder Judicial del Estado de México

Versión 1.0 - Septiembre 2025