
Si estaría interesado en ayudar a mantener uno de los editores de texto Wysiwyg más exitosos en GitHub, ¡háganoslo saber! (Ver número #1503)
Este es un clon de la barra de herramientas del editor en línea de Medium.com.
Se ha escrito medianos medianos utilizando Vanilla JavaScript, no se requieren marcos adicionales.
demostración : http://yabwe.github.io/medium-editor/
Vía NPM:
Ejecute en su consola: npm install medium-editor
Vía Bower:
bower install medium-editor
A través de un CDN externo
Para la última versión:
< script src =" //cdn.jsdelivr.net/npm/medium-editor@latest/dist/js/medium-editor.min.js " > </ script >
< link rel =" stylesheet " href =" //cdn.jsdelivr.net/npm/medium-editor@latest/dist/css/medium-editor.min.css " type =" text/css " media =" screen " charset =" utf-8 " >Para uno personalizado:
< script src =" //cdn.jsdelivr.net/npm/[email protected]/dist/js/medium-editor.min.js " > </ script >
< link rel =" stylesheet " href =" //cdn.jsdelivr.net/npm/[email protected]/dist/css/medium-editor.min.css " type =" text/css " media =" screen " charset =" utf-8 " >Instalación manual:
Descargue la última versión y adjunte las hojas de estilo del editor Medium a su página:
Encuentre los archivos a continuación que se mencionan en la carpeta DIST. (./medium-editor/dist/...)
< link rel =" stylesheet " href =" css/medium-editor.css " > <!-- Core -->
< link rel =" stylesheet " href =" css/themes/default.css " > <!-- or any other theme -->El siguiente paso es hacer referencia al script del editor
< script src =" js/medium-editor.js " > </ script >Ahora puede instanciar un nuevo objeto de medianos:
< script > var editor = new MediumEditor ( '.editable' ) ; </ script >El código anterior transformará todos los elementos con la clase. Editable en contenido editable HTML5 y les agregará la barra de herramientas del editor medio.
También puede aprobar una lista de elementos HTML:
var elements = document . querySelectorAll ( '.editable' ) ,
editor = new MediumEditor ( elements ) ; Medioditor también es compatible con TextAREA. Si proporciona un elemento TextAREA, el script creará un nuevo DIV con contentEditable=true , oculta el TextAREA y vinculará el valor TextAREA al contenido DIV HTML.
Las personas han contribuido con envoltorios en torno a medianos para integrarse con diferentes marcos y pilas tecnológicas. ¡Eche un vistazo a la lista de envoltorios e integraciones existentes que ya se han escrito para medianos!
Vea la documentación de opciones de medianos en todas las diversas opciones para medianos.
Las opciones para personalizar el editor medio se pasan como el segundo argumento al constructor de medianos. Ejemplo:
var editor = new MediumEditor ( '.editor' , {
// options go here
} ) ;'medium-editor-button-active'false | 'Fontaweamer'. Valor predeterminado: false El uso de 'fontawesome' ya que las Labelas de botones requieren la versión 4.1.0 del CSS Fontawesome que esté en la página para asegurarse de que todos los iconos se muestren correctamente
0falsefalsefalsefalsedocument.body{}truefalseLa barra de herramientas para medianos se implementa como una extensión incorporada que se muestra automáticamente cada vez que el usuario selecciona algún texto. La barra de herramientas puede contener cualquier conjunto de botones incorporados definidos, pero también puede mantener presionados los botones personalizados que pasan como extensiones.
Las opciones para la barra de herramientas se pasan como un objeto que es un miembro del objeto Outer Opciones. Ejemplo:
var editor = new MediumEditor ( '.editable' , {
toolbar : {
/* These are the default options for the toolbar,
if nothing is passed this is what is used */
allowMultiParagraphSelection : true ,
buttons : [ 'bold' , 'italic' , 'underline' , 'anchor' , 'h2' , 'h3' , 'quote' ] ,
diffLeft : 0 ,
diffTop : - 10 ,
firstButtonClass : 'medium-editor-button-first' ,
lastButtonClass : 'medium-editor-button-last' ,
relativeContainer : null ,
standardizeSelectionStart : false ,
static : false ,
/* options which only apply when static is true */
align : 'center' ,
sticky : false ,
updateOnEmptySelection : false
}
} ) ;true['bold', 'italic', 'underline', 'anchor', 'h2', 'h3', 'quote']0-10'medium-editor-button-first''medium-editor-button-last'relative en lugar de absolute . Valor predeterminado: nullfalsefalse static :left | center | right : cuando la opción estática es true , esto alinea la barra de herramientas estáticas en relación con el elemento de editor medio. Valor predeterminado: centertrue , esto habilita/deshabilita la barra de herramientas "pegarse" a la vista y permanecer visible en la pantalla mientras la página se desplaza. Valor predeterminado: falsetrue , esto habilita/deshabilita la actualización del estado de los botones de la barra de herramientas incluso cuando la selección está colapsada (no hay selección, solo un cursor). Valor predeterminado: false Para deshabilitar la barra de herramientas (que también deshabilita la extensión de anclaje previa), establezca el valor de la opción de toolbar en false :
var editor = new MediumEditor ( '.editable' , {
toolbar : false
} ) ; El comportamiento del botón se puede modificar pasando un objeto a la matriz de botones en lugar de una cadena. Esto permite anular parte del comportamiento predeterminado de los botones. Las siguientes opciones son algunas de las partes básicas de los botones que puede anular, pero cualquier parte del MediumEditor.Extension.prototype puede anularse a través de estas opciones de botones. (Consulte el código fuente de los botones para ver qué se puede anular todo).
MediumEditor.execAction() cuando se hace clic en el botón.<b> o <strong> que indica que el texto ya es audaz. Entonces, la variedad de nombres de etiqueta para Bold sería: ['b', 'strong']useQueryState se establece en true .'font-weight' establecida en 700 o 'bold' , que indica que el texto ya está en negrita. Entonces, el objeto de estilo para Bold sería { prop: 'font-weight', value: '700|bold' }useQueryState se establece en true .'|' )document.queryCommandState() para determinar si la acción ya se ha aplicado. Si la acción ya se ha aplicado, el botón se mostrará como 'activo' en la barra de herramientasdocument.queryCommandState('bold') que devolverá verdadero si el navegador cree que el texto ya está en negrita, y falso de lo contrarioinnerHTML predeterminado para colocar dentro del botóninnerHTML que se usará para el contenido del botón si la opción ButtonLabels para mediumeditor está configurada en 'fontawesome' Ejemplo de botones primordiales (aquí, el objetivo es imitar el medio teniendo botones H1 y H2 que realmente producen <h2> y <h3> etiquetas respectivamente)::
var editor = new MediumEditor ( '.editable' , {
toolbar : {
buttons : [
'bold' ,
'italic' ,
{
name : 'h1' ,
action : 'append-h2' ,
aria : 'header type 1' ,
tagNames : [ 'h2' ] ,
contentDefault : '<b>H1</b>' ,
classList : [ 'custom-class-h1' ] ,
attrs : {
'data-custom-attr' : 'attr-value-h1'
}
} ,
{
name : 'h2' ,
action : 'append-h3' ,
aria : 'header type 2' ,
tagNames : [ 'h3' ] ,
contentDefault : '<b>H2</b>' ,
classList : [ 'custom-class-h2' ] ,
attrs : {
'data-custom-attr' : 'attr-value-h2'
}
} ,
'justifyCenter' ,
'quote' ,
'anchor'
]
}
} ) ; La vista previa de Anchor es una extensión incorporada que muestra automáticamente una 'información sobre herramientas' cuando el usuario está rondando un enlace en el editor. La información sobre herramientas mostrará el href del enlace, y cuando se hace clic, abrirá el formulario de edición de anclaje en la barra de herramientas.
Las opciones para la vista previa de Anchor 'ToolTiP' se pasan como un objeto que es un miembro del objeto Opciones exteriores. Ejemplo:
var editor = new MediumEditor ( '.editable' , {
anchorPreview : {
/* These are the default options for anchor preview,
if nothing is passed this is what it used */
hideDelay : 500 ,
previewValueSelector : 'a'
}
}
} ) ;500'a'falsetrue Para deshabilitar la vista previa de Anchor, establezca el valor de la opción anchorPreview en false :
var editor = new MediumEditor ( '.editable' , {
anchorPreview : false
} ) ; toolbar: false o atributo data-disable-toolbar ), la revisión de anclaje se deshabilita automáticamente.El controlador de marcador de posición es una extensión incorporada que muestra el texto del marcador de posición cuando el editor está vacío.
Las opciones para el marcador de posición se pasan como un objeto que es un miembro del objeto Outal Options. Ejemplo:
var editor = new MediumEditor ( '.editable' , {
placeholder : {
/* This example includes the default options for placeholder,
if nothing is passed this is what it used */
text : 'Type your text' ,
hideOnClick : true
}
} ) ; Texto : Define el marcador de posición predeterminado para Contenteditables vacíos cuando el marcador de posición no se establece en False. Puede sobrescribirlo estableciendo un atributo data-placeholder en los elementos del editor. Valor predeterminado: 'Type your text'
HideOnclick : hace que el marcador de posición desaparezca tan pronto como el campo se centre. Valor predeterminado: true . Para ocultar el marcador de posición solo después de comenzar a escribir, y para mostrarlo nuevamente tan pronto como el campo esté vacío, establezca esta opción en false .
Para deshabilitar el marcador de posición, establezca el valor de la opción del placeholder en false :
var editor = new MediumEditor ( '.editable' , {
placeholder : false
} ) ;El formulario de anclaje es una extensión de botón incorporada que permite al usuario agregar/editar/eliminar enlaces desde el editor. Cuando el 'ancla' se pasa como un botón en la lista de botones, esta extensión se habilitará y se puede activar haciendo clic en el botón correspondiente en la barra de herramientas.
Las opciones para el formulario de anclaje se pasan como un objeto que es un miembro del objeto de opciones externas. Ejemplo:
var editor = new MediumEditor ( '.editable' , {
toolbar : {
buttons : [ 'bold' , 'italic' , 'underline' , 'anchor' ]
} ,
anchor : {
/* These are the default options for anchor form,
if nothing is passed this is what it used */
customClassOption : null ,
customClassOptionText : 'Button' ,
linkValidation : false ,
placeholderText : 'Paste or type a link' ,
targetCheckbox : false ,
targetCheckboxText : 'Open in new window'
}
}
} ) ;null'Button'encodeURI . Valor predeterminado: false'Paste or type a link'target del enlace creado. Valor predeterminado: false'Open in new window'El controlador de pasta es una extensión incorporada que intenta filtrar el contenido cuando el usuario pasea. Cómo los filtros del controlador de pasta se configuran a través de opciones específicas.
Las opciones para el manejo de la pasta se pasan como un objeto que es un miembro del objeto Outer Opciones. Ejemplo:
var editor = new MediumEditor ( '.editable' , {
paste : {
/* This example includes the default options for paste,
if nothing is passed this is what it used */
forcePlainText : true ,
cleanPastedHTML : false ,
cleanReplacements : [ ] ,
cleanAttrs : [ 'class' , 'style' , 'dir' ] ,
cleanTags : [ 'meta' ] ,
unwrapTags : [ ]
}
} ) ;truefalsetrue o cuando llaman al método auxiliar cleanPaste(text) . Estos reemplazos se ejecutan antes de los reemplazos de construcción. Por defecto: []true o cuando llaman al método auxiliar cleanPaste(text) . Estos reemplazos se ejecutan después de los reemplazos integrados. Por defecto: []true o cuando llame cleanPaste(text) o métodos pasteHTML(html,options) Predeterminado: ['class', 'style', 'dir']true o cuando llame pasteHTML(html,options) cleanPaste(text) o métodos a ayuda Valor predeterminado: ['meta']true o cuando llame a pasteHTML(html,options) cleanPaste(text) o métodos a ayuda Por defecto: []El controlador de comandos de teclado es una extensión incorporada para mapear combinaciones de teclas a acciones para ejecutar en el editor.
Las opciones para los comerciantes de teclado se pasan como un objeto que es un miembro del objeto Outsal Opciones. Ejemplo:
var editor = new MediumEditor ( '.editable' , {
keyboardCommands : {
/* This example includes the default options for keyboardCommands,
if nothing is passed this is what it used */
commands : [
{
command : 'bold' ,
key : 'B' ,
meta : true ,
shift : false ,
alt : false
} ,
{
command : 'italic' ,
key : 'I' ,
meta : true ,
shift : false ,
alt : false
} ,
{
command : 'underline' ,
key : 'U' ,
meta : true ,
shift : false ,
alt : false
}
] ,
}
} ) ;editor.execAction() cuando se usa la combinación de clavefalse , el acceso directo se deshabilitará Para deshabilitar los comandos del teclado, establezca el valor de la opción de los keyboardCommands en false :
var editor = new MediumEditor ( '.editable' , {
keyboardCommands : false
} ) ;El controlador de enlace automático es una extensión incorporada que convierte automáticamente las URL ingresadas en el campo de texto en etiquetas de anclaje HTML (similar a la funcionalidad de Markdown). Esta función está desactivada de forma predeterminada.
Para habilitar el soporte de enlace automático incorporado, establezca el valor de la opción autoLink en true :
var editor = new MediumEditor ( '.editable' , {
autoLink : true
} ) ;El controlador de arrastre de imagen es una extensión incorporada para manejar arrastrando y soltar imágenes a la contentable. Esta función está activada de forma predeterminada.
Para deshabilitar el arrastre de imagen incorporado, establezca el valor de la opción imageDragging en false :
var editor = new MediumEditor ( '.editable' , {
imageDragging : false
} ) ; Para dejar de prevenir los eventos de arrastrar y soltar y deshabilitar el arrastre de archivos en general, proporcione una extensión ficticia de imagen de imagen.
var editor = new MediumEditor ( '.editor' , {
extensions : {
'imageDragging' : { }
}
} ) ;Debido al estado del código en 5.0.0, el editor siempre evitó cualquier acción de arrastrar y soltar. Tendremos una mejor manera de deshabilitar el arrastre de archivos en 6.*
var editor = new MediumEditor ( '.editable' , {
delay : 1000 ,
targetBlank : true ,
toolbar : {
buttons : [ 'bold' , 'italic' , 'quote' ] ,
diffLeft : 25 ,
diffTop : 10 ,
} ,
anchor : {
placeholderText : 'Type a link' ,
customClassOption : 'btn' ,
customClassOptionText : 'Create Button'
} ,
paste : {
cleanPastedHTML : true ,
cleanAttrs : [ 'style' , 'dir' ] ,
cleanTags : [ 'label' , 'meta' ] ,
unwrapTags : [ 'sub' , 'sup' ]
} ,
anchorPreview : {
hideDelay : 300
} ,
placeholder : {
text : 'Click to edit'
}
} ) ; De forma predeterminada, MediumEditor admite botones para la mayoría de los comandos para document.execCommand() que están bien respaldados en todos sus navegadores compatibles.
Mediumeditor, por defecto, mostrará solo los botones enumerados aquí para evitar una gran barra de herramientas:
Estos son todos los botones incorporados compatibles con Medediator.
Consulte la página Wiki para obtener una lista de temas disponibles: https://github.com/yabwe/medium-editor/wiki/themes
Vea la documentación de la API del objeto medioso en el wiki para obtener detalles sobre todos los métodos admitidos en el objeto medioso.
on()importSelection()exportSelection() )saveSelection()document.execCommand('createLink')document.execCommanddocument.queryCommandState(action) para verificar si ya se ha aplicado una acción específica a la selección.delayinnerHTML recortado del elemento en indexinnerHTML en html del elemento en indexEs posible agregar dinámicamente nuevos elementos a su instancia existente de medianos:
var editor = new MediumEditor ( '.editable' ) ;
editor . subscribe ( 'editableInput' , this . _handleEditableInput . bind ( this ) ) ;
// imagine an ajax fetch/any other dynamic functionality which will add new '.editable' elements to the DOM
editor . addElements ( '.editable' ) ;
// OR editor.addElements(document.getElementsByClassName('editable'));
// OR editor.addElements(document.querySelectorAll('.editable')); Pasar un elemento o una variedad de elementos a addElements(elements) :
this.elements interna.<textarea> :<textarea><div contenteditable=true> y agréguelo a la matriz de elementos. Directo, solo llame a removeElements con el elemento o la matriz de elementos para querer derribar. Cada elemento en sí seguirá siendo contento: simplemente eliminará todos los controladores de eventos y todas las referencias a él para que pueda eliminarlo de manera segura de DOM.
editor . removeElements ( document . querySelector ( '#myElement' ) ) ;
// OR editor.removeElements(document.getElementById('myElement'));
// OR editor.removeElements('#myElement');
// in case you have jQuery and don't exactly know when an element was removed, for example after routing state change
var removedElements = [ ] ;
editor . elements . forEach ( function ( element ) {
// check if the element is still available in current DOM
if ( ! $ ( element ) . parents ( 'body' ) . length ) {
removedElements . push ( element ) ;
}
} ) ;
editor . removeElements ( removedElements ) ; Para observar cualquier cambio en ContentEditable, use el evento personalizado 'editableInput' expuesto a través del método subscribe() :
var editor = new MediumEditor ( '.editable' ) ;
editor . subscribe ( 'editableInput' , function ( event , editable ) {
// Do some work
} ) ; ¡Este evento es compatible con todos los navegadores compatibles con medianos (incluidos IE9+ y Edge)! Para ayudar con los casos en que una instancia de medianas está monitoreando múltiples elementos, el segundo argumento transmitido al controlador de eventos ( editable en el ejemplo anterior) será una referencia al elemento contento que realmente ha cambiado.
Esto es útil cuando necesita capturar cualquier modificación al elemento contento que incluye:
¿Por qué es esto interesante y por qué debería usar este evento en lugar de simplemente adjuntar al evento input en el elemento contento?
Entonces, para la mayoría de los navegadores modernos (Chrome, Firefox, Safari, etc.), el evento input funciona bien. De hecho, editableInput es solo un proxy para el evento input en esos navegadores. Sin embargo, el evento input no es compatible con elementos contentos en el IE 9-11 y se admite principalmente en Microsoft Edge, pero no completamente.
Por lo tanto, para admitir adecuadamente el evento editableInput en Internet Explorer y Microsoft Edge, MediumEditor utiliza una combinación de los eventos selectionchange y keypress , así como de monitoreo de llamadas a document.execCommand .
Consulte la documentación para aprender cómo desarrollar extensiones para medianos.
Aquí puede encontrar una lista de extensiones y complementos existentes, como imágenes e incrustaciones de medios, tablas y markdown.
Para ejecutar la demostración localmente:
npm install desde su consola en la raíznode index.js desde la raízhttp://localhost:8088/demo/index.html para ver la demostraciónLas tareas de desarrollo de medianos son administradas por Grunt. Para instalar todos los paquetes necesarios, simplemente invoque:
npm installPara ejecutar todas las pruebas y construir los archivos DIST para probar en páginas de demostración, simplemente invoque:
gruntEstas son las otras tareas de gruñidos disponibles:
Los archivos de origen se encuentran dentro del directorio SRC . Asegúrese de realizar cambios en estos archivos y no archivos en el directorio DIST.
Mata algunos insectos :)
git checkout -b my-new-feature )git commit -am 'Added some feature' ) sin archivos desde el directorio DIST .git push origin my-new-feature )Para ayudar a crear un código de aspecto consistente durante todo el proyecto, utilizamos algunas herramientas para ayudarnos. Tienen complementos para los editores/IDE más populares para hacer una codificación para nuestro proyecto, ¡pero también debe usarlos en su proyecto!
Usamos Jshint en cada compilación para encontrar errores fáciles de captar y problemas potenciales en nuestro JS. Puede encontrar nuestra configuración de JSHINT en el archivo .jshintrc en la raíz del proyecto.
Utilizamos JSC en cada compilación para hacer cumplir algunas reglas de estilo de código que tenemos para nuestro proyecto. Puede encontrar nuestra configuración JSCS en el archivo .jscsrc en la raíz del proyecto.
Utilizamos EditorConfig para mantener estilos de codificación consistentes entre varios editores e IDE. Puede encontrar nuestra configuración en el archivo .editorconfig en la raíz del proyecto.
¿Buscas algo simple para una primera contribución? ¡Intenta arreglar un primer error fácil!
https://github.com/yabwe/medium-editor/graphs/contributors
¡Agregue su organización aquí y podemos agregarlo a nuestra página de destino!
MIT: https://github.com/yabwe/medium-editor/blob/master/license